aboutsummaryrefslogtreecommitdiff
path: root/contrib/bc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bc')
-rw-r--r--contrib/bc/.gitignore61
-rw-r--r--contrib/bc/LICENSE.md55
-rw-r--r--contrib/bc/Makefile.in389
-rw-r--r--contrib/bc/NEWS.md975
-rw-r--r--contrib/bc/NOTICE.md14
-rw-r--r--contrib/bc/README.md347
-rw-r--r--contrib/bc/RELEASE.md54
l---------contrib/bc/configure1
-rwxr-xr-xcontrib/bc/configure.sh1098
-rwxr-xr-xcontrib/bc/exec-install.sh63
-rwxr-xr-xcontrib/bc/functions.sh218
-rw-r--r--contrib/bc/gen/bc_help.txt120
-rw-r--r--contrib/bc/gen/dc_help.txt101
-rw-r--r--contrib/bc/gen/lib.bc201
-rw-r--r--contrib/bc/gen/lib2.bc317
-rw-r--r--contrib/bc/gen/strgen.c144
-rwxr-xr-xcontrib/bc/gen/strgen.sh82
-rw-r--r--contrib/bc/include/args.h46
-rw-r--r--contrib/bc/include/bc.h182
-rw-r--r--contrib/bc/include/bcl.h184
-rw-r--r--contrib/bc/include/dc.h66
-rw-r--r--contrib/bc/include/file.h65
-rw-r--r--contrib/bc/include/history.h258
-rw-r--r--contrib/bc/include/lang.h327
-rw-r--r--contrib/bc/include/lex.h247
-rw-r--r--contrib/bc/include/library.h165
-rw-r--r--contrib/bc/include/num.h261
-rw-r--r--contrib/bc/include/opt.h79
-rw-r--r--contrib/bc/include/parse.h117
-rw-r--r--contrib/bc/include/program.h187
-rw-r--r--contrib/bc/include/rand.h234
-rw-r--r--contrib/bc/include/read.h60
-rw-r--r--contrib/bc/include/status.h198
-rw-r--r--contrib/bc/include/vector.h102
-rw-r--r--contrib/bc/include/vm.h453
-rwxr-xr-xcontrib/bc/karatsuba.py232
-rwxr-xr-xcontrib/bc/link.sh60
-rwxr-xr-xcontrib/bc/locale_install.sh252
-rwxr-xr-xcontrib/bc/locale_uninstall.sh66
l---------contrib/bc/locales/de_AT.ISO8859-1.msg1
l---------contrib/bc/locales/de_AT.ISO8859-15.msg1
l---------contrib/bc/locales/de_AT.UTF-8.msg1
l---------contrib/bc/locales/de_AT.utf8.msg1
l---------contrib/bc/locales/de_CH.ISO8859-1.msg1
l---------contrib/bc/locales/de_CH.ISO8859-15.msg1
l---------contrib/bc/locales/de_CH.UTF-8.msg1
l---------contrib/bc/locales/de_CH.utf8.msg1
-rw-r--r--contrib/bc/locales/de_DE.ISO8859-1.msg108
l---------contrib/bc/locales/de_DE.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/de_DE.UTF-8.msg108
l---------contrib/bc/locales/de_DE.utf8.msg1
l---------contrib/bc/locales/en_AU.ISO8859-1.msg1
l---------contrib/bc/locales/en_AU.ISO8859-15.msg1
l---------contrib/bc/locales/en_AU.US-ASCII.msg1
l---------contrib/bc/locales/en_AU.UTF-8.msg1
l---------contrib/bc/locales/en_AU.utf8.msg1
l---------contrib/bc/locales/en_CA.ISO8859-1.msg1
l---------contrib/bc/locales/en_CA.ISO8859-15.msg1
l---------contrib/bc/locales/en_CA.US-ASCII.msg1
l---------contrib/bc/locales/en_CA.UTF-8.msg1
l---------contrib/bc/locales/en_CA.utf8.msg1
l---------contrib/bc/locales/en_GB.ISO8859-1.msg1
l---------contrib/bc/locales/en_GB.ISO8859-15.msg1
l---------contrib/bc/locales/en_GB.US-ASCII.msg1
l---------contrib/bc/locales/en_GB.UTF-8.msg1
l---------contrib/bc/locales/en_GB.utf8.msg1
l---------contrib/bc/locales/en_IE.ISO8859-1.msg1
l---------contrib/bc/locales/en_IE.ISO8859-15.msg1
l---------contrib/bc/locales/en_IE.US_ASCII.msg1
l---------contrib/bc/locales/en_IE.UTF-8.msg1
l---------contrib/bc/locales/en_IE.utf8.msg1
l---------contrib/bc/locales/en_NZ.ISO8859-1.msg1
l---------contrib/bc/locales/en_NZ.ISO8859-15.msg1
l---------contrib/bc/locales/en_NZ.US-ASCII.msg1
l---------contrib/bc/locales/en_NZ.UTF-8.msg1
l---------contrib/bc/locales/en_NZ.utf8.msg1
l---------contrib/bc/locales/en_US.ISO8859-1.msg1
l---------contrib/bc/locales/en_US.ISO8859-15.msg1
l---------contrib/bc/locales/en_US.US-ASCII.msg1
l---------contrib/bc/locales/en_US.US_ASCII.msg1
l---------contrib/bc/locales/en_US.UTF-8.msg1
-rw-r--r--contrib/bc/locales/en_US.msg108
l---------contrib/bc/locales/en_US.utf8.msg1
-rw-r--r--contrib/bc/locales/es_ES.ISO8859-1.msg108
l---------contrib/bc/locales/es_ES.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/es_ES.UTF-8.msg108
l---------contrib/bc/locales/es_ES.utf8.msg1
l---------contrib/bc/locales/fr_BE.ISO8859-1.msg1
l---------contrib/bc/locales/fr_BE.ISO8859-15.msg1
l---------contrib/bc/locales/fr_BE.UTF-8.msg1
l---------contrib/bc/locales/fr_BE.utf8.msg1
l---------contrib/bc/locales/fr_CA.ISO8859-1.msg1
l---------contrib/bc/locales/fr_CA.ISO8859-15.msg1
l---------contrib/bc/locales/fr_CA.UTF-8.msg1
l---------contrib/bc/locales/fr_CA.utf8.msg1
l---------contrib/bc/locales/fr_CH.ISO8859-1.msg1
l---------contrib/bc/locales/fr_CH.ISO8859-15.msg1
l---------contrib/bc/locales/fr_CH.UTF-8.msg1
l---------contrib/bc/locales/fr_CH.utf8.msg1
-rw-r--r--contrib/bc/locales/fr_FR.ISO8859-1.msg108
l---------contrib/bc/locales/fr_FR.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/fr_FR.UTF-8.msg108
l---------contrib/bc/locales/fr_FR.utf8.msg1
-rw-r--r--contrib/bc/locales/ja_JP.UTF-8.msg111
-rw-r--r--contrib/bc/locales/ja_JP.eucJP.msg111
l---------contrib/bc/locales/ja_JP.utf8.msg1
l---------contrib/bc/locales/nl_BE.ISO8859-1.msg1
l---------contrib/bc/locales/nl_BE.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/nl_NL.ISO8859-1.msg111
l---------contrib/bc/locales/nl_NL.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/nl_NL.UTF-8.msg111
l---------contrib/bc/locales/nl_NL.utf8.msg1
-rw-r--r--contrib/bc/locales/pl_PL.ISO8859-2.msg111
-rw-r--r--contrib/bc/locales/pl_PL.UTF-8.msg111
l---------contrib/bc/locales/pl_PL.utf8.msg1
l---------contrib/bc/locales/pt_BR.ISO8859-1.msg1
l---------contrib/bc/locales/pt_BR.ISO8859-15.msg1
l---------contrib/bc/locales/pt_BR.UTF-8.msg1
l---------contrib/bc/locales/pt_BR.utf8.msg1
-rw-r--r--contrib/bc/locales/pt_PT.ISO8859-1.msg108
l---------contrib/bc/locales/pt_PT.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/pt_PT.UTF-8.msg108
l---------contrib/bc/locales/pt_PT.utf8.msg1
-rw-r--r--contrib/bc/locales/ru_RU.CP1251.msg111
-rw-r--r--contrib/bc/locales/ru_RU.CP866.msg111
-rw-r--r--contrib/bc/locales/ru_RU.ISO8859-5.msg111
-rw-r--r--contrib/bc/locales/ru_RU.KOI8-R.msg111
-rw-r--r--contrib/bc/locales/ru_RU.UTF-8.msg111
l---------contrib/bc/locales/ru_RU.utf8.msg1
-rw-r--r--contrib/bc/locales/zh_CN.GB18030.msg108
-rw-r--r--contrib/bc/locales/zh_CN.GB2312.msg108
-rw-r--r--contrib/bc/locales/zh_CN.GBK.msg108
-rw-r--r--contrib/bc/locales/zh_CN.UTF-8.msg108
-rw-r--r--contrib/bc/locales/zh_CN.eucCN.msg108
l---------contrib/bc/locales/zh_CN.utf8.msg1
-rwxr-xr-xcontrib/bc/manpage.sh131
-rw-r--r--contrib/bc/manuals/algorithms.md189
-rw-r--r--contrib/bc/manuals/bc.1.md.in1810
-rw-r--r--contrib/bc/manuals/bc/A.12041
-rw-r--r--contrib/bc/manuals/bc/A.1.md1693
-rw-r--r--contrib/bc/manuals/bc/E.11301
-rw-r--r--contrib/bc/manuals/bc/E.1.md1085
-rw-r--r--contrib/bc/manuals/bc/EH.11283
-rw-r--r--contrib/bc/manuals/bc/EH.1.md1069
-rw-r--r--contrib/bc/manuals/bc/EHN.11276
-rw-r--r--contrib/bc/manuals/bc/EHN.1.md1061
-rw-r--r--contrib/bc/manuals/bc/EHNP.11269
-rw-r--r--contrib/bc/manuals/bc/EHNP.1.md1055
-rw-r--r--contrib/bc/manuals/bc/EHP.11276
-rw-r--r--contrib/bc/manuals/bc/EHP.1.md1063
-rw-r--r--contrib/bc/manuals/bc/EN.11294
-rw-r--r--contrib/bc/manuals/bc/EN.1.md1077
-rw-r--r--contrib/bc/manuals/bc/ENP.11287
-rw-r--r--contrib/bc/manuals/bc/ENP.1.md1071
-rw-r--r--contrib/bc/manuals/bc/EP.11294
-rw-r--r--contrib/bc/manuals/bc/EP.1.md1079
-rw-r--r--contrib/bc/manuals/bc/H.12021
-rw-r--r--contrib/bc/manuals/bc/H.1.md1676
-rw-r--r--contrib/bc/manuals/bc/HN.12014
-rw-r--r--contrib/bc/manuals/bc/HN.1.md1668
-rw-r--r--contrib/bc/manuals/bc/HNP.12007
-rw-r--r--contrib/bc/manuals/bc/HNP.1.md1662
-rw-r--r--contrib/bc/manuals/bc/HP.12014
-rw-r--r--contrib/bc/manuals/bc/HP.1.md1670
-rw-r--r--contrib/bc/manuals/bc/N.12034
-rw-r--r--contrib/bc/manuals/bc/N.1.md1685
-rw-r--r--contrib/bc/manuals/bc/NP.12027
-rw-r--r--contrib/bc/manuals/bc/NP.1.md1679
-rw-r--r--contrib/bc/manuals/bc/P.12034
-rw-r--r--contrib/bc/manuals/bc/P.1.md1687
-rw-r--r--contrib/bc/manuals/bcl.31365
-rw-r--r--contrib/bc/manuals/bcl.3.md1177
-rw-r--r--contrib/bc/manuals/benchmarks.md673
-rw-r--r--contrib/bc/manuals/build.md694
-rw-r--r--contrib/bc/manuals/dc.1.md.in1258
-rw-r--r--contrib/bc/manuals/dc/A.11334
-rw-r--r--contrib/bc/manuals/dc/A.1.md1195
-rw-r--r--contrib/bc/manuals/dc/E.11130
-rw-r--r--contrib/bc/manuals/dc/E.1.md1031
-rw-r--r--contrib/bc/manuals/dc/EH.11115
-rw-r--r--contrib/bc/manuals/dc/EH.1.md1018
-rw-r--r--contrib/bc/manuals/dc/EHN.11111
-rw-r--r--contrib/bc/manuals/dc/EHN.1.md1013
-rw-r--r--contrib/bc/manuals/dc/EHNP.11104
-rw-r--r--contrib/bc/manuals/dc/EHNP.1.md1008
-rw-r--r--contrib/bc/manuals/dc/EHP.11108
-rw-r--r--contrib/bc/manuals/dc/EHP.1.md1013
-rw-r--r--contrib/bc/manuals/dc/EN.11126
-rw-r--r--contrib/bc/manuals/dc/EN.1.md1026
-rw-r--r--contrib/bc/manuals/dc/ENP.11119
-rw-r--r--contrib/bc/manuals/dc/ENP.1.md1021
-rw-r--r--contrib/bc/manuals/dc/EP.11123
-rw-r--r--contrib/bc/manuals/dc/EP.1.md1026
-rw-r--r--contrib/bc/manuals/dc/H.11319
-rw-r--r--contrib/bc/manuals/dc/H.1.md1182
-rw-r--r--contrib/bc/manuals/dc/HN.11315
-rw-r--r--contrib/bc/manuals/dc/HN.1.md1177
-rw-r--r--contrib/bc/manuals/dc/HNP.11308
-rw-r--r--contrib/bc/manuals/dc/HNP.1.md1172
-rw-r--r--contrib/bc/manuals/dc/HP.11312
-rw-r--r--contrib/bc/manuals/dc/HP.1.md1177
-rw-r--r--contrib/bc/manuals/dc/N.11330
-rw-r--r--contrib/bc/manuals/dc/N.1.md1190
-rw-r--r--contrib/bc/manuals/dc/NP.11323
-rw-r--r--contrib/bc/manuals/dc/NP.1.md1185
-rw-r--r--contrib/bc/manuals/dc/P.11327
-rw-r--r--contrib/bc/manuals/dc/P.1.md1190
-rw-r--r--contrib/bc/manuals/header.txt27
-rw-r--r--contrib/bc/manuals/header_bc.txt1
-rw-r--r--contrib/bc/manuals/header_bcl.txt1
-rw-r--r--contrib/bc/manuals/header_dc.txt1
-rwxr-xr-xcontrib/bc/release.sh582
-rwxr-xr-xcontrib/bc/safe-install.sh67
-rw-r--r--contrib/bc/src/args.c219
-rw-r--r--contrib/bc/src/bc.c56
-rw-r--r--contrib/bc/src/bc_lex.c409
-rw-r--r--contrib/bc/src/bc_parse.c1532
-rw-r--r--contrib/bc/src/data.c1025
-rw-r--r--contrib/bc/src/dc.c56
-rw-r--r--contrib/bc/src/dc_lex.c200
-rw-r--r--contrib/bc/src/dc_parse.c236
-rw-r--r--contrib/bc/src/file.c225
-rw-r--r--contrib/bc/src/history.c1449
-rw-r--r--contrib/bc/src/lang.c324
-rw-r--r--contrib/bc/src/lex.c230
-rw-r--r--contrib/bc/src/library.c1183
-rw-r--r--contrib/bc/src/main.c90
-rw-r--r--contrib/bc/src/num.c2971
-rw-r--r--contrib/bc/src/opt.c252
-rw-r--r--contrib/bc/src/parse.c218
-rw-r--r--contrib/bc/src/program.c2336
-rw-r--r--contrib/bc/src/rand.c414
-rw-r--r--contrib/bc/src/read.c227
-rw-r--r--contrib/bc/src/vector.c344
-rw-r--r--contrib/bc/src/vm.c919
-rwxr-xr-xcontrib/bc/tests/afl.py176
-rwxr-xr-xcontrib/bc/tests/all.sh305
-rw-r--r--contrib/bc/tests/all.txt2
-rw-r--r--contrib/bc/tests/bc/abs.txt7
-rw-r--r--contrib/bc/tests/bc/abs_results.txt7
-rw-r--r--contrib/bc/tests/bc/add.txt146
-rw-r--r--contrib/bc/tests/bc/add_results.txt158
-rw-r--r--contrib/bc/tests/bc/all.txt46
-rw-r--r--contrib/bc/tests/bc/arctangent.txt27
-rw-r--r--contrib/bc/tests/bc/arctangent_results.txt26
-rw-r--r--contrib/bc/tests/bc/arrays.txt10
-rw-r--r--contrib/bc/tests/bc/arrays_results.txt3
-rw-r--r--contrib/bc/tests/bc/assignments.txt122
-rw-r--r--contrib/bc/tests/bc/assignments_results.txt61
-rw-r--r--contrib/bc/tests/bc/boolean.txt184
-rw-r--r--contrib/bc/tests/bc/boolean_results.txt184
-rw-r--r--contrib/bc/tests/bc/comp.txt132
-rw-r--r--contrib/bc/tests/bc/comp_results.txt131
-rw-r--r--contrib/bc/tests/bc/cosine.txt44
-rw-r--r--contrib/bc/tests/bc/cosine_results.txt41
-rw-r--r--contrib/bc/tests/bc/decimal.txt61
-rw-r--r--contrib/bc/tests/bc/decimal_results.txt75
-rw-r--r--contrib/bc/tests/bc/divide.txt62
-rw-r--r--contrib/bc/tests/bc/divide_results.txt61
-rw-r--r--contrib/bc/tests/bc/engineering.txt19
-rw-r--r--contrib/bc/tests/bc/engineering_results.txt18
-rw-r--r--contrib/bc/tests/bc/errors.txt258
-rw-r--r--contrib/bc/tests/bc/errors/01.txt368
-rw-r--r--contrib/bc/tests/bc/errors/02.txt16
-rw-r--r--contrib/bc/tests/bc/errors/03.txt2
-rw-r--r--contrib/bc/tests/bc/errors/04.txt1
-rw-r--r--contrib/bc/tests/bc/errors/05.txt1
-rw-r--r--contrib/bc/tests/bc/errors/06.txt1
-rw-r--r--contrib/bc/tests/bc/errors/07.txt36
-rw-r--r--contrib/bc/tests/bc/errors/08.txt3
-rw-r--r--contrib/bc/tests/bc/errors/09.txt18
-rw-r--r--contrib/bc/tests/bc/errors/10.txt13
-rw-r--r--contrib/bc/tests/bc/errors/11.txt408
-rw-r--r--contrib/bc/tests/bc/errors/12.txt3
-rw-r--r--contrib/bc/tests/bc/errors/13.txt57
-rw-r--r--contrib/bc/tests/bc/errors/14.txt1
-rw-r--r--contrib/bc/tests/bc/errors/15.txt3
-rw-r--r--contrib/bc/tests/bc/errors/16.txt1
-rw-r--r--contrib/bc/tests/bc/errors/17.txt313
-rw-r--r--contrib/bc/tests/bc/errors/18.txt7
-rw-r--r--contrib/bc/tests/bc/errors/19.txt16
-rw-r--r--contrib/bc/tests/bc/errors/20.txt68
-rw-r--r--contrib/bc/tests/bc/errors/21.txtbin0 -> 4892 bytes
-rw-r--r--contrib/bc/tests/bc/errors/22.txt5
-rw-r--r--contrib/bc/tests/bc/errors/23.txtbin0 -> 5141 bytes
-rw-r--r--contrib/bc/tests/bc/errors/24.txt9
-rw-r--r--contrib/bc/tests/bc/exponent.txt22
-rw-r--r--contrib/bc/tests/bc/exponent_results.txt25
-rw-r--r--contrib/bc/tests/bc/functions.txt13
-rw-r--r--contrib/bc/tests/bc/functions_results.txt5
-rw-r--r--contrib/bc/tests/bc/globals.txt21
-rw-r--r--contrib/bc/tests/bc/globals_results.txt6
-rw-r--r--contrib/bc/tests/bc/length.txt129
-rw-r--r--contrib/bc/tests/bc/length_results.txt127
-rw-r--r--contrib/bc/tests/bc/letters.txt53
-rw-r--r--contrib/bc/tests/bc/letters_results.txt51
-rw-r--r--contrib/bc/tests/bc/lib2.txt463
-rw-r--r--contrib/bc/tests/bc/lib2_results.txt698
-rw-r--r--contrib/bc/tests/bc/log.txt22
-rw-r--r--contrib/bc/tests/bc/log_results.txt22
-rw-r--r--contrib/bc/tests/bc/misc.txt13
-rw-r--r--contrib/bc/tests/bc/misc1.txt76
-rw-r--r--contrib/bc/tests/bc/misc1_results.txt57
-rw-r--r--contrib/bc/tests/bc/misc2.txt110
-rw-r--r--contrib/bc/tests/bc/misc2_results.txt68
-rw-r--r--contrib/bc/tests/bc/misc3.txt12
-rw-r--r--contrib/bc/tests/bc/misc3_results.txt30
-rw-r--r--contrib/bc/tests/bc/misc4.txt2
-rw-r--r--contrib/bc/tests/bc/misc4_results.txt1
-rw-r--r--contrib/bc/tests/bc/misc5.txt20
-rw-r--r--contrib/bc/tests/bc/misc5_results.txt4
l---------contrib/bc/tests/bc/misc6.txt1
l---------contrib/bc/tests/bc/misc6_results.txt1
l---------contrib/bc/tests/bc/misc7.txt1
l---------contrib/bc/tests/bc/misc7_results.txt1
-rw-r--r--contrib/bc/tests/bc/misc_results.txt4
-rw-r--r--contrib/bc/tests/bc/modulus.txt70
-rw-r--r--contrib/bc/tests/bc/modulus_results.txt69
-rw-r--r--contrib/bc/tests/bc/multiply.txt64
-rw-r--r--contrib/bc/tests/bc/multiply_results.txt78
-rw-r--r--contrib/bc/tests/bc/pi.txt4
-rw-r--r--contrib/bc/tests/bc/pi_results.txt135
-rw-r--r--contrib/bc/tests/bc/places.txt20
-rw-r--r--contrib/bc/tests/bc/places_results.txt18
-rw-r--r--contrib/bc/tests/bc/posix_errors.txt31
-rw-r--r--contrib/bc/tests/bc/power.txt43
-rw-r--r--contrib/bc/tests/bc/power_results.txt72
-rw-r--r--contrib/bc/tests/bc/print2.txt194
-rw-r--r--contrib/bc/tests/bc/print2_results.txt79
-rw-r--r--contrib/bc/tests/bc/rand.txt323
-rw-r--r--contrib/bc/tests/bc/rand_results.txt616
-rw-r--r--contrib/bc/tests/bc/read.txt1
-rw-r--r--contrib/bc/tests/bc/read_errors.txt2
-rw-r--r--contrib/bc/tests/bc/read_results.txt1
-rw-r--r--contrib/bc/tests/bc/scale.txt57
-rw-r--r--contrib/bc/tests/bc/scale_results.txt57
-rw-r--r--contrib/bc/tests/bc/scientific.txt51
-rw-r--r--contrib/bc/tests/bc/scientific_results.txt50
-rw-r--r--contrib/bc/tests/bc/scripts/add.bc17
-rwxr-xr-xcontrib/bc/tests/bc/scripts/array.bc60
-rw-r--r--contrib/bc/tests/bc/scripts/array.txt428
-rwxr-xr-xcontrib/bc/tests/bc/scripts/atan.bc11
-rw-r--r--contrib/bc/tests/bc/scripts/atan.txt301
-rwxr-xr-xcontrib/bc/tests/bc/scripts/bessel.bc43
-rw-r--r--contrib/bc/tests/bc/scripts/divide.bc22
-rw-r--r--contrib/bc/tests/bc/scripts/functions.bc7
-rw-r--r--contrib/bc/tests/bc/scripts/functions.txt2
-rwxr-xr-xcontrib/bc/tests/bc/scripts/globals.bc23
-rw-r--r--contrib/bc/tests/bc/scripts/globals.txt6
-rw-r--r--contrib/bc/tests/bc/scripts/len.bc48
-rw-r--r--contrib/bc/tests/bc/scripts/len.txt3
-rw-r--r--contrib/bc/tests/bc/scripts/multiply.bc19
-rwxr-xr-xcontrib/bc/tests/bc/scripts/parse.bc20
-rwxr-xr-xcontrib/bc/tests/bc/scripts/print.bc25
-rw-r--r--contrib/bc/tests/bc/scripts/rand.bc97
-rw-r--r--contrib/bc/tests/bc/scripts/rand.txt119
-rwxr-xr-xcontrib/bc/tests/bc/scripts/references.bc408
-rw-r--r--contrib/bc/tests/bc/scripts/references.txt1272
-rwxr-xr-xcontrib/bc/tests/bc/scripts/screen.bc20
-rw-r--r--contrib/bc/tests/bc/scripts/screen.txt1
-rw-r--r--contrib/bc/tests/bc/scripts/subtract.bc17
-rw-r--r--contrib/bc/tests/bc/shift.txt5341
-rw-r--r--contrib/bc/tests/bc/shift_results.txt5325
-rw-r--r--contrib/bc/tests/bc/sine.txt207
-rw-r--r--contrib/bc/tests/bc/sine_results.txt204
-rw-r--r--contrib/bc/tests/bc/sqrt.txt18
-rw-r--r--contrib/bc/tests/bc/sqrt_results.txt16
-rw-r--r--contrib/bc/tests/bc/stdin.txt16
-rw-r--r--contrib/bc/tests/bc/stdin1.txt2
-rw-r--r--contrib/bc/tests/bc/stdin1_results.txt1
-rw-r--r--contrib/bc/tests/bc/stdin2.txt1
-rw-r--r--contrib/bc/tests/bc/stdin2_results.txt3
-rw-r--r--contrib/bc/tests/bc/stdin_results.txt7
-rw-r--r--contrib/bc/tests/bc/strings.txt16
-rw-r--r--contrib/bc/tests/bc/strings_results.txt8
-rw-r--r--contrib/bc/tests/bc/subtract.txt153
-rw-r--r--contrib/bc/tests/bc/subtract_results.txt157
-rwxr-xr-xcontrib/bc/tests/bc/timeconst.sh91
-rw-r--r--contrib/bc/tests/bc/trunc.txt15
-rw-r--r--contrib/bc/tests/bc/trunc_results.txt13
-rw-r--r--contrib/bc/tests/bc/vars.txt7
-rw-r--r--contrib/bc/tests/bc/vars_results.txt12
-rw-r--r--contrib/bc/tests/bc/void.txt20
-rw-r--r--contrib/bc/tests/bc/void_results.txt9
-rw-r--r--contrib/bc/tests/bcl.c228
-rw-r--r--contrib/bc/tests/dc/abs.txt7
-rw-r--r--contrib/bc/tests/dc/abs_results.txt7
-rw-r--r--contrib/bc/tests/dc/add.txt33
-rw-r--r--contrib/bc/tests/dc/add_results.txt45
-rw-r--r--contrib/bc/tests/dc/all.txt22
-rw-r--r--contrib/bc/tests/dc/boolean.txt80
-rw-r--r--contrib/bc/tests/dc/boolean_results.txt80
-rw-r--r--contrib/bc/tests/dc/decimal.txt36
-rw-r--r--contrib/bc/tests/dc/decimal_results.txt51
-rw-r--r--contrib/bc/tests/dc/divide.txt33
-rw-r--r--contrib/bc/tests/dc/divide_results.txt32
-rw-r--r--contrib/bc/tests/dc/divmod.txt64
-rw-r--r--contrib/bc/tests/dc/divmod_results.txt126
-rw-r--r--contrib/bc/tests/dc/engineering.txt19
-rw-r--r--contrib/bc/tests/dc/engineering_results.txt18
-rw-r--r--contrib/bc/tests/dc/errors.txt32
-rw-r--r--contrib/bc/tests/dc/errors/01.txt2
-rw-r--r--contrib/bc/tests/dc/errors/02.txt10
-rw-r--r--contrib/bc/tests/dc/errors/03.txt2
-rw-r--r--contrib/bc/tests/dc/errors/04.txt10
-rw-r--r--contrib/bc/tests/dc/errors/05.txt3
-rw-r--r--contrib/bc/tests/dc/errors/06.txt4
-rw-r--r--contrib/bc/tests/dc/errors/07.txt4
-rw-r--r--contrib/bc/tests/dc/errors/08.txt2
-rw-r--r--contrib/bc/tests/dc/errors/09.txt22
-rw-r--r--contrib/bc/tests/dc/errors/10.txt19
-rw-r--r--contrib/bc/tests/dc/errors/11.txt4
-rw-r--r--contrib/bc/tests/dc/errors/12.txt5
-rw-r--r--contrib/bc/tests/dc/errors/13.txt17
-rw-r--r--contrib/bc/tests/dc/errors/14.txt7
-rw-r--r--contrib/bc/tests/dc/errors/15.txt11
-rw-r--r--contrib/bc/tests/dc/errors/16.txt7
-rw-r--r--contrib/bc/tests/dc/errors/17.txt21
-rw-r--r--contrib/bc/tests/dc/errors/18.txt3
-rw-r--r--contrib/bc/tests/dc/errors/19.txtbin0 -> 5536 bytes
-rw-r--r--contrib/bc/tests/dc/errors/20.txt9
-rw-r--r--contrib/bc/tests/dc/errors/21.txt7
-rw-r--r--contrib/bc/tests/dc/errors/22.txt37
-rw-r--r--contrib/bc/tests/dc/errors/23.txtbin0 -> 125 bytes
-rw-r--r--contrib/bc/tests/dc/errors/24.txt1
-rw-r--r--contrib/bc/tests/dc/errors/25.txt7
-rw-r--r--contrib/bc/tests/dc/errors/26.txt222
-rw-r--r--contrib/bc/tests/dc/errors/27.txt2
-rw-r--r--contrib/bc/tests/dc/errors/28.txt2
-rw-r--r--contrib/bc/tests/dc/errors/29.txt20
-rw-r--r--contrib/bc/tests/dc/misc.txt2
-rw-r--r--contrib/bc/tests/dc/misc_results.txt21
-rw-r--r--contrib/bc/tests/dc/modexp.txt103
-rw-r--r--contrib/bc/tests/dc/modexp_results.txt103
-rw-r--r--contrib/bc/tests/dc/modulus.txt70
-rw-r--r--contrib/bc/tests/dc/modulus_results.txt68
-rw-r--r--contrib/bc/tests/dc/multiply.txt43
-rw-r--r--contrib/bc/tests/dc/multiply_results.txt43
-rw-r--r--contrib/bc/tests/dc/negate.txt3
-rw-r--r--contrib/bc/tests/dc/negate_results.txt3
-rw-r--r--contrib/bc/tests/dc/places.txt16
-rw-r--r--contrib/bc/tests/dc/places_results.txt16
-rw-r--r--contrib/bc/tests/dc/power.txt44
-rw-r--r--contrib/bc/tests/dc/power_results.txt72
-rw-r--r--contrib/bc/tests/dc/rand.txt1
-rw-r--r--contrib/bc/tests/dc/rand_results.txt3
-rw-r--r--contrib/bc/tests/dc/read.txt1
-rw-r--r--contrib/bc/tests/dc/read_errors.txt2
-rw-r--r--contrib/bc/tests/dc/read_results.txt1
-rw-r--r--contrib/bc/tests/dc/scientific.txt51
-rw-r--r--contrib/bc/tests/dc/scientific_results.txt50
-rwxr-xr-xcontrib/bc/tests/dc/scripts/array.dc3
-rw-r--r--contrib/bc/tests/dc/scripts/array.txt201
-rwxr-xr-xcontrib/bc/tests/dc/scripts/asciify.dc7
-rw-r--r--contrib/bc/tests/dc/scripts/asciify.txtbin0 -> 131076 bytes
-rwxr-xr-xcontrib/bc/tests/dc/scripts/else.dc4
-rw-r--r--contrib/bc/tests/dc/scripts/else.txt34
-rwxr-xr-xcontrib/bc/tests/dc/scripts/factorial.dc4
-rw-r--r--contrib/bc/tests/dc/scripts/factorial.txt50
-rwxr-xr-xcontrib/bc/tests/dc/scripts/loop.dc3
-rw-r--r--contrib/bc/tests/dc/scripts/loop.txt20
-rwxr-xr-xcontrib/bc/tests/dc/scripts/prime.dc1
-rwxr-xr-xcontrib/bc/tests/dc/scripts/quit.dc2
-rw-r--r--contrib/bc/tests/dc/scripts/quit.txt99
-rwxr-xr-xcontrib/bc/tests/dc/scripts/stream.dc1
-rwxr-xr-xcontrib/bc/tests/dc/scripts/weird.dc2
-rw-r--r--contrib/bc/tests/dc/scripts/weird.txt18
-rw-r--r--contrib/bc/tests/dc/shift.txt42
-rw-r--r--contrib/bc/tests/dc/shift_results.txt42
-rw-r--r--contrib/bc/tests/dc/sqrt.txt14
-rw-r--r--contrib/bc/tests/dc/sqrt_results.txt13
-rw-r--r--contrib/bc/tests/dc/stdin.txt1005
-rw-r--r--contrib/bc/tests/dc/stdin_results.txt1022
-rw-r--r--contrib/bc/tests/dc/strings.txt50
-rw-r--r--contrib/bc/tests/dc/strings_results.txt51
-rw-r--r--contrib/bc/tests/dc/subtract.txt33
-rw-r--r--contrib/bc/tests/dc/subtract_results.txt37
-rw-r--r--contrib/bc/tests/dc/trunc.txt11
-rw-r--r--contrib/bc/tests/dc/trunc_results.txt11
-rw-r--r--contrib/bc/tests/dc/vars.txt2
-rw-r--r--contrib/bc/tests/dc/vars_results.txt6
-rwxr-xr-xcontrib/bc/tests/errors.sh132
-rwxr-xr-xcontrib/bc/tests/radamsa.sh120
-rw-r--r--contrib/bc/tests/radamsa.txt17
-rwxr-xr-xcontrib/bc/tests/randmath.py306
-rwxr-xr-xcontrib/bc/tests/read.sh126
-rwxr-xr-xcontrib/bc/tests/script.sh155
-rwxr-xr-xcontrib/bc/tests/scripts.sh86
-rwxr-xr-xcontrib/bc/tests/stdin.sh81
-rwxr-xr-xcontrib/bc/tests/test.sh132
490 files changed, 147808 insertions, 0 deletions
diff --git a/contrib/bc/.gitignore b/contrib/bc/.gitignore
new file mode 100644
index 000000000000..fb9bc5ab6aa2
--- /dev/null
+++ b/contrib/bc/.gitignore
@@ -0,0 +1,61 @@
+*.config
+*.creator
+*.files
+*.includes
+*.creator.user*
+*.cflags
+*.cxxflags
+bin/*bc
+bin/*bc.exe
+bin/*dc
+bin/*dc.exe
+bin/bcl
+bc.old
+*.o
+*.a
+.log_*.txt
+.test.txt
+.math.txt
+.results.txt
+.ops.txt
+manuals/bc.1
+manuals/bc.1.ronn
+manuals/bc.1.md
+manuals/dc.1
+manuals/dc.1.ronn
+manuals/dc.1.md
+gen/strgen
+lib.c
+lib2.c
+lib3.c
+bc_help.c
+dc_help.c
+config.mak
+timeconst.bc
+Makefile
+
+.gdb_history
+
+# Ignore the generated test files
+parse.txt
+parse_results.txt
+print.txt
+print_results.txt
+bessel.txt
+bessel_results.txt
+prime.txt
+stream.txt
+tests/bc/scripts/add.txt
+tests/bc/scripts/divide.txt
+tests/bc/scripts/multiply.txt
+tests/bc/scripts/subtract.txt
+perf.data
+perf.data.old
+*.gcda
+*.gcno
+*.gcov
+*.html
+*.profraw
+
+cscope*.out
+tags
diff --git a/contrib/bc/LICENSE.md b/contrib/bc/LICENSE.md
new file mode 100644
index 000000000000..1681a053e0de
--- /dev/null
+++ b/contrib/bc/LICENSE.md
@@ -0,0 +1,55 @@
+# License
+
+Copyright (c) 2018-2020 Gavin D. Howard <yzena.tech@gmail.com>
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+## History
+
+The files `src/history.c` and `include/history.h` are under the following
+copyrights and license:
+
+Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com><br>
+Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com><br>
+Copyright (c) 2018 rain-1 <rain1@openmailbox.org><br>
+Copyright (c) 2018-2020, Gavin D. Howard <yzena.tech@gmail.com>
+
+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.
diff --git a/contrib/bc/Makefile.in b/contrib/bc/Makefile.in
new file mode 100644
index 000000000000..d17e74163397
--- /dev/null
+++ b/contrib/bc/Makefile.in
@@ -0,0 +1,389 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+# %%WARNING%%
+#
+.POSIX:
+
+VERSION = 3.2.4
+
+SRC = %%SRC%%
+OBJ = %%OBJ%%
+GCDA = %%GCDA%%
+GCNO = %%GCNO%%
+
+BC_ENABLED_NAME = BC_ENABLED
+BC_ENABLED = %%BC_ENABLED%%
+DC_ENABLED_NAME = DC_ENABLED
+DC_ENABLED = %%DC_ENABLED%%
+
+GEN_DIR = gen
+GEN = %%GEN%%
+GEN_EXEC = $(GEN_DIR)/$(GEN)
+GEN_C = $(GEN_DIR)/$(GEN).c
+
+GEN_EMU = %%GEN_EMU%%
+
+BC_LIB = $(GEN_DIR)/lib.bc
+BC_LIB_C = $(GEN_DIR)/lib.c
+BC_LIB_O = %%BC_LIB_O%%
+BC_LIB_GCDA = $(GEN_DIR)/lib.gcda
+BC_LIB_GCNO = $(GEN_DIR)/lib.gcno
+
+BC_LIB2 = $(GEN_DIR)/lib2.bc
+BC_LIB2_C = $(GEN_DIR)/lib2.c
+BC_LIB2_O = %%BC_LIB2_O%%
+BC_LIB2_GCDA = $(GEN_DIR)/lib2.gcda
+BC_LIB2_GCNO = $(GEN_DIR)/lib2.gcno
+
+BC_HELP = $(GEN_DIR)/bc_help.txt
+BC_HELP_C = $(GEN_DIR)/bc_help.c
+BC_HELP_O = %%BC_HELP_O%%
+BC_HELP_GCDA = $(GEN_DIR)/bc_help.gcda
+BC_HELP_GCNO = $(GEN_DIR)/bc_help.gcno
+
+DC_HELP = $(GEN_DIR)/dc_help.txt
+DC_HELP_C = $(GEN_DIR)/dc_help.c
+DC_HELP_O = %%DC_HELP_O%%
+DC_HELP_GCDA = $(GEN_DIR)/dc_help.gcda
+DC_HELP_GCNO = $(GEN_DIR)/dc_help.gcno
+
+BIN = bin
+LOCALES = locales
+EXEC_SUFFIX = %%EXECSUFFIX%%
+EXEC_PREFIX = %%EXECPREFIX%%
+
+BC = bc
+DC = dc
+BC_EXEC = $(BIN)/$(EXEC_PREFIX)$(BC)
+DC_EXEC = $(BIN)/$(EXEC_PREFIX)$(DC)
+
+LIB = libbcl
+LIB_NAME = $(LIB).a
+LIBBC = $(BIN)/$(LIB_NAME)
+BCL = bcl
+BCL_TEST = $(BIN)/$(BCL)
+BCL_TEST_C = tests/$(BCL).c
+
+MANUALS = manuals
+BC_MANPAGE_NAME = $(EXEC_PREFIX)$(BC)$(EXEC_SUFFIX).1
+BC_MANPAGE = $(MANUALS)/$(BC).1
+BC_MD = $(BC_MANPAGE).md
+DC_MANPAGE_NAME = $(EXEC_PREFIX)$(DC)$(EXEC_SUFFIX).1
+DC_MANPAGE = $(MANUALS)/$(DC).1
+DC_MD = $(DC_MANPAGE).md
+BCL_MANPAGE_NAME = bcl.3
+BCL_MANPAGE = $(MANUALS)/$(BCL_MANPAGE_NAME)
+BCL_MD = $(BCL_MANPAGE).md
+
+MANPAGE_INSTALL_ARGS = -Dm644
+BINARY_INSTALL_ARGS = -Dm755
+
+BCL_HEADER_NAME = bcl.h
+BCL_HEADER = include/$(BCL_HEADER_NAME)
+
+%%DESTDIR%%
+BINDIR = %%BINDIR%%
+INCLUDEDIR = %%INCLUDEDIR%%
+LIBDIR = %%LIBDIR%%
+MAN1DIR = %%MAN1DIR%%
+MAN3DIR = %%MAN3DIR%%
+MAIN_EXEC = $(EXEC_PREFIX)$(%%MAIN_EXEC%%)$(EXEC_SUFFIX)
+EXEC = $(%%EXEC%%)
+NLSPATH = %%NLSPATH%%
+
+BC_ENABLE_LIBRARY = %%LIBRARY%%
+
+BC_ENABLE_HISTORY = %%HISTORY%%
+BC_ENABLE_EXTRA_MATH_NAME = BC_ENABLE_EXTRA_MATH
+BC_ENABLE_EXTRA_MATH = %%EXTRA_MATH%%
+BC_ENABLE_NLS = %%NLS%%
+BC_ENABLE_PROMPT = %%PROMPT%%
+BC_LONG_BIT = %%LONG_BIT%%
+
+RM = rm
+MKDIR = mkdir
+
+INSTALL = ./exec-install.sh
+SAFE_INSTALL = ./safe-install.sh
+LINK = ./link.sh
+MANPAGE = ./manpage.sh
+KARATSUBA = ./karatsuba.py
+LOCALE_INSTALL = ./locale_install.sh
+LOCALE_UNINSTALL = ./locale_uninstall.sh
+
+VALGRIND_ARGS = --error-exitcode=100 --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all
+
+BC_NUM_KARATSUBA_LEN = %%KARATSUBA_LEN%%
+
+CPPFLAGS1 = -D$(BC_ENABLED_NAME)=$(BC_ENABLED) -D$(DC_ENABLED_NAME)=$(DC_ENABLED)
+CPPFLAGS2 = $(CPPFLAGS1) -I./include/ -DVERSION=$(VERSION) %%LONG_BIT_DEFINE%%
+CPPFLAGS3 = $(CPPFLAGS2) -DEXECPREFIX=$(EXEC_PREFIX) -DMAINEXEC=$(MAIN_EXEC)
+CPPFLAGS4 = $(CPPFLAGS3) -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700
+CPPFLAGS5 = $(CPPFLAGS4) -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN)
+CPPFLAGS6 = $(CPPFLAGS5) -DBC_ENABLE_NLS=$(BC_ENABLE_NLS) -DBC_ENABLE_PROMPT=$(BC_ENABLE_PROMPT)
+CPPFLAGS7 = $(CPPFLAGS6) -D$(BC_ENABLE_EXTRA_MATH_NAME)=$(BC_ENABLE_EXTRA_MATH)
+CPPFLAGS = $(CPPFLAGS7) -DBC_ENABLE_HISTORY=$(BC_ENABLE_HISTORY) -DBC_ENABLE_LIBRARY=$(BC_ENABLE_LIBRARY)
+CFLAGS = $(CPPFLAGS) %%CPPFLAGS%% %%CFLAGS%%
+LDFLAGS = %%LDFLAGS%%
+
+HOSTCFLAGS = %%HOSTCFLAGS%%
+
+CC = %%CC%%
+HOSTCC = %%HOSTCC%%
+
+BC_LIB_C_ARGS = bc_lib bc_lib_name $(BC_ENABLED_NAME) 1
+BC_LIB2_C_ARGS = bc_lib2 bc_lib2_name "$(BC_ENABLED_NAME) && $(BC_ENABLE_EXTRA_MATH_NAME)" 1
+
+OBJS = $(BC_HELP_O) $(DC_HELP_O) $(BC_LIB_O) $(BC_LIB2_O) $(OBJ)
+OBJ_TARGETS = $(DC_HELP_O) $(BC_HELP_O) $(BC_LIB_O) $(BC_LIB2_O) $(OBJ)
+
+.c.o:
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+all: %%ALL_PREREQ%%
+
+execs: make_bin $(OBJ_TARGETS)
+ $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC)
+ %%LINK%%
+
+library: make_bin $(OBJ) $(BC_LIB_O) $(BC_LIB2_O)
+ ar -r -cu $(LIBBC) $(BC_LIB_O) $(BC_LIB2_O) $(OBJ)
+
+$(GEN_EXEC):
+ %%GEN_EXEC_TARGET%%
+
+$(BC_LIB_C): $(GEN_EXEC) $(BC_LIB)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_LIB) $(BC_LIB_C) $(BC_LIB_C_ARGS)
+
+$(BC_LIB2_C): $(GEN_EXEC) $(BC_LIB2)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_LIB2) $(BC_LIB2_C) $(BC_LIB2_C_ARGS)
+
+$(BC_HELP_C): $(GEN_EXEC) $(BC_HELP)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) bc_help "" $(BC_ENABLED_NAME)
+
+$(DC_HELP_C): $(GEN_EXEC) $(DC_HELP)
+ $(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) dc_help "" $(DC_ENABLED_NAME)
+
+make_bin:
+ $(MKDIR) -p $(BIN)
+
+help:
+ @printf 'available targets:\n'
+ @printf '\n'
+ @printf ' all (default) builds %%EXECUTABLES%%\n'
+ @printf ' check alias for `make test`\n'
+ @printf ' clean removes all build files\n'
+ @printf ' clean_config removes all build files as well as the generated Makefile\n'
+ @printf ' clean_tests removes all build files, the generated Makefile,\n'
+ @printf ' and generated tests\n'
+ @printf ' install installs binaries to "%s%s"\n' "$(DESTDIR)" "$(BINDIR)"
+ @printf ' and (if enabled) manpages to "%s%s"\n' "$(DESTDIR)" "$(MAN1DIR)"
+ @printf ' karatsuba runs the karatsuba script (requires Python 3)\n'
+ @printf ' karatsuba_test runs the karatsuba script while running tests\n'
+ @printf ' (requires Python 3)\n'
+ @printf ' uninstall uninstalls binaries from "%s%s"\n' "$(DESTDIR)" "$(BINDIR)"
+ @printf ' and (if enabled) manpages from "%s%s"\n' "$(DESTDIR)" "$(MAN1DIR)"
+ @printf ' test runs the test suite\n'
+ @printf ' test_bc runs the bc test suite, if bc has been built\n'
+ @printf ' test_dc runs the dc test suite, if dc has been built\n'
+ @printf ' time_test runs the test suite, displaying times for some things\n'
+ @printf ' time_test_bc runs the bc test suite, displaying times for some things\n'
+ @printf ' time_test_dc runs the dc test suite, displaying times for some things\n'
+ @printf ' timeconst runs the test on the Linux timeconst.bc script,\n'
+ @printf ' if it exists and bc has been built\n'
+ @printf ' valgrind runs the test suite through valgrind\n'
+ @printf ' valgrind_bc runs the bc test suite, if bc has been built,\n'
+ @printf ' through valgrind\n'
+ @printf ' valgrind_dc runs the dc test suite, if dc has been built,\n'
+ @printf ' through valgrind\n'
+
+check: test
+
+test: %%TESTS%%
+
+test_bc:
+ %%BC_TEST%%
+
+test_dc:
+ %%DC_TEST%%
+
+time_test: time_test_bc timeconst time_test_dc
+
+time_test_bc:
+ %%BC_TIME_TEST%%
+
+time_test_dc:
+ %%DC_TIME_TEST%%
+
+timeconst:
+ %%TIMECONST%%
+
+library_test: library
+ $(CC) $(CFLAGS) $(BCL_TEST_C) $(LIBBC) -o $(BCL_TEST)
+
+test_library: library_test
+ $(BCL_TEST)
+
+valgrind: valgrind_bc valgrind_dc
+
+valgrind_bc:
+ %%VG_BC_TEST%%
+
+valgrind_dc:
+ %%VG_DC_TEST%%
+
+karatsuba:
+ %%KARATSUBA%%
+
+karatsuba_test:
+ %%KARATSUBA_TEST%%
+
+coverage_output:
+ %%COVERAGE_OUTPUT%%
+
+coverage:%%COVERAGE_PREREQS%%
+
+version:
+ @printf '%s' "$(VERSION)"
+
+libcname:
+ @printf '%s' "$(BC_LIB_C)"
+
+extra_math:
+ @printf '%s' "$(BC_ENABLE_EXTRA_MATH)"
+
+manpages:
+ $(MANPAGE) bc
+ $(MANPAGE) dc
+ $(MANPAGE) bcl
+
+clean_gen:
+ @$(RM) -f $(GEN_EXEC)
+
+clean:%%CLEAN_PREREQS%%
+ @printf 'Cleaning files...\n'
+ @$(RM) -f $(OBJ)
+ @$(RM) -f $(BC_EXEC)
+ @$(RM) -f $(DC_EXEC)
+ @$(RM) -fr $(BIN)
+ @$(RM) -f $(LOCALES)/*.cat
+ @$(RM) -f $(BC_LIB_C) $(BC_LIB_O)
+ @$(RM) -f $(BC_LIB2_C) $(BC_LIB2_O)
+ @$(RM) -f $(BC_HELP_C) $(BC_HELP_O)
+ @$(RM) -f $(DC_HELP_C) $(DC_HELP_O)
+
+clean_config: clean
+ @printf 'Cleaning config...\n'
+ @$(RM) -f Makefile
+ @$(RM) -f $(BC_MD) $(DC_MD)
+ @$(RM) -f $(BC_MANPAGE) $(DC_MANPAGE)
+
+clean_coverage:
+ @printf 'Cleaning coverage files...\n'
+ @$(RM) -f *.gcov
+ @$(RM) -f *.html
+ @$(RM) -f *.gcda *.gcno
+ @$(RM) -f *.profraw
+ @$(RM) -f $(GCDA) $(GCNO)
+ @$(RM) -f $(BC_GCDA) $(BC_GCNO)
+ @$(RM) -f $(DC_GCDA) $(DC_GCNO)
+ @$(RM) -f $(HISTORY_GCDA) $(HISTORY_GCNO)
+ @$(RM) -f $(RAND_GCDA) $(RAND_GCNO)
+ @$(RM) -f $(BC_LIB_GCDA) $(BC_LIB_GCNO)
+ @$(RM) -f $(BC_LIB2_GCDA) $(BC_LIB2_GCNO)
+ @$(RM) -f $(BC_HELP_GCDA) $(BC_HELP_GCNO)
+ @$(RM) -f $(DC_HELP_GCDA) $(DC_HELP_GCNO)
+
+clean_tests: clean clean_config clean_coverage
+ @printf 'Cleaning test files...\n'
+ @$(RM) -f tests/bc/parse.txt tests/bc/parse_results.txt
+ @$(RM) -f tests/bc/print.txt tests/bc/print_results.txt
+ @$(RM) -f tests/bc/bessel.txt tests/bc/bessel_results.txt
+ @$(RM) -f tests/bc/scripts/bessel.txt
+ @$(RM) -f tests/bc/scripts/parse.txt
+ @$(RM) -f tests/bc/scripts/print.txt
+ @$(RM) -f tests/bc/scripts/add.txt
+ @$(RM) -f tests/bc/scripts/divide.txt
+ @$(RM) -f tests/bc/scripts/multiply.txt
+ @$(RM) -f tests/bc/scripts/subtract.txt
+ @$(RM) -f tests/dc/scripts/prime.txt tests/dc/scripts/stream.txt
+ @$(RM) -f .log_*.txt
+ @$(RM) -f .math.txt .results.txt .ops.txt
+ @$(RM) -f .test.txt
+ @$(RM) -f tags .gdbbreakpoints .gdb_history .gdbsetup
+ @$(RM) -f cscope.*
+ @$(RM) -f bc.old
+
+install_locales:
+ %%INSTALL_LOCALES%%
+
+install_bc_manpage:
+ $(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(BC_MANPAGE) $(DESTDIR)$(MAN1DIR)/$(BC_MANPAGE_NAME)
+
+install_dc_manpage:
+ $(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(DC_MANPAGE) $(DESTDIR)$(MAN1DIR)/$(DC_MANPAGE_NAME)
+
+install_bcl_manpage:
+ $(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(BCL_MANPAGE) $(DESTDIR)$(MAN3DIR)/$(BCL_MANPAGE_NAME)
+
+install_bcl_header:
+ $(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(BCL_HEADER) $(DESTDIR)$(INCLUDEDIR)/$(BCL_HEADER_NAME)
+
+install_execs:
+ $(INSTALL) $(DESTDIR)$(BINDIR) "$(EXEC_SUFFIX)"
+
+install_library:
+ $(SAFE_INSTALL) $(BINARY_INSTALL_ARGS) $(LIBBC) $(DESTDIR)$(LIBDIR)/$(LIB_NAME)
+
+install:%%INSTALL_LOCALES_PREREQS%%%%INSTALL_MAN_PREREQS%%%%INSTALL_PREREQS%%
+
+uninstall_locales:
+ $(LOCALE_UNINSTALL) $(NLSPATH) $(MAIN_EXEC) $(DESTDIR)
+
+uninstall_bc_manpage:
+ $(RM) -f $(DESTDIR)$(MAN1DIR)/$(BC_MANPAGE_NAME)
+
+uninstall_bc:
+ $(RM) -f $(DESTDIR)$(BINDIR)/$(EXEC_PREFIX)$(BC)$(EXEC_SUFFIX)
+
+uninstall_dc_manpage:
+ $(RM) -f $(DESTDIR)$(MAN1DIR)/$(DC_MANPAGE_NAME)
+
+uninstall_dc:
+ $(RM) -f $(DESTDIR)$(BINDIR)/$(EXEC_PREFIX)$(DC)$(EXEC_SUFFIX)
+
+uninstall_library:
+ $(RM) -f $(DESTDIR)$(LIBDIR)/$(LIB_NAME)
+
+uninstall_bcl_header:
+ $(RM) -f $(DESTDIR)$(INCLUDEDIR)/$(BCL_HEADER_NAME)
+
+uninstall_bcl_manpage:
+ $(RM) -f $(DESTDIR)$(MAN3DIR)/$(BCL_MANPAGE_NAME)
+
+uninstall:%%UNINSTALL_LOCALES_PREREQS%%%%UNINSTALL_MAN_PREREQS%%%%UNINSTALL_PREREQS%%
diff --git a/contrib/bc/NEWS.md b/contrib/bc/NEWS.md
new file mode 100644
index 000000000000..f4fc2f5779ce
--- /dev/null
+++ b/contrib/bc/NEWS.md
@@ -0,0 +1,975 @@
+# News
+
+## 3.2.4
+
+This is a production release that fixes a warning on `gcc` 6 or older, which
+does not have an attribute that is used.
+
+Users do ***NOT*** need to upgrade if they don't use `gcc` 6 or older.
+
+## 3.2.3
+
+This is a production release that fixes a bug in `gen/strgen.sh`. I recently
+changed `gen/strgen.c`, but I did not change `gen/strgen.sh`.
+
+Users that do not use `gen/strgen.sh` do not need to upgrade.
+
+## 3.2.2
+
+This is a production release that fixes a portability bug in `configure.sh`. The
+bug was using the GNU `find` extension `-wholename`.
+
+## 3.2.1
+
+This is a production release that has one fix for `bcl(3)`. It is technically
+not a bug fix since the behavior is undefined, but the `BclNumber`s that
+`bcl_divmod()` returns will be set to `BCL_ERROR_INVALID_NUM` if there is an
+error. Previously, they were not set.
+
+## 3.2.0
+
+This is a production release that has one bug fix and a major addition.
+
+The bug fix was a missing `auto` variable in the bessel `j()` function in the
+math library.
+
+The major addition is a way to build a version of `bc`'s math code as a library.
+This is done with the `-a` option to `configure.sh`. The API for the library can
+be read in `./manuals/bcl.3.md` or `man bcl` once the library is installed with
+`make install`.
+
+This library was requested by developers before I even finished version 1.0, but
+I could not figure out how to do it until now.
+
+If the library has API breaking changes, the major version of `bc` will be
+incremented.
+
+## 3.1.6
+
+This is a production release that fixes a new warning from Clang 12 for FreeBSD
+and also removes some possible undefined behavior found by UBSan that compilers
+did not seem to take advantage of.
+
+Users do ***NOT*** need to upgrade, if they do not want to.
+
+## 3.1.5
+
+This is a production release that fixes the Chinese locales (which caused `bc`
+to crash) and a crash caused by `bc` executing code when it should not have been
+able to.
+
+***ALL USERS SHOULD UPGRADE.***
+
+## 3.1.4
+
+This is a production release that fixes one bug, changes two behaviors, and
+removes one environment variable.
+
+The bug is like the one in the last release except it applies if files are being
+executed. I also made the fix more general.
+
+The behavior that was changed is that `bc` now exits when given `-e`, `-f`,
+`--expression` or `--file`. However, if the last one of those is `-f-` (using
+`stdin` as the file), `bc` does not exit. If `-f-` exists and is not the last of
+the `-e` and `-f` options (and equivalents), `bc` gives a fatal error and exits.
+
+Next, I removed the `BC_EXPR_EXIT` and `DC_EXPR_EXIT` environment variables
+since their use is not needed with the behavior change.
+
+Finally, I made it so `bc` does not print the header, though the `-q` and
+`--quiet` options were kept for compatibility with GNU `bc`.
+
+## 3.1.3
+
+This is a production release that fixes one minor bug: if `bc` was invoked like
+the following, it would error:
+
+```
+echo "if (1 < 3) 1" | bc
+```
+
+Unless users run into this bug, they do not need to upgrade, but it is suggested
+that they do.
+
+## 3.1.2
+
+This is a production release that adds a way to install *all* locales. Users do
+***NOT*** need to upgrade.
+
+For package maintainers wishing to make use of the change, just pass `-l` to
+`configure.sh`.
+
+## 3.1.1
+
+This is a production release that adds two Spanish locales. Users do ***NOT***
+need to upgrade, unless they want those locales.
+
+## 3.1.0
+
+This is a production release that adjusts one behavior, fixes eight bugs, and
+improves manpages for FreeBSD. Because this release fixes bugs, **users and
+package maintainers should update to this version as soon as possible**.
+
+The behavior that was adjusted was how code from the `-e` and `-f` arguments
+(and equivalents) were executed. They used to be executed as one big chunk, but
+in this release, they are now executed line-by-line.
+
+The first bug fix in how output to `stdout` was handled in `SIGINT`. If a
+`SIGINT` came in, the `stdout` buffer was not correctly flushed. In fact, a
+clean-up function was not getting called. This release fixes that bug.
+
+The second bug is in how `dc` handled input from `stdin`. This affected `bc` as
+well since it was a mishandling of the `stdin` buffer.
+
+The third fixed bug was that `bc` and `dc` could `abort()` (in debug mode) when
+receiving a `SIGTERM`. This one was a race condition with pushing and popping
+items onto and out of vectors.
+
+The fourth bug fixed was that `bc` could leave extra items on the stack and
+thus, not properly clean up some memory. (The memory would still get
+`free()`'ed, but it would not be `free()`'ed when it could have been.)
+
+The next two bugs were bugs in `bc`'s parser that caused crashes when executing
+the resulting code.
+
+The last two bugs were crashes in `dc` that resulted from mishandling of
+strings.
+
+The manpage improvement was done by switching from [ronn][20] to [Pandoc][21] to
+generate manpages. Pandoc generates much cleaner manpages and doesn't leave
+blank lines where they shouldn't be.
+
+## 3.0.3
+
+This is a production release that adds one new feature: specific manpages.
+
+Before this release, `bc` and `dc` only used one manpage each that referred to
+various build options. This release changes it so there is one manpage set per
+relevant build type. Each manual only has information about its particular
+build, and `configure.sh` selects the correct set for install.
+
+## 3.0.2
+
+This is a production release that adds `utf8` locale symlinks and removes an
+unused `auto` variable from the `ceil()` function in the [extended math
+library][16].
+
+Users do ***NOT*** need to update unless they want the locales.
+
+## 3.0.1
+
+This is a production release with two small changes. Users do ***NOT*** need to
+upgrade to this release; however, if they haven't upgraded to `3.0.0` yet, it
+may be worthwhile to upgrade to this release.
+
+The first change is fixing a compiler warning on FreeBSD with strict warnings
+on.
+
+The second change is to make the new implementation of `ceil()` in `lib2.bc`
+much more efficient.
+
+## 3.0.0
+
+*Notes for package maintainers:*
+
+*First, the `2.7.0` release series saw a change in the option parsing. This made
+me change one error message and add a few others. The error message that was
+changed removed one format specifier. This means that `printf()` will seqfault
+on old locale files. Unfortunately, `bc` cannot use any locale files except the
+global ones that are already installed, so it will use the previous ones while
+running tests during install. **If `bc` segfaults while running arg tests when
+updating, it is because the global locale files have not been replaced. Make
+sure to either prevent the test suite from running on update or remove the old
+locale files before updating.** (Removing the locale files can be done with
+`make uninstall` or by running the `locale_uninstall.sh` script.) Once this is
+done, `bc` should install without problems.*
+
+*Second, **the option to build without signal support has been removed**. See
+below for the reasons why.*
+
+This is a production release with some small bug fixes, a few improvements,
+three major bug fixes, and a complete redesign of `bc`'s error and signal
+handling. **Users and package maintainers should update to this version as soon
+as possible.**
+
+The first major bug fix was in how `bc` executed files. Previously, a whole file
+was parsed before it was executed, but if a function is defined *after* code,
+especially if the function definition was actually a redefinition, and the code
+before the definition referred to the previous function, this `bc` would replace
+the function before executing any code. The fix was to make sure that all code
+that existed before a function definition was executed.
+
+The second major bug fix was in `bc`'s `lib2.bc`. The `ceil()` function had a
+bug where a `0` in the decimal place after the truncation position, caused it to
+output the wrong numbers if there was any non-zero digit after.
+
+The third major bug is that when passing parameters to functions, if an
+expression included an array (not an array element) as a parameter, it was
+accepted, when it should have been rejected. It is now correctly rejected.
+
+Beyond that, this `bc` got several improvements that both sped it up, improved
+the handling of signals, and improved the error handling.
+
+First, the requirements for `bc` were pushed back to POSIX 2008. `bc` uses one
+function, `strdup()`, which is not in POSIX 2001, and it is in the X/Open System
+Interfaces group 2001. It is, however, in POSIX 2008, and since POSIX 2008 is
+old enough to be supported anywhere that I care, that should be the requirement.
+
+Second, the BcVm global variable was put into `bss`. This actually slightly
+reduces the size of the executable from a massive code shrink, and it will stop
+`bc` from allocating a large set of memory when `bc` starts.
+
+Third, the default Karatsuba length was updated from 64 to 32 after making the
+optimization changes below, since 32 is going to be better than 64 after the
+changes.
+
+Fourth, Spanish translations were added.
+
+Fifth, the interpreter received a speedup to make performance on non-math-heavy
+scripts more competitive with GNU `bc`. While improvements did, in fact, get it
+much closer (see the [benchmarks][19]), it isn't quite there.
+
+There were several things done to speed up the interpreter:
+
+First, several small inefficiencies were removed. These inefficiencies included
+calling the function `bc_vec_pop(v)` twice instead of calling
+`bc_vec_npop(v, 2)`. They also included an extra function call for checking the
+size of the stack and checking the size of the stack more than once on several
+operations.
+
+Second, since the current `bc` function is the one that stores constants and
+strings, the program caches pointers to the current function's vectors of
+constants and strings to prevent needing to grab the current function in order
+to grab a constant or a string.
+
+Third, `bc` tries to reuse `BcNum`'s (the internal representation of
+arbitary-precision numbers). If a `BcNum` has the default capacity of
+`BC_NUM_DEF_SIZE` (32 on 64-bit and 16 on 32-bit) when it is freed, it is added
+to a list of available `BcNum`'s. And then, when a `BcNum` is allocated with a
+capacity of `BC_NUM_DEF_SIZE` and any `BcNum`'s exist on the list of reusable
+ones, one of those ones is grabbed instead.
+
+In order to support these changes, the `BC_NUM_DEF_SIZE` was changed. It used to
+be 16 bytes on all systems, but it was changed to more closely align with the
+minimum allocation size on Linux, which is either 32 bytes (64-bit musl), 24
+bytes (64-bit glibc), 16 bytes (32-bit musl), or 12 bytes (32-bit glibc). Since
+these are the minimum allocation sizes, these are the sizes that would be
+allocated anyway, making it worth it to just use the whole space, so the value
+of `BC_NUM_DEF_SIZE` on 64-bit systems was changed to 32 bytes.
+
+On top of that, at least on 64-bit, `BC_NUM_DEF_SIZE` supports numbers with
+either 72 integer digits or 45 integer digits and 27 fractional digits. This
+should be more than enough for most cases since `bc`'s default `scale` values
+are 0 or 20, meaning that, by default, it has at most 20 fractional digits. And
+45 integer digits are *a lot*; it's enough to calculate the amount of mass in
+the Milky Way galaxy in kilograms. Also, 72 digits is enough to calculate the
+diameter of the universe in Planck lengths.
+
+(For 32-bit, these numbers are either 32 integer digits or 12 integer digits and
+20 fractional digits. These are also quite big, and going much bigger on a
+32-bit system seems a little pointless since 12 digits in just under a trillion
+and 20 fractional digits is still enough for about any use since `10^-20` light
+years is just under a millimeter.)
+
+All of this together means that for ordinary uses, and even uses in scientific
+work, the default number size will be all that is needed, which means that
+nearly all, if not all, numbers will be reused, relieving pressure on the system
+allocator.
+
+I did several experiments to find the changes that had the most impact,
+especially with regard to reusing `BcNum`'s. One was putting `BcNum`'s into
+buckets according to their capacity in powers of 2 up to 512. That performed
+worse than `bc` did in `2.7.2`. Another was putting any `BcNum` on the reuse
+list that had a capacity of `BC_NUM_DEF_SIZE * 2` and reusing them for `BcNum`'s
+that requested `BC_NUM_DEF_SIZE`. This did reduce the amount of time spent, but
+it also spent a lot of time in the system allocator for an unknown reason. (When
+using `strace`, a bunch more `brk` calls showed up.) Just reusing `BcNum`'s that
+had exactly `BC_NUM_DEF_SIZE` capacity spent the smallest amount of time in both
+user and system time. This makes sense, especially with the changes to make
+`BC_NUM_DEF_SIZE` bigger on 64-bit systems, since the vast majority of numbers
+will only ever use numbers with a size less than or equal to `BC_NUM_DEF_SIZE`.
+
+Last of all, `bc`'s signal handling underwent a complete redesign. (This is the
+reason that this version is `3.0.0` and not `2.8.0`.) The change was to move
+from a polling approach to signal handling to an interrupt-based approach.
+
+Previously, every single loop condition had a check for signals. I suspect that
+this could be expensive when in tight loops.
+
+Now, the signal handler just uses `longjmp()` (actually `siglongjmp()`) to start
+an unwinding of the stack until it is stopped or the stack is unwound to
+`main()`, which just returns. If `bc` is currently executing code that cannot be
+safely interrupted (according to POSIX), then signals are "locked." The signal
+handler checks if the lock is taken, and if it is, it just sets the status to
+indicate that a signal arrived. Later, when the signal lock is released, the
+status is checked to see if a signal came in. If so, the stack unwinding starts.
+
+This design eliminates polling in favor of maintaining a stack of `jmp_buf`'s.
+This has its own performance implications, but it gives better interaction. And
+the cost of pushing and popping a `jmp_buf` in a function is paid at most twice.
+Most functions do not pay that price, and most of the rest only pay it once.
+(There are only some 3 functions in `bc` that push and pop a `jmp_buf` twice.)
+
+As a side effect of this change, I had to eliminate the use of `stdio.h` in `bc`
+because `stdio` does not play nice with signals and `longjmp()`. I implemented
+custom I/O buffer code that takes a fraction of the size. This means that static
+builds will be smaller, but non-static builds will be bigger, though they will
+have less linking time.
+
+This change is also good because my history implementation was already bypassing
+`stdio` for good reasons, and unifying the architecture was a win.
+
+Another reason for this change is that my `bc` should *always* behave correctly
+in the presence of signals like `SIGINT`, `SIGTERM`, and `SIGQUIT`. With the
+addition of my own I/O buffering, I needed to also make sure that the buffers
+were correctly flushed even when such signals happened.
+
+For this reason, I **removed the option to build without signal support**.
+
+As a nice side effect of this change, the error handling code could be changed
+to take advantage of the stack unwinding that signals used. This means that
+signals and error handling use the same code paths, which means that the stack
+unwinding is well-tested. (Errors are tested heavily in the test suite.)
+
+It also means that functions do not need to return a status code that
+***every*** caller needs to check. This eliminated over 100 branches that simply
+checked return codes and then passed that return code up the stack if necessary.
+The code bloat savings from this is at least 1700 bytes on `x86_64`, *before*
+taking into account the extra code from removing `stdio.h`.
+
+## 2.7.2
+
+This is a production release with one major bug fix.
+
+The `length()` built-in function can take either a number or an array. If it
+takes an array, it returns the length of the array. Arrays can be passed by
+reference. The bug is that the `length()` function would not properly
+dereference arrays that were references. This is a bug that affects all users.
+
+**ALL USERS SHOULD UPDATE `bc`**.
+
+## 2.7.1
+
+This is a production release with fixes for new locales and fixes for compiler
+warnings on FreeBSD.
+
+## 2.7.0
+
+This is a production release with a bug fix for Linux, new translations, and new
+features.
+
+Bug fixes:
+
+* Option parsing in `BC_ENV_ARGS` was broken on Linux in 2.6.1 because `glibc`'s
+ `getopt_long()` is broken. To get around that, and to support long options on
+ every platform, an adapted version of [`optparse`][17] was added. Now, `bc`
+ does not even use `getopt()`.
+* Parsing `BC_ENV_ARGS` with quotes now works. It isn't the smartest, but it
+ does the job if there are spaces in file names.
+
+The following new languages are supported:
+
+* Dutch
+* Polish
+* Russian
+* Japanes
+* Simplified Chinese
+
+All of these translations were generated using [DeepL][18], so improvements are
+welcome.
+
+There is only one new feature: **`bc` now has a built-in pseudo-random number
+generator** (PRNG).
+
+The PRNG is seeded, making it useful for applications where
+`/dev/urandom` does not work because output needs to be reproducible. However,
+it also uses `/dev/urandom` to seed itself by default, so it will start with a
+good seed by default.
+
+It also outputs 32 bits on 32-bit platforms and 64 bits on 64-bit platforms, far
+better than the 15 bits of C's `rand()` and `bash`'s `$RANDOM`.
+
+In addition, the PRNG can take a bound, and when it gets a bound, it
+automatically adjusts to remove bias. It can also generate numbers of arbitrary
+size. (As of the time of release, the largest pseudo-random number generated by
+this `bc` was generated with a bound of `2^(2^20)`.)
+
+***IMPORTANT: read the [`bc` manual][9] and the [`dc` manual][10] to find out
+exactly what guarantees the PRNG provides. The underlying implementation is not
+guaranteed to stay the same, but the guarantees that it provides are guaranteed
+to stay the same regardless of the implementation.***
+
+On top of that, four functions were added to `bc`'s [extended math library][16]
+to make using the PRNG easier:
+
+* `frand(p)`: Generates a number between `[0,1)` to `p` decimal places.
+* `ifrand(i, p)`: Generates an integer with bound `i` and adds it to `frand(p)`.
+* `srand(x)`: Randomizes the sign of `x`. In other words, it flips the sign of
+ `x` with probability `0.5`.
+* `brand()`: Returns a random boolean value (either `0` or `1`).
+
+## 2.6.1
+
+This is a production release with a bug fix for FreeBSD.
+
+The bug was that when `bc` was built without long options, it would give a fatal
+error on every run. This was caused by a mishandling of `optind`.
+
+## 2.6.0
+
+This release is a production release ***with no bugfixes***. If you do not want
+to upgrade, you don't have to.
+
+No source code changed; the only thing that changed was `lib2.bc`.
+
+This release adds one function to the [extended math library][16]: `p(x, y)`,
+which calculates `x` to the power of `y`, whether or not `y` is an integer. (The
+`^` operator can only accept integer powers.)
+
+This release also includes a couple of small tweaks to the [extended math
+library][16], mostly to fix returning numbers with too high of `scale`.
+
+## 2.5.3
+
+This release is a production release which addresses inconsistencies in the
+Portuguese locales. No `bc` code was changed.
+
+The issues were that the ISO files used different naming, and also that the
+files that should have been symlinks were not. I did not catch that because
+GitHub rendered them the exact same way.
+
+## 2.5.2
+
+This release is a production release.
+
+No code was changed, but the build system was changed to allow `CFLAGS` to be
+given to `CC`, like this:
+
+```
+CC="gcc -O3 -march=native" ./configure.sh
+```
+
+If this happens, the flags are automatically put into `CFLAGS`, and the compiler
+is set appropriately. In the example above this means that `CC` will be "gcc"
+and `CFLAGS` will be "-O3 -march=native".
+
+This behavior was added to conform to GNU autotools practices.
+
+## 2.5.1
+
+This is a production release which addresses portability concerns discovered
+in the `bc` build system. No `bc` code was changed.
+
+* Support for Solaris SPARC and AIX were added.
+* Minor documentations edits were performed.
+* An option for `configure.sh` was added to disable long options if
+ `getopt_long()` is missing.
+
+## 2.5.0
+
+This is a production release with new translations. No code changed.
+
+The translations were contributed by [bugcrazy][15], and they are for
+Portuguese, both Portugal and Brazil locales.
+
+## 2.4.0
+
+This is a production release primarily aimed at improving `dc`.
+
+* A couple of copy and paste errors in the [`dc` manual][10] were fixed.
+* `dc` startup was optimized by making sure it didn't have to set up `bc`-only
+ things.
+* The `bc` `&&` and `||` operators were made available to `dc` through the `M`
+ and `m` commands, respectively.
+* `dc` macros were changed to be tail call-optimized.
+
+The last item, tail call optimization, means that if the last thing in a macro
+is a call to another macro, then the old macro is popped before executing the
+new macro. This change was made to stop `dc` from consuming more and more memory
+as macros are executed in a loop.
+
+The `q` and `Q` commands still respect the "hidden" macros by way of recording
+how many macros were removed by tail call optimization.
+
+## 2.3.2
+
+This is a production release meant to fix warnings in the Gentoo `ebuild` by
+making it possible to disable binary stripping. Other users do *not* need to
+upgrade.
+
+## 2.3.1
+
+This is a production release. It fixes a bug that caused `-1000000000 < -1` to
+return `0`. This only happened with negative numbers and only if the value on
+the left was more negative by a certain amount. That said, this bug *is* a bad
+bug, and needs to be fixed.
+
+**ALL USERS SHOULD UPDATE `bc`**.
+
+## 2.3.0
+
+This is a production release with changes to the build system.
+
+## 2.2.0
+
+This release is a production release. It only has new features and performance
+improvements.
+
+1. The performance of `sqrt(x)` was improved.
+2. The new function `root(x, n)` was added to the extended math library to
+ calculate `n`th roots.
+3. The new function `cbrt(x)` was added to the extended math library to
+ calculate cube roots.
+
+## 2.1.3
+
+This is a non-critical release; it just changes the build system, and in
+non-breaking ways:
+
+1. Linked locale files were changed to link to their sources with a relative
+ link.
+2. A bug in `configure.sh` that caused long option parsing to fail under `bash`
+ was fixed.
+
+## 2.1.2
+
+This release is not a critical release.
+
+1. A few codes were added to history.
+2. Multiplication was optimized a bit more.
+3. Addition and subtraction were both optimized a bit more.
+
+## 2.1.1
+
+This release contains a fix for the test suite made for Linux from Scratch: now
+the test suite prints `pass` when a test is passed.
+
+Other than that, there is no change in this release, so distros and other users
+do not need to upgrade.
+
+## 2.1.0
+
+This release is a production release.
+
+The following bugs were fixed:
+
+1. A `dc` bug that caused stack mishandling was fixed.
+2. A warning on OpenBSD was fixed.
+3. Bugs in `ctrl+arrow` operations in history were fixed.
+4. The ability to paste multiple lines in history was added.
+5. A `bc` bug, mishandling of array arguments to functions, was fixed.
+6. A crash caused by freeing the wrong pointer was fixed.
+7. A `dc` bug where strings, in a rare case, were mishandled in parsing was
+ fixed.
+
+In addition, the following changes were made:
+
+1. Division was slightly optimized.
+2. An option was added to the build to disable printing of prompts.
+3. The special case of empty arguments is now handled. This is to prevent
+ errors in scripts that end up passing empty arguments.
+4. A harmless bug was fixed. This bug was that, with the pop instructions
+ (mostly) removed (see below), `bc` would leave extra values on its stack for
+ `void` functions and in a few other cases. These extra items would not
+ affect anything put on the stack and would not cause any sort of crash or
+ even buggy behavior, but they would cause `bc` to take more memory than it
+ needed.
+
+On top of the above changes, the following optimizations were added:
+
+1. The need for pop instructions in `bc` was removed.
+2. Extra tests on every iteration of the interpreter loop were removed.
+3. Updating function and code pointers on every iteration of the interpreter
+ loop was changed to only updating them when necessary.
+4. Extra assignments to pointers were removed.
+
+Altogether, these changes sped up the interpreter by around 2x.
+
+***NOTE***: This is the last release with new features because this `bc` is now
+considered complete. From now on, only bug fixes and new translations will be
+added to this `bc`.
+
+## 2.0.3
+
+This is a production, bug-fix release.
+
+Two bugs were fixed in this release:
+
+1. A rare and subtle signal handling bug was fixed.
+2. A misbehavior on `0` to a negative power was fixed.
+
+The last bug bears some mentioning.
+
+When I originally wrote power, I did not thoroughly check its error cases;
+instead, I had it check if the first number was `0` and then if so, just return
+`0`. However, `0` to a negative power means that `1` will be divided by `0`,
+which is an error.
+
+I caught this, but only after I stopped being cocky. You see, sometime later, I
+had noticed that GNU `bc` returned an error, correctly, but I thought it was
+wrong simply because that's not what my `bc` did. I saw it again later and had a
+double take. I checked for real, finally, and found out that my `bc` was wrong
+all along.
+
+That was bad on me. But the bug was easy to fix, so it is fixed now.
+
+There are two other things in this release:
+
+1. Subtraction was optimized by [Stefan Eßer][14].
+2. Division was also optimized, also by Stefan Eßer.
+
+## 2.0.2
+
+This release contains a fix for a possible overflow in the signal handling. I
+would be surprised if any users ran into it because it would only happen after 2
+billion (`2^31-1`) `SIGINT`'s, but I saw it and had to fix it.
+
+## 2.0.1
+
+This release contains very few things that will apply to any users.
+
+1. A slight bug in `dc`'s interactive mode was fixed.
+2. A bug in the test suite that was only triggered on NetBSD was fixed.
+3. **The `-P`/`--no-prompt` option** was added for users that do not want a
+ prompt.
+4. A `make check` target was added as an alias for `make test`.
+5. `dc` got its own read prompt: `?> `.
+
+## 2.0.0
+
+This release is a production release.
+
+This release is also a little different from previous releases. From here on
+out, I do not plan on adding any more features to this `bc`; I believe that it
+is complete. However, there may be bug fix releases in the future, if I or any
+others manage to find bugs.
+
+This release has only a few new features:
+
+1. `atan2(y, x)` was added to the extended math library as both `a2(y, x)` and
+ `atan2(y, x)`.
+2. Locales were fixed.
+3. A **POSIX shell-compatible script was added as an alternative to compiling
+ `gen/strgen.c`** on a host machine. More details about making the choice
+ between the two can be found by running `./configure.sh --help` or reading
+ the [build manual][13].
+4. Multiplication was optimized by using **diagonal multiplication**, rather
+ than straight brute force.
+5. The `locale_install.sh` script was fixed.
+6. `dc` was given the ability to **use the environment variable
+ `DC_ENV_ARGS`**.
+7. `dc` was also given the ability to **use the `-i` or `--interactive`**
+ options.
+8. Printing the prompt was fixed so that it did not print when it shouldn't.
+9. Signal handling was fixed.
+10. **Handling of `SIGTERM` and `SIGQUIT`** was fixed.
+11. The **built-in functions `maxibase()`, `maxobase()`, and `maxscale()`** (the
+ commands `T`, `U`, `V` in `dc`, respectively) were added to allow scripts to
+ query for the max allowable values of those globals.
+12. Some incompatibilities with POSIX were fixed.
+
+In addition, this release is `2.0.0` for a big reason: the internal format for
+numbers changed. They used to be a `char` array. Now, they are an array of
+larger integers, packing more decimal digits into each integer. This has
+delivered ***HUGE*** performance improvements, especially for multiplication,
+division, and power.
+
+This `bc` should now be the fastest `bc` available, but I may be wrong.
+
+## 1.2.8
+
+This release contains a fix for a harmless bug (it is harmless in that it still
+works, but it just copies extra data) in the [`locale_install.sh`][12] script.
+
+## 1.2.7
+
+This version contains fixes for the build on Arch Linux.
+
+## 1.2.6
+
+This release removes the use of `local` in shell scripts because it's not POSIX
+shell-compatible, and also updates a man page that should have been updated a
+long time ago but was missed.
+
+## 1.2.5
+
+This release contains some missing locale `*.msg` files.
+
+## 1.2.4
+
+This release contains a few bug fixes and new French translations.
+
+## 1.2.3
+
+This release contains a fix for a bug: use of uninitialized data. Such data was
+only used when outputting an error message, but I am striving for perfection. As
+Michelangelo said, "Trifles make perfection, and perfection is no trifle."
+
+## 1.2.2
+
+This release contains fixes for OpenBSD.
+
+## 1.2.1
+
+This release contains bug fixes for some rare bugs.
+
+## 1.2.0
+
+This is a production release.
+
+There have been several changes since `1.1.0`:
+
+1. The build system had some changes.
+2. Locale support has been added. (Patches welcome for translations.)
+3. **The ability to turn `ibase`, `obase`, and `scale` into stacks** was added
+ with the `-g` command-line option. (See the [`bc` manual][9] for more
+ details.)
+4. Support for compiling on Mac OSX out of the box was added.
+5. The extended math library got `t(x)`, `ceil(x)`, and some aliases.
+6. The extended math library also got `r2d(x)` (for converting from radians to
+ degrees) and `d2r(x)` (for converting from degrees to radians). This is to
+ allow using degrees with the standard library.
+7. Both calculators now accept numbers in **scientific notation**. See the
+ [`bc` manual][9] and the [`dc` manual][10] for details.
+8. Both calculators can **output in either scientific or engineering
+ notation**. See the [`bc` manual][9] and the [`dc` manual][10] for details.
+9. Some inefficiencies were removed.
+10. Some bugs were fixed.
+11. Some bugs in the extended library were fixed.
+12. Some defects from [Coverity Scan][11] were fixed.
+
+## 1.1.4
+
+This release contains a fix to the build system that allows it to build on older
+versions of `glibc`.
+
+## 1.1.3
+
+This release contains a fix for a bug in the test suite where `bc` tests and
+`dc` tests could not be run in parallel.
+
+## 1.1.2
+
+This release has a fix for a history bug; the down arrow did not work.
+
+## 1.1.1
+
+This release fixes a bug in the `1.1.0` build system. The source is exactly the
+same.
+
+The bug that was fixed was a failure to install if no `EXECSUFFIX` was used.
+
+## 1.1.0
+
+This is a production release. However, many new features were added since `1.0`.
+
+1. **The build system has been changed** to use a custom, POSIX
+ shell-compatible configure script ([`configure.sh`][6]) to generate a POSIX
+ make-compatible `Makefile`, which means that `bc` and `dc` now build out of
+ the box on any POSIX-compatible system.
+2. Out-of-memory and output errors now cause the `bc` to report the error,
+ clean up, and die, rather than just reporting and trying to continue.
+3. **Strings and constants are now garbage collected** when possible.
+4. Signal handling and checking has been made more simple and more thorough.
+5. `BcGlobals` was refactored into `BcVm` and `BcVm` was made global. Some
+ procedure names were changed to reflect its difference to everything else.
+6. Addition got a speed improvement.
+7. Some common code for addition and multiplication was refactored into its own
+ procedure.
+8. A bug was removed where `dc` could have been selected, but the internal
+ `#define` that returned `true` for a query about `dc` would not have
+ returned `true`.
+9. Useless calls to `bc_num_zero()` were removed.
+10. **History support was added.** The history support is based off of a
+ [UTF-8 aware fork][7] of [`linenoise`][8], which has been customized with
+ `bc`'s own data structures and signal handling.
+11. Generating C source from the math library now removes tabs from the library,
+ shrinking the size of the executable.
+12. The math library was shrunk.
+13. Error handling and reporting was improved.
+14. Reallocations were reduced by giving access to the request size for each
+ operation.
+15. **`abs()` (`b` command for `dc`) was added as a builtin.**
+16. Both calculators were tested on FreeBSD.
+17. Many obscure parse bugs were fixed.
+18. Markdown and man page manuals were added, and the man pages are installed by
+ `make install`.
+19. Executable size was reduced, though the added features probably made the
+ executable end up bigger.
+20. **GNU-style array references were added as a supported feature.**
+21. Allocations were reduced.
+22. **New operators were added**: `$` (`$` for `dc`), `@` (`@` for `dc`), `@=`,
+ `<<` (`H` for `dc`), `<<=`, `>>` (`h` for `dc`), and `>>=`. See the
+ [`bc` manual][9] and the [`dc` manual][10] for more details.
+23. **An extended math library was added.** This library contains code that
+ makes it so I can replace my desktop calculator with this `bc`. See the
+ [`bc` manual][3] for more details.
+24. Support for all capital letters as numbers was added.
+25. **Support for GNU-style void functions was added.**
+26. A bug fix for improper handling of function parameters was added.
+27. Precedence for the or (`||`) operator was changed to match GNU `bc`.
+28. `dc` was given an explicit negation command.
+29. `dc` was changed to be able to handle strings in arrays.
+
+## 1.1 Release Candidate 3
+
+This release is the eighth release candidate for 1.1, though it is the third
+release candidate meant as a general release candidate. The new code has not
+been tested as thoroughly as it should for release.
+
+## 1.1 Release Candidate 2
+
+This release is the seventh release candidate for 1.1, though it is the second
+release candidate meant as a general release candidate. The new code has not
+been tested as thoroughly as it should for release.
+
+## 1.1 FreeBSD Beta 5
+
+This release is the sixth release candidate for 1.1, though it is the fifth
+release candidate meant specifically to test if `bc` works on FreeBSD. The new
+code has not been tested as thoroughly as it should for release.
+
+## 1.1 FreeBSD Beta 4
+
+This release is the fifth release candidate for 1.1, though it is the fourth
+release candidate meant specifically to test if `bc` works on FreeBSD. The new
+code has not been tested as thoroughly as it should for release.
+
+## 1.1 FreeBSD Beta 3
+
+This release is the fourth release candidate for 1.1, though it is the third
+release candidate meant specifically to test if `bc` works on FreeBSD. The new
+code has not been tested as thoroughly as it should for release.
+
+## 1.1 FreeBSD Beta 2
+
+This release is the third release candidate for 1.1, though it is the second
+release candidate meant specifically to test if `bc` works on FreeBSD. The new
+code has not been tested as thoroughly as it should for release.
+
+## 1.1 FreeBSD Beta 1
+
+This release is the second release candidate for 1.1, though it is meant
+specifically to test if `bc` works on FreeBSD. The new code has not been tested as
+thoroughly as it should for release.
+
+## 1.1 Release Candidate 1
+
+This is the first release candidate for 1.1. The new code has not been tested as
+thoroughly as it should for release.
+
+## 1.0
+
+This is the first non-beta release. `bc` is ready for production use.
+
+As such, a lot has changed since 0.5.
+
+1. `dc` has been added. It has been tested even more thoroughly than `bc` was
+ for `0.5`. It does not have the `!` command, and for security reasons, it
+ never will, so it is complete.
+2. `bc` has been more thoroughly tested. An entire section of the test suite
+ (for both programs) has been added to test for errors.
+3. A prompt (`>>> `) has been added for interactive mode, making it easier to
+ see inputs and outputs.
+4. Interrupt handling has been improved, including elimination of race
+ conditions (as much as possible).
+5. MinGW and [Windows Subsystem for Linux][1] support has been added (see
+ [xstatic][2] for binaries).
+6. Memory leaks and errors have been eliminated (as far as ASan and Valgrind
+ can tell).
+7. Crashes have been eliminated (as far as [afl][3] can tell).
+8. Karatsuba multiplication was added (and thoroughly) tested, speeding up
+ multiplication and power by orders of magnitude.
+9. Performance was further enhanced by using a "divmod" function to reduce
+ redundant divisions and by removing superfluous `memset()` calls.
+10. To switch between Karatsuba and `O(n^2)` multiplication, the config variable
+ `BC_NUM_KARATSUBA_LEN` was added. It is set to a sane default, but the
+ optimal number can be found with [`karatsuba.py`][4] (requires Python 3)
+ and then configured through `make`.
+11. The random math test generator script was changed to Python 3 and improved.
+ `bc` and `dc` have together been run through 30+ million random tests.
+12. All known math bugs have been fixed, including out of control memory
+ allocations in `sine` and `cosine` (that was actually a parse bug), certain
+ cases of infinite loop on square root, and slight inaccuracies (as much as
+ possible; see the [README][5]) in transcendental functions.
+13. Parsing has been fixed as much as possible.
+14. Test coverage was improved to 94.8%. The only paths not covered are ones
+ that happen when `malloc()` or `realloc()` fails.
+15. An extension to get the length of an array was added.
+16. The boolean not (`!`) had its precedence change to match negation.
+17. Data input was hardened.
+18. `bc` was made fully compliant with POSIX when the `-s` flag is used or
+ `POSIXLY_CORRECT` is defined.
+19. Error handling was improved.
+20. `bc` now checks that files it is given are not directories.
+
+## 1.0 Release Candidate 7
+
+This is the seventh release candidate for 1.0. It fixes a few bugs in 1.0
+Release Candidate 6.
+
+## 1.0 Release Candidate 6
+
+This is the sixth release candidate for 1.0. It fixes a few bugs in 1.0 Release
+Candidate 5.
+
+## 1.0 Release Candidate 5
+
+This is the fifth release candidate for 1.0. It fixes a few bugs in 1.0 Release
+Candidate 4.
+
+## 1.0 Release Candidate 4
+
+This is the fourth release candidate for 1.0. It fixes a few bugs in 1.0 Release
+Candidate 3.
+
+## 1.0 Release Candidate 3
+
+This is the third release candidate for 1.0. It fixes a few bugs in 1.0 Release
+Candidate 2.
+
+## 1.0 Release Candidate 2
+
+This is the second release candidate for 1.0. It fixes a few bugs in 1.0 Release
+Candidate 1.
+
+## 1.0 Release Candidate 1
+
+This is the first Release Candidate for 1.0. `bc` is complete, with `dc`, but it
+is not tested.
+
+## 0.5
+
+This beta release completes more features, but it is still not complete nor
+tested as thoroughly as necessary.
+
+## 0.4.1
+
+This beta release fixes a few bugs in 0.4.
+
+## 0.4
+
+This is a beta release. It does not have the complete set of features, and it is
+not thoroughly tested.
+
+[1]: https://docs.microsoft.com/en-us/windows/wsl/install-win10
+[2]: https://pkg.musl.cc/bc/
+[3]: http://lcamtuf.coredump.cx/afl/
+[4]: ./karatsuba.py
+[5]: ./README.md
+[6]: ./configure.sh
+[7]: https://github.com/rain-1/linenoise-mob
+[8]: https://github.com/antirez/linenoise
+[9]: ./manuals/bc/A.1.md
+[10]: ./manuals/dc/A.1.md
+[11]: https://scan.coverity.com/projects/gavinhoward-bc
+[12]: ./locale_install.sh
+[13]: ./manuals/build.md
+[14]: https://github.com/stesser
+[15]: https://github.com/bugcrazy
+[16]: ./manuals/bc/A.1.md#extended-library
+[17]: https://github.com/skeeto/optparse
+[18]: https://www.deepl.com/translator
+[19]: ./manuals/benchmarks.md
+[20]: https://github.com/apjanke/ronn-ng
+[21]: https://pandoc.org/
diff --git a/contrib/bc/NOTICE.md b/contrib/bc/NOTICE.md
new file mode 100644
index 000000000000..92117daa9a6c
--- /dev/null
+++ b/contrib/bc/NOTICE.md
@@ -0,0 +1,14 @@
+# Notice
+
+Copyright 2018-2020 Gavin D. Howard and contributors.
+
+## Contributors
+
+The contributors to `bc` (besides Gavin) are listed below in alphabetical order.
+
+* Laurent Bercot (skarnet)
+* Stefan Eßer (stesser)
+* Michael Forney (michaelforney)
+* John Regan (jprjr)
+* rofl0r
+* Zach van Rijn (me@zv.io)
diff --git a/contrib/bc/README.md b/contrib/bc/README.md
new file mode 100644
index 000000000000..6f3c3f252cbc
--- /dev/null
+++ b/contrib/bc/README.md
@@ -0,0 +1,347 @@
+# `bc`
+
+[![Coverity Scan Build Status][17]][18]
+
+***WARNING: This project has moved to [https://git.yzena.com/][20] for [these
+reasons][21], though GitHub will remain a mirror.***
+
+This is an implementation of the [POSIX `bc` calculator][12] that implements
+[GNU `bc`][1] extensions, as well as the period (`.`) extension for the BSD
+flavor of `bc`.
+
+For more information, see this `bc`'s full manual.
+
+This `bc` also includes an implementation of `dc` in the same binary, accessible
+via a symbolic link, which implements all FreeBSD and GNU extensions. (If a
+standalone `dc` binary is desired, `bc` can be copied and renamed to `dc`.) The
+`!` command is omitted; I believe this poses security concerns and that such
+functionality is unnecessary.
+
+For more information, see the `dc`'s full manual.
+
+This `bc` is Free and Open Source Software (FOSS). It is offered under the BSD
+2-clause License. Full license text may be found in the [`LICENSE.md`][4] file.
+
+## Prerequisites
+
+This `bc` only requires a C99-compatible compiler and a (mostly) POSIX
+2008-compatible system with the XSI (X/Open System Interfaces) option group.
+
+Since POSIX 2008 with XSI requires the existence of a C99 compiler as `c99`, any
+POSIX and XSI-compatible system will have everything needed.
+
+Systems that are known to work:
+
+* Linux
+* FreeBSD
+* OpenBSD
+* NetBSD
+* Mac OSX
+* Solaris* (as long as the Solaris version supports POSIX 2008)
+* AIX
+
+Please submit bug reports if this `bc` does not build out of the box on any
+system besides Windows. If Windows binaries are needed, they can be found at
+[xstatic][6].
+
+## Build
+
+This `bc` should build unmodified on any POSIX-compliant system.
+
+For more complex build requirements than the ones below, see the
+[build manual][5].
+
+### Pre-built Binaries
+
+It is possible to download pre-compiled binaries for a wide list of platforms,
+including Linux- and Windows-based systems, from [xstatic][6]. This link always
+points to the latest release of `bc`.
+
+### Default
+
+For the default build with optimization, use the following commands in the root
+directory:
+
+```
+./configure.sh -O3
+make
+```
+
+### One Calculator
+
+To only build `bc`, use the following commands:
+
+```
+./configure.sh --disable-dc
+make
+```
+
+To only build `dc`, use the following commands:
+
+```
+./configure.sh --disable-bc
+make
+```
+
+### Debug
+
+For debug builds, use the following commands in the root directory:
+
+```
+./configure.sh -g
+make
+```
+
+### Install
+
+To install, use the following command:
+
+```
+make install
+```
+
+By default, `bc` and `dc` will be installed in `/usr/local`. For installing in
+other locations, use the `PREFIX` environment variable when running
+`configure.sh` or pass the `--prefix=<prefix>` option to `configure.sh`. See the
+[build manual][5], or run `./configure.sh --help`, for more details.
+
+### Library
+
+This `bc` does provide a way to build a math library with C bindings. This is
+done by the `-a` or `--library` options to `configure.sh`:
+
+```
+./configure.sh -a
+```
+
+When building the library, the executables are not built. For more information,
+see the [build manual][5].
+
+The library API can be found in [`manuals/bcl.3.md`][26] or `man bcl` once the
+library is installed.
+
+The library is built as `bin/libbcl.a`.
+
+### Package and Distro Maintainers
+
+#### Recommended Compiler
+
+When I ran benchmarks with my `bc` compiled under `clang`, it performed much
+better than when compiled under `gcc`. I recommend compiling this `bc` with
+`clang`.
+
+I also recommend building this `bc` with C11 if you can because `bc` will detect
+a C11 compiler and add `_Noreturn` to any relevant function(s).
+
+#### Recommended Optimizations
+
+I wrote this `bc` with Separation of Concerns, which means that there are many
+small functions that could be inlined. However, they are often called across
+file boundaries, and the default optimizer can only look at the current file,
+which means that they are not inlined.
+
+Thus, because of the way this `bc` is built, it will automatically be slower
+than other `bc` implementations when running scripts with no math. (My `bc`'s
+math is *much* faster, so any non-trivial script should run faster in my `bc`.)
+
+Some, or all, of the difference can be made up with the right optimizations. The
+optimizations I recommend are:
+
+1. `-O3`
+2. `-flto` (link-time optimization)
+
+in that order.
+
+Link-time optimization, in particular, speeds up the `bc` a lot. This is because
+when link-time optimization is turned on, the optimizer can look across files
+and inline *much* more heavily.
+
+However, I recommend ***NOT*** using `-march=native`. Doing so will reduce this
+`bc`'s performance, at least when building with link-time optimization. See the
+[benchmarks][19] for more details.
+
+#### Stripping Binaries
+
+By default, non-debug binaries are stripped, but stripping can be disabled with
+the `-T` option to `configure.sh`.
+
+#### Using This `bc` as an Alternative
+
+If this `bc` is packaged as an alternative to an already existing `bc` package,
+it is possible to rename it in the build to prevent name collision. To prepend
+to the name, just run the following:
+
+```
+EXECPREFIX=<some_prefix> ./configure.sh
+```
+
+To append to the name, just run the following:
+
+```
+EXECSUFFIX=<some_suffix> ./configure.sh
+```
+
+If a package maintainer wishes to add both a prefix and a suffix, that is
+allowed.
+
+**Note**: The suggested name (and package name) when `bc` is not available is
+`bc-gh`.
+
+#### Karatsuba Number
+
+Package and distro maintainers have one tool at their disposal to build this
+`bc` in the optimal configuration: `karatsuba.py`.
+
+This script is not a compile-time or runtime prerequisite; it is for package and
+distro maintainers to run once when a package is being created. It finds the
+optimal Karatsuba number (see the [algorithms manual][7] for more information)
+for the machine that it is running on.
+
+The easiest way to run this script is with `make karatsuba`.
+
+If desired, maintainers can also skip running this script because there is a
+sane default for the Karatsuba number.
+
+## Status
+
+This `bc` is robust.
+
+It is well-tested, fuzzed, and fully standards-compliant (though not certified)
+with POSIX `bc`. The math has been tested with 40+ million random problems, so
+it is as correct as I can make it.
+
+This `bc` can be used as a drop-in replacement for any existing `bc`. This `bc`
+is also compatible with MinGW toolchains, though history is not supported on
+Windows.
+
+In addition, this `bc` is considered complete; i.e., there will be no more
+releases with additional features. However, it *is* actively maintained, so if
+any bugs are found, they will be fixed in new releases. Also, additional
+translations will also be added as they are provided.
+
+## Comparison to GNU `bc`
+
+This `bc` compares favorably to GNU `bc`.
+
+* It has more extensions, which make this `bc` more useful for scripting.
+* This `bc` is a bit more POSIX compliant.
+* It has a much less buggy parser. The GNU `bc` will give parse errors for what
+ is actually valid `bc` code, or should be. For example, putting an `else` on
+ a new line after a brace can cause GNU `bc` to give a parse error.
+* This `bc` has fewer crashes.
+* GNU `bc` calculates the wrong number of significant digits for `length(x)`.
+* GNU `bc` will sometimes print numbers incorrectly. For example, when running
+ it on the file `tests/bc/power.txt` in this repo, GNU `bc` gets all the right
+ answers, but it fails to wrap the numbers at the proper place when outputting
+ to a file.
+* This `bc` is faster. (See [Performance](#performance).)
+
+### Performance
+
+Because this `bc` packs more than `1` decimal digit per hardware integer, this
+`bc` is faster than GNU `bc` and can be *much* faster. Full benchmarks can be
+found at [manuals/benchmarks.md][19].
+
+There is one instance where this `bc` is slower: if scripts are light on math.
+This is because this `bc`'s intepreter is slightly slower than GNU `bc`, but
+that is because it is more robust. See the [benchmarks][19].
+
+## Algorithms
+
+To see what algorithms this `bc` uses, see the [algorithms manual][7].
+
+## Locales
+
+Currently, this `bc` only has support for English (and US English), French,
+German, Portuguese, Dutch, Polish, Russian, Japanese, and Chinese locales.
+Patches are welcome for translations; use the existing `*.msg` files in
+`locales/` as a starting point.
+
+In addition, patches for improvements are welcome; the last two messages in
+Portuguese were made with Google Translate, and the Dutch, Polish, Russian,
+Japanese, and Chinese locales were all generated with [DeepL][22].
+
+The message files provided assume that locales apply to all regions where a
+language is used, but this might not be true for, e.g., `fr_CA` and `fr_CH`.
+Any corrections or a confirmation that the current texts are acceptable for
+those regions would be appreciated, too.
+
+## Other Projects
+
+Other projects based on this bc are:
+
+* [busybox `bc`][8]. The busybox maintainers have made their own changes, so any
+ bugs in the busybox `bc` should be reported to them.
+
+* [toybox `bc`][9]. The maintainer has also made his own changes, so bugs in the
+ toybox `bc` should be reported there.
+
+* [FreeBSD `bc`][23]. While the `bc` in FreeBSD is kept up-to-date, it is better
+ to [report bugs there][24], as well as [submit patches][25], and the
+ maintainers of the package will contact me if necessary.
+
+## Language
+
+This `bc` is written in pure ISO C99, using POSIX 2008 APIs.
+
+## Commit Messages
+
+This `bc` uses the commit message guidelines laid out in [this blog post][10].
+
+## Semantic Versioning
+
+This `bc` uses [semantic versioning][11].
+
+## Contents
+
+Items labeled with `(maintainer use only)` are not included in release source
+tarballs.
+
+Files:
+
+ .gitignore The git ignore file (maintainer use only).
+ configure A symlink to configure.sh to make packaging easier.
+ configure.sh The configure script.
+ functions.sh A script with functions used by other scripts.
+ install.sh Install script.
+ karatsuba.py Script to find the optimal Karatsuba number.
+ LICENSE.md A Markdown form of the BSD 2-clause License.
+ link.sh A script to link dc to bc.
+ locale_install.sh A script to install locales, if desired.
+ locale_uninstall.sh A script to uninstall locales.
+ Makefile.in The Makefile template.
+ manpage.sh Script to generate man pages from markdown files.
+ NOTICE.md List of contributors and copyright owners.
+ RELEASE.md A checklist for making a release (maintainer use only).
+ release.sh A script to test for release (maintainer use only).
+ safe-install.sh Safe install script from musl libc.
+
+Folders:
+
+ gen The bc math library, help texts, and code to generate C source.
+ include All header files.
+ locales Locale files, in .msg format. Patches welcome for translations.
+ manuals Manuals for both programs.
+ src All source code.
+ tests All tests.
+
+[1]: https://www.gnu.org/software/bc/
+[4]: ./LICENSE.md
+[5]: ./manuals/build.md
+[6]: https://pkg.musl.cc/bc/
+[7]: ./manuals/algorithms.md
+[8]: https://git.busybox.net/busybox/tree/miscutils/bc.c
+[9]: https://github.com/landley/toybox/blob/master/toys/pending/bc.c
+[10]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+[11]: http://semver.org/
+[12]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[17]: https://img.shields.io/coverity/scan/16609.svg
+[18]: https://scan.coverity.com/projects/gavinhoward-bc
+[19]: ./manuals/benchmarks.md
+[20]: https://git.yzena.com/gavin/bc
+[21]: https://gavinhoward.com/2020/04/i-am-moving-away-from-github/
+[22]: https://www.deepl.com/translator
+[23]: https://svnweb.freebsd.org/base/head/contrib/bc/
+[24]: https://bugs.freebsd.org/
+[25]: https://reviews.freebsd.org/
+[26]: ./manuals/bcl.3.md
diff --git a/contrib/bc/RELEASE.md b/contrib/bc/RELEASE.md
new file mode 100644
index 000000000000..487ef95b051b
--- /dev/null
+++ b/contrib/bc/RELEASE.md
@@ -0,0 +1,54 @@
+# Release Checklist
+
+This is the checklist for cutting a release.
+
+1. Update the README.
+2. Update the manuals.
+3. Test history manually.
+4. Test with POSIX test suite.
+5. Run the randmath.py script an excessive amount and add failing tests to
+ test suite.
+ * debug
+ * release
+ * minrelease
+6. Fuzz with AFL.
+ * reldebug
+7. Fix AFL crashes.
+8. Find ASan crashes on AFL test cases.
+9. Fix ASan crashes.
+10. Build with xstatic.
+11. Run and pass the `release.sh` script on my own machine.
+12. Run and pass the `release.sh` script, without generated tests and
+ sanitizers, on FreeBSD.
+13. Run and pass the `release.sh` script, without generated tests, sanitizers,
+ and 64-bit, on Thalheim's ARM server.
+14. Run and pass the release script, with no generated tests, no clang, no
+ sanitizers, and no valgrind, on NetBSD.
+15. Run and pass the release script, with no generated tests, no clang, no
+ sanitizers, and no valgrind, on OpenBSD.
+16. Run Coverity Scan and eliminate warnings, if possible (both only).
+ * debug
+17. Run `scan-build make`.
+18. Repeat steps 3-14 again and repeat until nothing is found.
+19. Update the benchmarks.
+20. Change the version (remove "-dev") and commit.
+21. Run `make clean_tests`.
+22. Run the release script.
+23. Upload the custom tarball to GitHub.
+24. Add sha's to release notes.
+25. Edit release notes for the changelog.
+26. Increment to the next version (with "-dev").
+27. Notify the following:
+ * FreeBSD
+ * Adelie Linux
+ * Ataraxia Linux
+ * Sabotage
+ * xstatic
+ * OpenBSD
+ * NetBSD
+28. Submit new packages for the following:
+ * Alpine Linux
+ * Void Linux
+ * Gentoo Linux
+ * Linux from Scratch
+ * Arch Linux
diff --git a/contrib/bc/configure b/contrib/bc/configure
new file mode 120000
index 000000000000..bd7a56adb6f9
--- /dev/null
+++ b/contrib/bc/configure
@@ -0,0 +1 @@
+configure.sh \ No newline at end of file
diff --git a/contrib/bc/configure.sh b/contrib/bc/configure.sh
new file mode 100755
index 000000000000..b6caf3debba3
--- /dev/null
+++ b/contrib/bc/configure.sh
@@ -0,0 +1,1098 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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"
+
+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] [-EfgGHlMNPT] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script"
+ printf ' %s \\\n' "$script"
+ printf ' [--library|--bc-only --disable-dc|--dc-only --disable-bc|--coverage]\\\n'
+ printf ' [--force --debug --disable-extra-math --disable-generated-tests] \\\n'
+ printf ' [--disable-history --disable-man-pages --disable-nls] \\\n'
+ printf ' [--disable-prompt --disable-strip] [--install-all-locales] \\\n'
+ printf ' [--opt=OPT_LEVEL] [--karatsuba-len=KARATSUBA_LEN] \\\n'
+ printf ' [--prefix=PREFIX] [--bindir=BINDIR] [--datarootdir=DATAROOTDIR] \\\n'
+ printf ' [--datadir=DATADIR] [--mandir=MANDIR] [--man1dir=MAN1DIR] \\\n'
+ printf '\n'
+ printf ' -a, --library\n'
+ printf ' Build the libbc instead of the programs. This is meant to be used with\n'
+ printf ' Other software like programming languages that want to make use of the\n'
+ printf ' parsing and math capabilities. This option will install headers using\n'
+ printf ' `make install`.\n'
+ printf ' -b, --bc-only\n'
+ printf ' Build bc only. It is an error if "-d", "--dc-only", "-B", or\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 ' -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, --disable-man-pages\n'
+ printf ' Disable installing manpages.\n'
+ printf ' -N, --disable-nls\n'
+ printf ' Disable POSIX locale (NLS) support.\n'
+ printf ' -O OPT_LEVEL, --opt OPT_LEVEL\n'
+ printf ' Set the optimization level. This can also be included in the CFLAGS,\n'
+ printf ' but it is provided, so maintainers can build optimized debug builds.\n'
+ printf ' This is passed through to the compiler, so it must be supported.\n'
+ printf ' -P, --disable-prompt\n'
+ printf ' Disables the prompt in the built bc. The prompt will never show up,\n'
+ printf ' or in other words, it will be permanently disabled and cannot be\n'
+ printf ' enabled.\n'
+ printf ' -T, --disable-strip\n'
+ printf ' Disable stripping symbols from the compiled binary or binaries.\n'
+ printf ' Stripping symbols only happens when debug mode is off.\n'
+ printf ' --prefix PREFIX\n'
+ printf ' The prefix to install to. Overrides "$PREFIX" if it exists.\n'
+ printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n'
+ printf ' Default is "/usr/local".\n'
+ printf ' --bindir BINDIR\n'
+ printf ' The directory to install binaries 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"
+}
+
+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
+
+ while [ "$#" -ge 1 ]; do
+ a="$1"
+ shift
+ args="$args ! -path src/${a}"
+ done
+
+ else
+ args="-print"
+ 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/ -depth -name "*.c" $args | tr '\n' ' ')
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_src" "$_gen_file_list_replacement")
+
+ _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "c" "o")
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_obj" "$_gen_file_list_replacement")
+
+ _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "o" "gcda")
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_gcda" "$_gen_file_list_replacement")
+
+ _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "gcda" "gcno")
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_gcno" "$_gen_file_list_replacement")
+
+ cd "$p"
+
+ printf '%s\n' "$_gen_file_list_contents"
+}
+
+bc_only=0
+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
+
+while getopts "abBcdDEfgGhHk:lMNO:PST-" opt; do
+
+ case "$opt" in
+ a) library=1 ;;
+ b) bc_only=1 ;;
+ B) dc_only=1 ;;
+ c) coverage=1 ;;
+ d) dc_only=1 ;;
+ D) bc_only=1 ;;
+ E) extra_math=0 ;;
+ f) force=1 ;;
+ g) debug=1 ;;
+ G) generate_tests=0 ;;
+ h) usage ;;
+ H) hist=0 ;;
+ k) karatsuba_len="$OPTARG" ;;
+ l) all_locales=1 ;;
+ M) install_manpages=0 ;;
+ N) nls=0 ;;
+ O) optimization="$OPTARG" ;;
+ P) prompt=0 ;;
+ T) strip_bin=0 ;;
+ -)
+ arg="$1"
+ arg="${arg#--}"
+ LONG_OPTARG="${arg#*=}"
+ case $arg in
+ help) usage ;;
+ 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-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 ;;
+ 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-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" ;;
+ 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 [ "$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)"
+bc_time_test="@tests/all.sh bc $extra_math 1 $generate_tests 1 \$(BC_EXEC)"
+
+dc_test="@tests/all.sh dc $extra_math 1 $generate_tests 0 \$(DC_EXEC)"
+dc_time_test="@tests/all.sh dc $extra_math 1 $generate_tests 1 \$(DC_EXEC)"
+
+timeconst="@tests/bc/timeconst.sh tests/bc/scripts/timeconst.bc \$(BC_EXEC)"
+
+# In order to have cleanup at exit, we need to be in
+# debug mode, so don't run valgrind without that.
+if [ "$debug" -ne 0 ]; then
+ vg_bc_test="@tests/all.sh bc $extra_math 1 $generate_tests 0 valgrind \$(VALGRIND_ARGS) \$(BC_EXEC)"
+ vg_dc_test="@tests/all.sh dc $extra_math 1 $generate_tests 0 valgrind \$(VALGRIND_ARGS) \$(DC_EXEC)"
+else
+ vg_bc_test="@printf 'Cannot run valgrind without debug flags\\\\n'"
+ vg_dc_test="@printf 'Cannot run valgrind without debug flags\\\\n'"
+fi
+
+karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
+karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
+
+bc_lib="\$(GEN_DIR)/lib.o"
+bc_help="\$(GEN_DIR)/bc_help.o"
+dc_help="\$(GEN_DIR)/dc_help.o"
+
+if [ "$bc_only" -eq 1 ]; then
+
+ bc=1
+ dc=0
+
+ dc_help=""
+
+ executables="bc"
+
+ dc_test="@printf 'No dc tests to run\\\\n'"
+ dc_time_test="@printf 'No dc tests to run\\\\n'"
+ vg_dc_test="@printf 'No dc tests to run\\\\n'"
+
+ install_prereqs=" install_execs"
+ install_man_prereqs=" install_bc_manpage"
+ uninstall_prereqs=" uninstall_bc"
+ uninstall_man_prereqs=" uninstall_bc_manpage"
+
+elif [ "$dc_only" -eq 1 ]; then
+
+ bc=0
+ dc=1
+
+ bc_lib=""
+ bc_help=""
+
+ executables="dc"
+
+ main_exec="DC"
+ executable="DC_EXEC"
+
+ bc_test="@printf 'No bc tests to run\\\\n'"
+ bc_time_test="@printf 'No bc tests to run\\\\n'"
+ vg_bc_test="@printf 'No bc tests to run\\\\n'"
+
+ timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'"
+
+ install_prereqs=" install_execs"
+ install_man_prereqs=" install_dc_manpage"
+ uninstall_prereqs=" uninstall_dc"
+ uninstall_man_prereqs=" uninstall_dc_manpage"
+
+else
+
+ bc=1
+ dc=1
+
+ executables="bc and dc"
+
+ link="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)"
+
+ karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)"
+ karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)"
+
+ if [ "$library" -eq 0 ]; then
+ install_prereqs=" install_execs"
+ install_man_prereqs=" install_bc_manpage install_dc_manpage"
+ uninstall_prereqs=" uninstall_bc uninstall_dc"
+ uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
+ else
+ install_prereqs=" install_library install_bcl_header"
+ install_man_prereqs=" install_bcl_manpage"
+ uninstall_prereqs=" uninstall_library uninstall_bcl_header"
+ uninstall_man_prereqs=" uninstall_bcl_manpage"
+ tests="test_library"
+ fi
+
+fi
+
+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 [ "$library" -ne 0 ]; then
+ extra_math=1
+ nls=0
+ hist=0
+ prompt=0
+ ALL_PREREQ="library"
+else
+ ALL_PREREQ="execs"
+fi
+
+if [ "$nls" -ne 0 ]; then
+
+ set +e
+
+ 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=""
+
+if [ "$extra_math" -eq 0 ]; then
+ manpage_args="E"
+fi
+
+if [ "$hist" -eq 0 ]; then
+ manpage_args="${manpage_args}H"
+fi
+
+if [ "$nls" -eq 0 ]; then
+ manpage_args="${manpage_args}N"
+fi
+
+if [ "$prompt" -eq 0 ]; then
+ manpage_args="${manpage_args}P"
+fi
+
+if [ "$manpage_args" = "" ]; then
+ manpage_args="A"
+fi
+
+unneeded=""
+
+if [ "$hist" -eq 0 ]; then
+ unneeded="$unneeded history.c"
+fi
+
+if [ "$bc" -eq 0 ]; then
+ unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
+fi
+
+if [ "$dc" -eq 0 ]; then
+ unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
+fi
+
+if [ "$extra_math" -eq 0 ]; then
+ unneeded="$unneeded rand.c"
+fi
+
+if [ "$library" -ne 0 ]; then
+ unneeded="$unneeded args.c opt.c read.c file.c main.c"
+ unneeded="$unneeded lang.c lex.c parse.c program.c"
+ unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
+ unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
+else
+ unneeded="$unneeded library.c"
+fi
+
+# Print out the values; this is for debugging.
+if [ "$bc" -ne 0 ]; then
+ printf 'Building bc\n'
+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 '\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
+ contents=$(gen_file_list "$contents" "library.c")
+else
+ contents=$(gen_file_list "$contents" $unneeded)
+fi
+
+contents=$(replace "$contents" "BC_ENABLED" "$bc")
+contents=$(replace "$contents" "DC_ENABLED" "$dc")
+contents=$(replace "$contents" "LINK" "$link")
+
+contents=$(replace "$contents" "LIBRARY" "$library")
+contents=$(replace "$contents" "HISTORY" "$hist")
+contents=$(replace "$contents" "EXTRA_MATH" "$extra_math")
+contents=$(replace "$contents" "NLS" "$nls")
+contents=$(replace "$contents" "PROMPT" "$prompt")
+contents=$(replace "$contents" "BC_LIB_O" "$bc_lib")
+contents=$(replace "$contents" "BC_HELP_O" "$bc_help")
+contents=$(replace "$contents" "DC_HELP_O" "$dc_help")
+contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O")
+contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len")
+
+contents=$(replace "$contents" "NLSPATH" "$NLSPATH")
+contents=$(replace "$contents" "DESTDIR" "$destdir")
+contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX")
+contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX")
+contents=$(replace "$contents" "BINDIR" "$BINDIR")
+contents=$(replace "$contents" "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" "ALL_PREREQ" "$ALL_PREREQ")
+
+contents=$(replace "$contents" "EXECUTABLES" "$executables")
+contents=$(replace "$contents" "MAIN_EXEC" "$main_exec")
+contents=$(replace "$contents" "EXEC" "$executable")
+contents=$(replace "$contents" "TESTS" "$tests")
+
+contents=$(replace "$contents" "BC_TEST" "$bc_test")
+contents=$(replace "$contents" "BC_TIME_TEST" "$bc_time_test")
+
+contents=$(replace "$contents" "DC_TEST" "$dc_test")
+contents=$(replace "$contents" "DC_TIME_TEST" "$dc_time_test")
+
+contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test")
+contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test")
+
+contents=$(replace "$contents" "TIMECONST" "$timeconst")
+
+contents=$(replace "$contents" "KARATSUBA" "$karatsuba")
+contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test")
+
+contents=$(replace "$contents" "LONG_BIT" "$LONG_BIT")
+contents=$(replace "$contents" "LONG_BIT_DEFINE" "$LONG_BIT_DEFINE")
+
+contents=$(replace "$contents" "GEN" "$GEN")
+contents=$(replace "$contents" "GEN_EXEC_TARGET" "$GEN_EXEC_TARGET")
+contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS")
+contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU")
+
+printf '%s\n' "$contents" > "$scriptdir/Makefile"
+
+cd "$scriptdir"
+
+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/contrib/bc/exec-install.sh b/contrib/bc/exec-install.sh
new file mode 100755
index 000000000000..6d1600330ba9
--- /dev/null
+++ b/contrib/bc/exec-install.sh
@@ -0,0 +1,63 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+usage() {
+ printf "usage: %s install_dir exec_suffix\n" "$0" 1>&2
+ exit 1
+}
+
+script="$0"
+scriptdir=$(dirname "$script")
+
+. "$scriptdir/functions.sh"
+
+INSTALL="$scriptdir/safe-install.sh"
+
+test "$#" -ge 2 || usage
+
+installdir="$1"
+shift
+
+exec_suffix="$1"
+shift
+
+bindir="$scriptdir/bin"
+
+for exe in $bindir/*; do
+
+ base=$(basename "$exe")
+
+ if [ -L "$exe" ]; then
+ link=$(readlink "$exe")
+ "$INSTALL" -Dlm 755 "$link$exec_suffix" "$installdir/$base$exec_suffix"
+ else
+ "$INSTALL" -Dm 755 "$exe" "$installdir/$base$exec_suffix"
+ fi
+
+done
diff --git a/contrib/bc/functions.sh b/contrib/bc/functions.sh
new file mode 100755
index 000000000000..96afb059c951
--- /dev/null
+++ b/contrib/bc/functions.sh
@@ -0,0 +1,218 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+readlink() {
+
+ _readlink_f="$1"
+ shift
+
+ _readlink_arrow="-> "
+ _readlink_d=$(dirname "$_readlink_f")
+
+ _readlink_lsout=""
+ _readlink_link=""
+
+ _readlink_lsout=$(ls -dl "$_readlink_f")
+ _readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}")
+
+ while [ -z "${_readlink_lsout##*$_readlink_arrow*}" ]; do
+ _readlink_f="$_readlink_d/$_readlink_link"
+ _readlink_d=$(dirname "$_readlink_f")
+ _readlink_lsout=$(ls -dl "$_readlink_f")
+ _readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}")
+ done
+
+ printf '%s' "${_readlink_f##*$_readlink_d/}"
+}
+
+err_exit() {
+
+ if [ "$#" -ne 2 ]; then
+ printf 'Invalid number of args to err_exit\n'
+ exit 1
+ fi
+
+ printf '%s\n' "$1"
+ printf '\nexiting...\n'
+ exit "$2"
+}
+
+die() {
+
+ _die_d="$1"
+ shift
+
+ _die_msg="$1"
+ shift
+
+ _die_name="$1"
+ shift
+
+ _die_err="$1"
+ shift
+
+ _die_str=$(printf '\n%s %s on test:\n\n %s\n' "$_die_d" "$_die_msg" "$_die_name")
+
+ err_exit "$_die_str" "$_die_err"
+}
+
+checkcrash() {
+
+ _checkcrash_d="$1"
+ shift
+
+ _checkcrash_error="$1"
+ shift
+
+ _checkcrash_name="$1"
+ shift
+
+ if [ "$_checkcrash_error" -gt 127 ]; then
+ die "$_checkcrash_d" "crashed ($_checkcrash_error)" \
+ "$_checkcrash_name" "$_checkcrash_error"
+ fi
+}
+
+checktest()
+{
+ _checktest_d="$1"
+ shift
+
+ _checktest_error="$1"
+ shift
+
+ _checktest_name="$1"
+ shift
+
+ _checktest_out="$1"
+ shift
+
+ _checktest_exebase="$1"
+ shift
+
+ checkcrash "$_checktest_d" "$_checktest_error" "$_checktest_name"
+
+ if [ "$_checktest_error" -eq 0 ]; then
+ die "$_checktest_d" "returned no error" "$_checktest_name" 127
+ fi
+
+ if [ "$_checktest_error" -eq 100 ]; then
+
+ _checktest_output=$(cat "$_checktest_out")
+ _checktest_fatal_error="Fatal error"
+
+ if [ "${_checktest_output##*$_checktest_fatal_error*}" ]; then
+ printf "%s\n" "$_checktest_output"
+ die "$_checktest_d" "had memory errors on a non-fatal error" \
+ "$_checktest_name" "$_checktest_error"
+ fi
+ fi
+
+ if [ ! -s "$_checktest_out" ]; then
+ die "$_checktest_d" "produced no error message" "$_checktest_name" "$_checktest_error"
+ fi
+
+ # Display the error messages if not directly running exe.
+ # This allows the script to print valgrind output.
+ if [ "$_checktest_exebase" != "bc" -a "$_checktest_exebase" != "dc" ]; then
+ cat "$_checktest_out"
+ fi
+}
+
+substring_replace() {
+
+ _substring_replace_str="$1"
+ shift
+
+ _substring_replace_needle="$1"
+ shift
+
+ _substring_replace_replacement="$1"
+ shift
+
+ _substring_replace_result=$(printf '%s\n' "$_substring_replace_str" | \
+ sed -e "s!$_substring_replace_needle!$_substring_replace_replacement!g")
+
+ printf '%s' "$_substring_replace_result"
+}
+
+gen_nlspath() {
+
+ _gen_nlspath_nlspath="$1"
+ shift
+
+ _gen_nlspath_locale="$1"
+ shift
+
+ _gen_nlspath_execname="$1"
+ shift
+
+ _gen_nlspath_char="@"
+ _gen_nlspath_modifier="${_gen_nlspath_locale#*$_gen_nlspath_char}"
+ _gen_nlspath_tmplocale="${_gen_nlspath_locale%%$_gen_nlspath_char*}"
+
+ _gen_nlspath_char="."
+ _gen_nlspath_charset="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}"
+ _gen_nlspath_tmplocale="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}"
+
+ if [ "$_gen_nlspath_charset" = "$_gen_nlspath_tmplocale" ]; then
+ _gen_nlspath_charset=""
+ fi
+
+ _gen_nlspath_char="_"
+ _gen_nlspath_territory="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}"
+ _gen_nlspath_language="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}"
+
+ if [ "$_gen_nlspath_territory" = "$_gen_nlspath_tmplocale" ]; then
+ _gen_nlspath_territory=""
+ fi
+
+ if [ "$_gen_nlspath_language" = "$_gen_nlspath_tmplocale" ]; then
+ _gen_nlspath_language=""
+ fi
+
+ _gen_nlspath_needles="%%:%L:%N:%l:%t:%c"
+
+ _gen_nlspath_needles=$(printf '%s' "$_gen_nlspath_needles" | tr ':' '\n')
+
+ for _gen_nlspath_i in $_gen_nlspath_needles; do
+ _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "$_gen_nlspath_i" "|$_gen_nlspath_i|")
+ done
+
+ _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%%" "%")
+ _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%L" "$_gen_nlspath_locale")
+ _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%N" "$_gen_nlspath_execname")
+ _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%l" "$_gen_nlspath_language")
+ _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%t" "$_gen_nlspath_territory")
+ _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%c" "$_gen_nlspath_charset")
+
+ _gen_nlspath_nlspath=$(printf '%s' "$_gen_nlspath_nlspath" | tr -d '|')
+
+ printf '%s' "$_gen_nlspath_nlspath"
+}
diff --git a/contrib/bc/gen/bc_help.txt b/contrib/bc/gen/bc_help.txt
new file mode 100644
index 000000000000..e013251b16bb
--- /dev/null
+++ b/contrib/bc/gen/bc_help.txt
@@ -0,0 +1,120 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The bc help text.
+ *
+ */
+
+usage: %s [options] [file...]
+
+bc is a command-line, arbitrary-precision calculator with a Turing-complete
+language. For details, use `man %s`.
+
+This bc is compatible with both the GNU bc and the POSIX bc spec. See the GNU bc
+manual (https://www.gnu.org/software/bc/manual/bc.html) and bc spec
+(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+for details.
+
+This bc has three differences to the GNU bc:
+
+ 1) Arrays can be passed to the builtin "length" function to get the number of
+ elements currently in the array. The following example prints "1":
+
+ a[0] = 0
+ length(a[])
+
+ 2) The precedence of the boolean "not" operator (!) is equal to that of the
+ unary minus (-), or negation, operator. This still allows POSIX-compliant
+ scripts to work while somewhat preserving expected behavior (versus C) and
+ making parsing easier.
+ 3) This bc has many more extensions than the GNU bc does. For details, see the
+ man page.
+
+This bc also implements the dot (.) extension of the BSD bc.
+
+Options:
+
+ -e expr --expression=expr
+
+ Run "expr" and quit. If multiple expressions or files (see below) are
+ given, they are all run before executing from stdin.
+
+ -f file --file=file
+
+ Run the bc code in "file" and exit. See above as well.
+
+ -g --global-stacks
+
+ Turn scale, ibase, and obase into stacks. This makes the value of each be
+ be restored on returning from functions. See the man page for more
+ details.
+
+ -h --help
+
+ Print this usage message and exit.
+
+ -i --interactive
+
+ Force interactive mode.
+
+ -l --mathlib
+
+ Use predefined math routines:
+
+ s(expr) = sine of expr in radians
+ c(expr) = cosine of expr in radians
+ a(expr) = arctangent of expr, returning radians
+ l(expr) = natural log of expr
+ e(expr) = raises e to the power of expr
+ j(n, x) = Bessel function of integer order n of x
+
+ This bc may load more functions with these options. See the manpage for
+ details.
+
+ -P --no-prompt
+
+ Disable the prompt in interactive mode.
+
+ -q --quiet
+
+ Don't print version and copyright.
+
+ -s --standard
+
+ Error if any non-POSIX extensions are used.
+
+ -w --warn
+
+ Warn if any non-POSIX extensions are used.
+
+ -v --version
+
+ Print version information and copyright and exit.
diff --git a/contrib/bc/gen/dc_help.txt b/contrib/bc/gen/dc_help.txt
new file mode 100644
index 000000000000..6a26ece26488
--- /dev/null
+++ b/contrib/bc/gen/dc_help.txt
@@ -0,0 +1,101 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The dc help text.
+ *
+ */
+
+usage: %s [options] [file...]
+
+dc is a reverse-polish notation command-line calculator which supports unlimited
+precision arithmetic. For details, use `man %s`.
+
+This dc is (mostly) compatible with the FreeBSD dc and the GNU dc. See the
+FreeBSD man page (https://www.unix.com/man-page/FreeBSD/1/dc/) and the GNU dc
+manual (https://www.gnu.org/software/bc/manual/dc-1.05/html_mono/dc.html) for
+details.
+
+This dc has a few differences from the two above:
+
+ 1) When printing a byte stream (command "P"), this bc follows what the FreeBSD
+ dc does.
+ 2) This dc implements the GNU extensions for divmod ("~") and modular
+ exponentiation ("|").
+ 3) This dc implements all FreeBSD extensions, except for "J" and "M".
+ 4) This dc does not implement the run command ("!"), for security reasons.
+ 5) Like the FreeBSD dc, this dc supports extended registers. However, they are
+ implemented differently. When it encounters whitespace where a register
+ should be, it skips the whitespace. If the character following is not
+ a lowercase letter, an error is issued. Otherwise, the register name is
+ parsed by the following regex:
+
+ [a-z][a-z0-9_]*
+
+ This generally means that register names will be surrounded by whitespace.
+
+ Examples:
+
+ l idx s temp L index S temp2 < do_thing
+
+ Also note that, unlike the FreeBSD dc, extended registers are not even
+ parsed unless the "-x" option is given. Instead, the space after a command
+ that requires a register name is taken as the register name.
+
+Options:
+
+ -e expr --expression=expr
+
+ Run "expr" and quit. If multiple expressions or files (see below) are
+ given, they are all run. After running, dc will exit.
+
+ -f file --file=file
+
+ Run the dc code in "file" and exit. See above.
+
+ -h --help
+
+ Print this usage message and exit.
+
+ -i --interactive
+
+ Put dc into interactive mode. See the man page for more details.
+
+ -P --no-prompt
+
+ Disable the prompt in interactive mode.
+
+ -V --version
+
+ Print version and copyright and exit.
+
+ -x --extended-register
+
+ Enable extended register mode.
diff --git a/contrib/bc/gen/lib.bc b/contrib/bc/gen/lib.bc
new file mode 100644
index 000000000000..7768eb74bad1
--- /dev/null
+++ b/contrib/bc/gen/lib.bc
@@ -0,0 +1,201 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The bc math library.
+ *
+ */
+
+scale=20
+define e(x){
+ auto b,s,n,r,d,i,p,f,v
+ b=ibase
+ ibase=A
+ if(x<0){
+ n=1
+ x=-x
+ }
+ s=scale
+ r=6+s+.44*x
+ scale=scale(x)+1
+ while(x>1){
+ d+=1
+ x/=2
+ scale+=1
+ }
+ scale=r
+ r=x+1
+ p=x
+ f=v=1
+ for(i=2;v;++i){
+ p*=x
+ f*=i
+ v=p/f
+ r+=v
+ }
+ while(d--)r*=r
+ scale=s
+ ibase=b
+ if(n)return(1/r)
+ return(r/1)
+}
+define l(x){
+ auto b,s,r,p,a,q,i,v
+ if(x<=0)return((1-A^scale)/1)
+ b=ibase
+ ibase=A
+ s=scale
+ scale+=6
+ p=2
+ while(x>=2){
+ p*=2
+ x=sqrt(x)
+ }
+ while(x<=.5){
+ p*=2
+ x=sqrt(x)
+ }
+ r=a=(x-1)/(x+1)
+ q=a*a
+ v=1
+ for(i=3;v;i+=2){
+ a*=q
+ v=a/i
+ r+=v
+ }
+ r*=p
+ scale=s
+ ibase=b
+ return(r/1)
+}
+define s(x){
+ auto b,s,r,a,q,i
+ if(x<0)return(-s(-x))
+ b=ibase
+ ibase=A
+ s=scale
+ scale=1.1*s+2
+ a=a(1)
+ scale=0
+ q=(x/a+2)/4
+ x-=4*q*a
+ if(q%2)x=-x
+ scale=s+2
+ r=a=x
+ q=-x*x
+ for(i=3;a;i+=2){
+ a*=q/(i*(i-1))
+ r+=a
+ }
+ scale=s
+ ibase=b
+ return(r/1)
+}
+define c(x){
+ auto b,s
+ b=ibase
+ ibase=A
+ s=scale
+ scale*=1.2
+ x=s(2*a(1)+x)
+ scale=s
+ ibase=b
+ return(x/1)
+}
+define a(x){
+ auto b,s,r,n,a,m,t,f,i,u
+ b=ibase
+ ibase=A
+ n=1
+ if(x<0){
+ n=-1
+ x=-x
+ }
+ if(scale<65){
+ if(x==1){
+ r=.7853981633974483096156608458198757210492923498437764552437361480/n
+ ibase=b
+ return(r)
+ }
+ if(x==.2){
+ r=.1973955598498807583700497651947902934475851037878521015176889402/n
+ ibase=b
+ return(r)
+ }
+ }
+ s=scale
+ if(x>.2){
+ scale+=5
+ a=a(.2)
+ }
+ scale=s+3
+ while(x>.2){
+ m+=1
+ x=(x-.2)/(1+.2*x)
+ }
+ r=u=x
+ f=-x*x
+ t=1
+ for(i=3;t;i+=2){
+ u*=f
+ t=u/i
+ r+=t
+ }
+ scale=s
+ ibase=b
+ return((m*a+r)/n)
+}
+define j(n,x){
+ auto b,s,o,a,i,r,v,f
+ b=ibase
+ ibase=A
+ s=scale
+ scale=0
+ n/=1
+ if(n<0){
+ n=-n
+ o=n%2
+ }
+ a=1
+ for(i=2;i<=n;++i)a*=i
+ scale=1.5*s
+ a=(x^n)/2^n/a
+ r=v=1
+ f=-x*x/4
+ scale+=length(a)-scale(a)
+ for(i=1;v;++i){
+ v=v*f/i/(n+i)
+ r+=v
+ }
+ scale=s
+ ibase=b
+ if(o)a=-a
+ return(a*r/1)
+}
diff --git a/contrib/bc/gen/lib2.bc b/contrib/bc/gen/lib2.bc
new file mode 100644
index 000000000000..98baffdd30f6
--- /dev/null
+++ b/contrib/bc/gen/lib2.bc
@@ -0,0 +1,317 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The second bc math library.
+ *
+ */
+
+define p(x,y){
+ auto a
+ a=y$
+ if(y==a)return (x^a)@scale
+ return e(y*l(x))
+}
+define r(x,p){
+ auto t,n
+ if(x==0)return x
+ p=abs(p)$
+ n=(x<0)
+ x=abs(x)
+ t=x@p
+ if(p<scale(x)&&x-t>=5>>p+1)t+=1>>p
+ if(n)t=-t
+ return t
+}
+define ceil(x,p){
+ auto t,n
+ if(x==0)return x
+ p=abs(p)$
+ n=(x<0)
+ x=abs(x)
+ t=(x+((x@p<x)>>p))@p
+ if(n)t=-t
+ return t
+}
+define f(n){
+ auto r
+ n=abs(n)$
+ for(r=1;n>1;--n)r*=n
+ return r
+}
+define perm(n,k){
+ auto f,g,s
+ if(k>n)return 0
+ n=abs(n)$
+ k=abs(k)$
+ f=f(n)
+ g=f(n-k)
+ s=scale
+ scale=0
+ f/=g
+ scale=s
+ return f
+}
+define comb(n,r){
+ auto s,f,g,h
+ if(r>n)return 0
+ n=abs(n)$
+ r=abs(r)$
+ s=scale
+ scale=0
+ f=f(n)
+ h=f(r)
+ g=f(n-r)
+ f/=h*g
+ scale=s
+ return f
+}
+define log(x,b){
+ auto p,s
+ s=scale
+ if(scale<K)scale=K
+ if(scale(x)>scale)scale=scale(x)
+ scale*=2
+ p=l(x)/l(b)
+ scale=s
+ return p@s
+}
+define l2(x){return log(x,2)}
+define l10(x){return log(x,A)}
+define root(x,n){
+ auto s,m,r,q,p
+ if(n<0)sqrt(n)
+ n=n$
+ if(n==0)x/n
+ if(n==1)return x
+ if(n==2)return sqrt(x)
+ s=scale
+ scale=0
+ if(x<0&&n%2==0)sqrt(x)
+ scale=s+2
+ m=(x<0)
+ x=abs(x)
+ p=n-1
+ q=10^ceil((length(x$)/n)$,0)
+ while(r!=q){
+ r=q
+ q=(p*r+x/r^p)/n
+ }
+ if(m)r=-r
+ scale=s
+ return r@s
+}
+define cbrt(x){return root(x,3)}
+define pi(s){
+ auto t,v
+ if(s==0)return 3
+ s=abs(s)$
+ t=scale
+ scale=s+1
+ v=4*a(1)
+ scale=t
+ return v@s
+}
+define t(x){
+ auto s,c,l
+ l=scale
+ scale+=2
+ s=s(x)
+ c=c(x)
+ scale=l
+ return s/c
+}
+define a2(y,x){
+ auto a,p
+ if(!x&&!y)y/x
+ if(x<=0){
+ p=pi(scale+2)
+ if(y<0)p=-p
+ }
+ if(x==0)a=p/2
+ else{
+ scale+=2
+ a=a(y/x)+p
+ scale-=2
+ }
+ return a@scale
+}
+define sin(x){return s(x)}
+define cos(x){return c(x)}
+define atan(x){return a(x)}
+define tan(x){return t(x)}
+define atan2(y,x){return a2(y,x)}
+define r2d(x){
+ auto r,i,s
+ s=scale
+ scale+=5
+ i=ibase
+ ibase=A
+ r=x*180/pi(scale)
+ ibase=i
+ scale=s
+ return r@s
+}
+define d2r(x){
+ auto r,i,s
+ s=scale
+ scale+=5
+ i=ibase
+ ibase=A
+ r=x*pi(scale)/180
+ ibase=i
+ scale=s
+ return r@s
+}
+define frand(p){
+ p=abs(p)$
+ return irand(10^p)>>p
+}
+define ifrand(i,p){return irand(abs(i)$)+frand(p)}
+define srand(x){
+ if(irand(2))return -x
+ return x
+}
+define brand(){return irand(2)}
+define void output(x,b){
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+}
+define void hex(x){output(x,G)}
+define void binary(x){output(x,2)}
+define ubytes(x){
+ auto p,b,i
+ b=ibase
+ ibase=A
+ x=abs(x)$
+ i=2^8
+ for(p=1;i-1<x;p*=2){i*=i}
+ ibase=b
+ return p
+}
+define sbytes(x){
+ auto p,b,n,z
+ z=(x<0)
+ x=abs(x)
+ x=x$
+ n=ubytes(x)
+ b=ibase
+ ibase=A
+ p=2^(n*8-1)
+ if(x>p||(!z&&x==p))n*=2
+ ibase=b
+ return n
+}
+define void output_byte(x,i){
+ auto j,p,y,b
+ j=ibase
+ ibase=A
+ s=scale
+ scale=0
+ x=abs(x)$
+ b=x/(2^(i*8))
+ b%=2^8
+ y=log(256,obase)
+ if(b>1)p=log(b,obase)+1
+ else p=b
+ for(i=y-p;i>0;--i)print 0
+ if(b)print b
+ scale=s
+ ibase=j
+}
+define void output_uint(x,n){
+ auto i,b
+ b=ibase
+ ibase=A
+ for(i=n-1;i>=0;--i){
+ output_byte(x,i)
+ if(i)print" "
+ else print"\n"
+ }
+ ibase=b
+}
+define void hex_uint(x,n){
+ auto o
+ o=obase
+ obase=G
+ output_uint(x,n)
+ obase=o
+}
+define void binary_uint(x,n){
+ auto o
+ o=obase
+ obase=2
+ output_uint(x,n)
+ obase=o
+}
+define void uintn(x,n){
+ if(scale(x)){
+ print"Error: ",x," is not an integer.\n"
+ return
+ }
+ if(x<0){
+ print"Error: ",x," is negative.\n"
+ return
+ }
+ if(x>=2^(n*8)){
+ print"Error: ",x," cannot fit into ",n," unsigned byte(s).\n"
+ return
+ }
+ binary_uint(x,n)
+ hex_uint(x,n)
+}
+define void intn(x,n){
+ auto t
+ if(scale(x)){
+ print"Error: ",x," is not an integer.\n"
+ return
+ }
+ t=2^(n*8-1)
+ if(abs(x)>=t&&(x>0||x!=-t)){
+ print "Error: ",x," cannot fit into ",n," signed byte(s).\n"
+ return
+ }
+ if(x<0)x=2^(n*8)-(-x)
+ binary_uint(x,n)
+ hex_uint(x,n)
+}
+define void uint8(x){uintn(x,1)}
+define void int8(x){intn(x,1)}
+define void uint16(x){uintn(x,2)}
+define void int16(x){intn(x,2)}
+define void uint32(x){uintn(x,4)}
+define void int32(x){intn(x,4)}
+define void uint64(x){uintn(x,8)}
+define void int64(x){intn(x,8)}
+define void uint(x){uintn(x,ubytes(x))}
+define void int(x){intn(x,sbytes(x))}
diff --git a/contrib/bc/gen/strgen.c b/contrib/bc/gen/strgen.c
new file mode 100644
index 000000000000..0b2306152874
--- /dev/null
+++ b/contrib/bc/gen/strgen.c
@@ -0,0 +1,144 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Generates a const array from a bc script.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <errno.h>
+
+#include <libgen.h>
+
+static const char* const bc_gen_header =
+ "// Copyright (c) 2018-2020 Gavin D. Howard and contributors.\n"
+ "// Licensed under the 2-clause BSD license.\n"
+ "// *** AUTOMATICALLY GENERATED FROM %s. DO NOT MODIFY. ***\n\n";
+
+static const char* const bc_gen_label = "const char *%s = \"%s\";\n\n";
+static const char* const bc_gen_label_extern = "extern const char *%s;\n\n";
+static const char* const bc_gen_ifdef = "#if %s\n";
+static const char* const bc_gen_endif = "#endif // %s\n";
+static const char* const bc_gen_name = "const char %s[] = {\n";
+static const char* const bc_gen_name_extern = "extern const char %s[];\n\n";
+
+#define IO_ERR (1)
+#define INVALID_INPUT_FILE (2)
+#define INVALID_PARAMS (3)
+
+#define MAX_WIDTH (74)
+
+int main(int argc, char *argv[]) {
+
+ FILE *in, *out;
+ char *label, *define, *name;
+ int c, count, slashes, err = IO_ERR;
+ bool has_label, has_define, remove_tabs;
+
+ if (argc < 5) {
+ printf("usage: %s input output name header [label [define [remove_tabs]]]\n", argv[0]);
+ return INVALID_PARAMS;
+ }
+
+ name = argv[3];
+
+ has_label = (argc > 4 && strcmp("", argv[4]) != 0);
+ label = has_label ? argv[4] : "";
+
+ has_define = (argc > 5 && strcmp("", argv[5]) != 0);
+ define = has_define ? argv[5] : "";
+
+ remove_tabs = (argc > 6);
+
+ in = fopen(argv[1], "r");
+ if (!in) return INVALID_INPUT_FILE;
+
+ out = fopen(argv[2], "w");
+ if (!out) goto out_err;
+
+ if (fprintf(out, bc_gen_header, argv[1]) < 0) goto err;
+ if (has_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 (fprintf(out, bc_gen_name, name) < 0) goto err;
+
+ c = count = slashes = 0;
+
+ while (slashes < 2 && (c = fgetc(in)) >= 0) {
+ slashes += (slashes == 1 && c == '/' && fgetc(in) == '\n');
+ slashes += (!slashes && c == '/' && fgetc(in) == '*');
+ }
+
+ if (c < 0) {
+ err = INVALID_INPUT_FILE;
+ goto err;
+ }
+
+ while ((c = fgetc(in)) == '\n');
+
+ while (c >= 0) {
+
+ int val;
+
+ if (!remove_tabs || c != '\t') {
+
+ if (!count && fputc('\t', out) == EOF) goto err;
+
+ val = fprintf(out, "%d,", c);
+ if (val < 0) goto err;
+
+ count += val;
+
+ if (count > MAX_WIDTH) {
+ count = 0;
+ if (fputc('\n', out) == EOF) goto err;
+ }
+ }
+
+ c = fgetc(in);
+ }
+
+ if (!count && (fputc(' ', out) == EOF || fputc(' ', out) == EOF)) goto err;
+ if (fprintf(out, "0\n};\n") < 0) goto err;
+
+ err = (has_define && fprintf(out, bc_gen_endif, define) < 0);
+
+err:
+ fclose(out);
+out_err:
+ fclose(in);
+ return err;
+}
diff --git a/contrib/bc/gen/strgen.sh b/contrib/bc/gen/strgen.sh
new file mode 100755
index 000000000000..27edf9a1355d
--- /dev/null
+++ b/contrib/bc/gen/strgen.sh
@@ -0,0 +1,82 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+export LANG=C
+export LC_CTYPE=C
+
+progname=${0##*/}
+
+if [ $# -lt 3 ]; then
+ echo "usage: $progname input output name [label [define [remove_tabs]]]"
+ exit 1
+fi
+
+input="$1"
+output="$2"
+name="$3"
+label="$4"
+define="$5"
+remove_tabs="$6"
+
+exec < "$input"
+exec > "$output"
+
+if [ -n "$label" ]; then
+ nameline="const char *${label} = \"${input}\";"
+ labelexternline="extern const char *${label};"
+fi
+
+if [ -n "$define" ]; then
+ condstart="#if ${define}"
+ condend="#endif"
+fi
+
+if [ -n "$remove_tabs" ]; then
+ if [ "$remove_tabs" -ne 0 ]; then
+ remtabsexpr='s: ::g;'
+ fi
+fi
+
+cat<<EOF
+// Copyright (c) 2018-2020 Gavin D. Howard and contributors.
+// Licensed under the 2-clause BSD license.
+// *** AUTOMATICALLY GENERATED FROM ${input}. DO NOT MODIFY. ***
+
+${condstart}
+$labelexternline
+
+extern const char $name[];
+
+$nameline
+
+const char ${name}[] =
+$(sed -e "$remtabsexpr " -e '1,/^$/d; s:\\n:\\\\n:g; s:":\\":g; s:^:":; s:$:\\n":')
+;
+${condend}
+EOF
diff --git a/contrib/bc/include/args.h b/contrib/bc/include/args.h
new file mode 100644
index 000000000000..f2bc2d6bab05
--- /dev/null
+++ b/contrib/bc/include/args.h
@@ -0,0 +1,46 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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_ARGS_H
+#define BC_ARGS_H
+
+#include <status.h>
+#include <vm.h>
+
+void bc_args(int argc, char *argv[]);
+
+extern const char* const bc_args_env_name;
+
+#endif // BC_ARGS_H
diff --git a/contrib/bc/include/bc.h b/contrib/bc/include/bc.h
new file mode 100644
index 000000000000..383e7e7ec562
--- /dev/null
+++ b/contrib/bc/include/bc.h
@@ -0,0 +1,182 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 bc.
+ *
+ */
+
+#ifndef BC_BC_H
+#define BC_BC_H
+
+#if BC_ENABLED
+
+#include <limits.h>
+#include <stdbool.h>
+
+#include <status.h>
+#include <lex.h>
+#include <parse.h>
+
+void bc_main(int argc, char **argv);
+
+extern const char bc_help[];
+extern const char bc_lib[];
+extern const char* bc_lib_name;
+
+#if BC_ENABLE_EXTRA_MATH
+extern const char bc_lib2[];
+extern const char* bc_lib2_name;
+#endif // BC_ENABLE_EXTRA_MATH
+
+typedef struct BcLexKeyword {
+ uchar data;
+ const char name[9];
+} BcLexKeyword;
+
+#define BC_LEX_CHAR_MSB(bit) ((bit) << (CHAR_BIT - 1))
+
+#define BC_LEX_KW_POSIX(kw) ((kw)->data & (BC_LEX_CHAR_MSB(1)))
+#define BC_LEX_KW_LEN(kw) ((size_t) ((kw)->data & ~(BC_LEX_CHAR_MSB(1))))
+
+#define BC_LEX_KW_ENTRY(a, b, c) \
+ { .data = ((b) & ~(BC_LEX_CHAR_MSB(1))) | BC_LEX_CHAR_MSB(c), .name = a }
+
+extern const BcLexKeyword bc_lex_kws[];
+extern const size_t bc_lex_kws_len;
+
+void bc_lex_token(BcLex *l);
+
+#define BC_PARSE_TOP_FLAG_PTR(p) ((uint16_t*) bc_vec_top(&(p)->flags))
+#define BC_PARSE_TOP_FLAG(p) (*(BC_PARSE_TOP_FLAG_PTR(p)))
+
+#define BC_PARSE_FLAG_BRACE (UINTMAX_C(1)<<0)
+#define BC_PARSE_BRACE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BRACE)
+
+#define BC_PARSE_FLAG_FUNC_INNER (UINTMAX_C(1)<<1)
+#define BC_PARSE_FUNC_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC_INNER)
+
+#define BC_PARSE_FLAG_FUNC (UINTMAX_C(1)<<2)
+#define BC_PARSE_FUNC(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC)
+
+#define BC_PARSE_FLAG_BODY (UINTMAX_C(1)<<3)
+#define BC_PARSE_BODY(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BODY)
+
+#define BC_PARSE_FLAG_LOOP (UINTMAX_C(1)<<4)
+#define BC_PARSE_LOOP(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP)
+
+#define BC_PARSE_FLAG_LOOP_INNER (UINTMAX_C(1)<<5)
+#define BC_PARSE_LOOP_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP_INNER)
+
+#define BC_PARSE_FLAG_IF (UINTMAX_C(1)<<6)
+#define BC_PARSE_IF(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF)
+
+#define BC_PARSE_FLAG_ELSE (UINTMAX_C(1)<<7)
+#define BC_PARSE_ELSE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_ELSE)
+
+#define BC_PARSE_FLAG_IF_END (UINTMAX_C(1)<<8)
+#define BC_PARSE_IF_END(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF_END)
+
+#define BC_PARSE_NO_EXEC(p) ((p)->flags.len != 1 || BC_PARSE_TOP_FLAG(p) != 0)
+
+#define BC_PARSE_DELIMITER(t) \
+ ((t) == BC_LEX_SCOLON || (t) == BC_LEX_NLINE || (t) == BC_LEX_EOF)
+
+#define BC_PARSE_BLOCK_STMT(f) \
+ ((f) & (BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_LOOP_INNER))
+
+#define BC_PARSE_OP(p, l) (((p) & ~(BC_LEX_CHAR_MSB(1))) | (BC_LEX_CHAR_MSB(l)))
+
+#define BC_PARSE_OP_DATA(t) bc_parse_ops[((t) - BC_LEX_OP_INC)]
+#define BC_PARSE_OP_LEFT(op) (BC_PARSE_OP_DATA(op) & BC_LEX_CHAR_MSB(1))
+#define BC_PARSE_OP_PREC(op) (BC_PARSE_OP_DATA(op) & ~(BC_LEX_CHAR_MSB(1)))
+
+#define BC_PARSE_EXPR_ENTRY(e1, e2, e3, e4, e5, e6, e7, e8) \
+ ((UINTMAX_C(e1) << 7) | (UINTMAX_C(e2) << 6) | (UINTMAX_C(e3) << 5) | \
+ (UINTMAX_C(e4) << 4) | (UINTMAX_C(e5) << 3) | (UINTMAX_C(e6) << 2) | \
+ (UINTMAX_C(e7) << 1) | (UINTMAX_C(e8) << 0))
+
+#define BC_PARSE_EXPR(i) \
+ (bc_parse_exprs[(((i) & (uchar) ~(0x07)) >> 3)] & (1 << (7 - ((i) & 0x07))))
+
+#define BC_PARSE_TOP_OP(p) (*((BcLexType*) bc_vec_top(&(p)->ops)))
+#define BC_PARSE_LEAF(prev, bin_last, rparen) \
+ (!(bin_last) && ((rparen) || bc_parse_inst_isLeaf(prev)))
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+#define BC_PARSE_INST_VAR(t) \
+ ((t) >= BC_INST_VAR && (t) <= BC_INST_SEED && (t) != BC_INST_ARRAY)
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+#define BC_PARSE_INST_VAR(t) \
+ ((t) >= BC_INST_VAR && (t) <= BC_INST_SCALE && (t) != BC_INST_ARRAY)
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+#define BC_PARSE_PREV_PREFIX(p) \
+ ((p) >= BC_INST_NEG && (p) <= BC_INST_BOOL_NOT)
+#define BC_PARSE_OP_PREFIX(t) ((t) == BC_LEX_OP_BOOL_NOT || (t) == BC_LEX_NEG)
+
+// We can calculate the conversion between tokens and exprs by subtracting the
+// position of the first operator in the lex enum and adding the position of
+// the first in the expr enum. Note: This only works for binary operators.
+#define BC_PARSE_TOKEN_INST(t) ((uchar) ((t) - BC_LEX_NEG + BC_INST_NEG))
+
+typedef enum BcParseStatus {
+
+ BC_PARSE_STATUS_SUCCESS,
+ BC_PARSE_STATUS_EMPTY_EXPR,
+
+} BcParseStatus;
+
+void bc_parse_expr(BcParse *p, uint8_t flags);
+
+void bc_parse_parse(BcParse *p);
+void bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next);
+
+extern const char bc_sig_msg[];
+extern const uchar bc_sig_msg_len;
+
+extern const char* const bc_parse_const1;
+extern const uint8_t bc_parse_exprs[];
+extern const uchar bc_parse_ops[];
+extern const BcParseNext bc_parse_next_expr;
+extern const BcParseNext bc_parse_next_param;
+extern const BcParseNext bc_parse_next_print;
+extern const BcParseNext bc_parse_next_rel;
+extern const BcParseNext bc_parse_next_elem;
+extern const BcParseNext bc_parse_next_for;
+extern const BcParseNext bc_parse_next_read;
+
+#else // BC_ENABLED
+
+#define BC_PARSE_NO_EXEC(p) (0)
+
+#endif // BC_ENABLED
+
+#endif // BC_BC_H
diff --git a/contrib/bc/include/bcl.h b/contrib/bc/include/bcl.h
new file mode 100644
index 000000000000..05f1631e5534
--- /dev/null
+++ b/contrib/bc/include/bcl.h
@@ -0,0 +1,184 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The public header for the bc library.
+ *
+ */
+
+#ifndef BC_BCL_H
+#define BC_BCL_H
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#define BC_SEED_ULONGS (4)
+#define BC_SEED_SIZE (sizeof(long) * BC_SEED_ULONGS)
+
+// For some reason, LONG_BIT is not defined in some versions of gcc.
+// I define it here to the minimum accepted value in the POSIX standard.
+#ifndef LONG_BIT
+#define LONG_BIT (32)
+#endif // LONG_BIT
+
+#ifndef BC_LONG_BIT
+#define BC_LONG_BIT LONG_BIT
+#endif // BC_LONG_BIT
+
+#if BC_LONG_BIT > LONG_BIT
+#error BC_LONG_BIT cannot be greater than LONG_BIT
+#endif // BC_LONG_BIT > LONG_BIT
+
+#if BC_LONG_BIT >= 64
+
+typedef uint64_t BclBigDig;
+typedef uint64_t BclRandInt;
+
+#elif BC_LONG_BIT >= 32
+
+typedef uint32_t BclBigDig;
+typedef uint32_t BclRandInt;
+
+#else
+
+#error BC_LONG_BIT must be at least 32
+
+#endif // BC_LONG_BIT >= 64
+
+typedef enum BclError {
+
+ BCL_ERROR_NONE,
+
+ BCL_ERROR_INVALID_NUM,
+ BCL_ERROR_INVALID_CONTEXT,
+ BCL_ERROR_SIGNAL,
+
+ BCL_ERROR_MATH_NEGATIVE,
+ BCL_ERROR_MATH_NON_INTEGER,
+ BCL_ERROR_MATH_OVERFLOW,
+ BCL_ERROR_MATH_DIVIDE_BY_ZERO,
+
+ BCL_ERROR_PARSE_INVALID_STR,
+
+ BCL_ERROR_FATAL_ALLOC_ERR,
+ BCL_ERROR_FATAL_UNKNOWN_ERR,
+
+ BCL_ERROR_NELEMS,
+
+} BclError;
+
+typedef struct BclNumber {
+
+ size_t i;
+
+} BclNumber;
+
+struct BclCtxt;
+
+typedef struct BclCtxt* BclContext;
+
+void bcl_handleSignal(void);
+bool bcl_running(void);
+
+BclError bcl_init(void);
+void bcl_free(void);
+
+bool bcl_abortOnFatalError(void);
+void bcl_setAbortOnFatalError(bool abrt);
+
+void bcl_gc(void);
+
+BclError bcl_pushContext(BclContext ctxt);
+void bcl_popContext(void);
+BclContext bcl_context(void);
+
+BclContext bcl_ctxt_create(void);
+void bcl_ctxt_free(BclContext ctxt);
+void bcl_ctxt_freeNums(BclContext ctxt);
+
+size_t bcl_ctxt_scale(BclContext ctxt);
+void bcl_ctxt_setScale(BclContext ctxt, size_t scale);
+size_t bcl_ctxt_ibase(BclContext ctxt);
+void bcl_ctxt_setIbase(BclContext ctxt, size_t ibase);
+size_t bcl_ctxt_obase(BclContext ctxt);
+void bcl_ctxt_setObase(BclContext ctxt, size_t obase);
+
+BclError bcl_err(BclNumber n);
+
+BclNumber bcl_num_create(void);
+void bcl_num_free(BclNumber n);
+
+bool bcl_num_neg(BclNumber n);
+void bcl_num_setNeg(BclNumber n, bool neg);
+size_t bcl_num_scale(BclNumber n);
+BclError bcl_num_setScale(BclNumber n, size_t scale);
+size_t bcl_num_len(BclNumber n);
+
+BclError bcl_copy(BclNumber d, BclNumber s);
+BclNumber bcl_dup(BclNumber s);
+
+BclError bcl_bigdig(BclNumber n, BclBigDig *result);
+BclNumber bcl_bigdig2num(BclBigDig val);
+
+BclNumber bcl_add(BclNumber a, BclNumber b);
+BclNumber bcl_sub(BclNumber a, BclNumber b);
+BclNumber bcl_mul(BclNumber a, BclNumber b);
+BclNumber bcl_div(BclNumber a, BclNumber b);
+BclNumber bcl_mod(BclNumber a, BclNumber b);
+BclNumber bcl_pow(BclNumber a, BclNumber b);
+BclNumber bcl_lshift(BclNumber a, BclNumber b);
+BclNumber bcl_rshift(BclNumber a, BclNumber b);
+BclNumber bcl_sqrt(BclNumber a);
+BclError bcl_divmod(BclNumber a, BclNumber b, BclNumber *c, BclNumber *d);
+BclNumber bcl_modexp(BclNumber a, BclNumber b, BclNumber c);
+
+ssize_t bcl_cmp(BclNumber a, BclNumber b);
+
+void bcl_zero(BclNumber n);
+void bcl_one(BclNumber n);
+
+BclNumber bcl_parse(const char *restrict val);
+char* bcl_string(BclNumber n);
+
+BclNumber bcl_irand(BclNumber a);
+BclNumber bcl_frand(size_t places);
+BclNumber bcl_ifrand(BclNumber a, size_t places);
+
+BclError bcl_rand_seedWithNum(BclNumber n);
+BclError bcl_rand_seed(unsigned char seed[BC_SEED_SIZE]);
+void bcl_rand_reseed(void);
+BclNumber bcl_rand_seed2num(void);
+BclRandInt bcl_rand_int(void);
+BclRandInt bcl_rand_bounded(BclRandInt bound);
+
+#endif // BC_BCL_H
diff --git a/contrib/bc/include/dc.h b/contrib/bc/include/dc.h
new file mode 100644
index 000000000000..07af135bc38f
--- /dev/null
+++ b/contrib/bc/include/dc.h
@@ -0,0 +1,66 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 bc.
+ *
+ */
+
+#ifndef BC_DC_H
+#define BC_DC_H
+
+#if DC_ENABLED
+
+#include <status.h>
+#include <lex.h>
+#include <parse.h>
+
+void dc_main(int argc, char **argv);
+
+extern const char dc_help[];
+
+void dc_lex_token(BcLex *l);
+bool dc_lex_negCommand(BcLex *l);
+
+extern const char dc_sig_msg[];
+extern const uchar dc_sig_msg_len;
+
+extern const uint8_t dc_lex_regs[];
+extern const size_t dc_lex_regs_len;
+
+extern const uint8_t dc_lex_tokens[];
+extern const uint8_t dc_parse_insts[];
+
+void dc_parse_parse(BcParse *p);
+void dc_parse_expr(BcParse *p, uint8_t flags);
+
+#endif // DC_ENABLED
+
+#endif // BC_DC_H
diff --git a/contrib/bc/include/file.h b/contrib/bc/include/file.h
new file mode 100644
index 000000000000..6fa08b3f436c
--- /dev/null
+++ b/contrib/bc/include/file.h
@@ -0,0 +1,65 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 implementing buffered I/O on my own terms.
+ *
+ */
+
+#ifndef BC_FILE_H
+#define BC_FILE_H
+
+#include <stdarg.h>
+
+#include <vector.h>
+
+#define BC_FILE_ULL_LENGTH (21)
+
+typedef struct BcFile {
+
+ int fd;
+ char *buf;
+ size_t len;
+ size_t cap;
+
+} BcFile;
+
+void bc_file_init(BcFile *f, int fd, char *buf, size_t cap);
+void bc_file_free(BcFile *f);
+
+void bc_file_putchar(BcFile *restrict f, uchar c);
+BcStatus bc_file_flushErr(BcFile *restrict f);
+void bc_file_flush(BcFile *restrict f);
+void bc_file_write(BcFile *restrict f, const char *buf, size_t n);
+void bc_file_printf(BcFile *restrict f, const char *fmt, ...);
+void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args);
+void bc_file_puts(BcFile *restrict f, const char *str);
+
+#endif // BC_FILE_H
diff --git a/contrib/bc/include/history.h b/contrib/bc/include/history.h
new file mode 100644
index 000000000000..c632bc81a2a0
--- /dev/null
+++ b/contrib/bc/include/history.h
@@ -0,0 +1,258 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Adapted from the following:
+ *
+ * linenoise.c -- guerrilla line editing library against the idea that a
+ * line editing lib needs to be 20,000 lines of C code.
+ *
+ * You can find the original source code at:
+ * http://github.com/antirez/linenoise
+ *
+ * You can find the fork that this code is based on at:
+ * https://github.com/rain-1/linenoise-mob
+ *
+ * ------------------------------------------------------------------------
+ *
+ * This code is also under the following license:
+ *
+ * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for line history.
+ *
+ */
+
+#ifndef BC_HISTORY_H
+#define BC_HISTORY_H
+
+#ifndef BC_ENABLE_HISTORY
+#define BC_ENABLE_HISTORY (1)
+#endif // BC_ENABLE_HISTORY
+
+#if BC_ENABLE_HISTORY
+
+#ifdef _WIN32
+#error History is not supported on Windows.
+#endif // _WIN32
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <signal.h>
+
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/select.h>
+
+#include <status.h>
+#include <vector.h>
+#include <read.h>
+
+#if BC_DEBUG_CODE
+#include <file.h>
+#endif // BC_DEBUG_CODE
+
+#define BC_HIST_DEF_COLS (80)
+#define BC_HIST_MAX_LEN (128)
+#define BC_HIST_MAX_LINE (4095)
+#define BC_HIST_SEQ_SIZE (64)
+
+#define BC_HIST_BUF_LEN(h) ((h)->buf.len - 1)
+#define BC_HIST_READ(s, n) (bc_history_read((s), (n)) == -1)
+
+#define BC_HIST_NEXT (false)
+#define BC_HIST_PREV (true)
+
+#if BC_DEBUG_CODE
+
+#define BC_HISTORY_DEBUG_BUF_SIZE (1024)
+
+#define lndebug(...) \
+ do { \
+ if (bc_history_debug_fp.fd == 0) { \
+ bc_history_debug_buf = bc_vm_malloc(BC_HISTORY_DEBUG_BUF_SIZE); \
+ bc_file_init(&bc_history_debug_fp, \
+ open("/tmp/lndebug.txt", O_APPEND), \
+ BC_HISTORY_DEBUG_BUF_SIZE); \
+ bc_file_printf(&bc_history_debug_fp, \
+ "[%zu %zu %zu] p: %d, rows: %d, " \
+ "rpos: %d, max: %zu, oldmax: %d\n", \
+ l->len, l->pos, l->oldcolpos, plen, rows, rpos, \
+ l->maxrows, old_rows); \
+ } \
+ bc_file_printf(&bc_history_debug_fp, ", " __VA_ARGS__); \
+ bc_file_flush(&bc_history_debug_fp); \
+ } while (0)
+#else // BC_DEBUG_CODE
+#define lndebug(fmt, ...)
+#endif // BC_DEBUG_CODE
+
+#if !BC_ENABLE_PROMPT
+#define bc_history_line(h, vec, prompt) bc_history_line(h, vec)
+#define bc_history_raw(h, prompt) bc_history_raw(h)
+#define bc_history_edit(h, prompt) bc_history_edit(h)
+#endif // BC_ENABLE_PROMPT
+
+typedef enum BcHistoryAction {
+
+ BC_ACTION_NULL = 0,
+ BC_ACTION_CTRL_A = 1,
+ BC_ACTION_CTRL_B = 2,
+ BC_ACTION_CTRL_C = 3,
+ BC_ACTION_CTRL_D = 4,
+ BC_ACTION_CTRL_E = 5,
+ BC_ACTION_CTRL_F = 6,
+ BC_ACTION_CTRL_H = 8,
+ BC_ACTION_TAB = 9,
+ BC_ACTION_LINE_FEED = 10,
+ BC_ACTION_CTRL_K = 11,
+ BC_ACTION_CTRL_L = 12,
+ BC_ACTION_ENTER = 13,
+ BC_ACTION_CTRL_N = 14,
+ BC_ACTION_CTRL_P = 16,
+ BC_ACTION_CTRL_T = 20,
+ BC_ACTION_CTRL_U = 21,
+ BC_ACTION_CTRL_W = 23,
+ BC_ACTION_CTRL_Z = 26,
+ BC_ACTION_ESC = 27,
+ BC_ACTION_BACKSPACE = 127
+
+} BcHistoryAction;
+
+/**
+ * This represents the state during line editing. We pass this state
+ * to functions implementing specific editing functionalities.
+ */
+typedef struct BcHistory {
+
+ /// Edited line buffer.
+ BcVec buf;
+
+ /// The history.
+ BcVec history;
+
+#if BC_ENABLE_PROMPT
+ /// Prompt to display.
+ const char *prompt;
+
+ /// Prompt length.
+ size_t plen;
+#endif // BC_ENABLE_PROMPT
+
+ /// Prompt column length.
+ size_t pcol;
+
+ /// Current cursor position.
+ size_t pos;
+
+ /// Previous refresh cursor column position.
+ size_t oldcolpos;
+
+ /// Number of columns in terminal.
+ size_t cols;
+
+ /// The history index we are currently editing.
+ size_t idx;
+
+ /// The original terminal state.
+ struct termios orig_termios;
+
+ /// These next three are here because pahole found a 4 byte hole here.
+
+ /// This is to signal that there is more, so we don't process yet.
+ bool stdin_has_data;
+
+ /// Whether we are in rawmode.
+ bool rawMode;
+
+ /// Whether the terminal is bad.
+ bool badTerm;
+
+ /// This is to check if stdin has more data.
+ fd_set rdset;
+
+ /// This is to check if stdin has more data.
+ struct timespec ts;
+
+ /// This is to check if stdin has more data.
+ sigset_t sigmask;
+
+} BcHistory;
+
+BcStatus bc_history_line(BcHistory *h, BcVec *vec, const char *prompt);
+
+void bc_history_init(BcHistory *h);
+void bc_history_free(BcHistory *h);
+
+extern const char *bc_history_bad_terms[];
+extern const char bc_history_tab[];
+extern const size_t bc_history_tab_len;
+extern const char bc_history_ctrlc[];
+extern const uint32_t bc_history_wchars[][2];
+extern const size_t bc_history_wchars_len;
+extern const uint32_t bc_history_combo_chars[];
+extern const size_t bc_history_combo_chars_len;
+#if BC_DEBUG_CODE
+extern BcFile bc_history_debug_fp;
+extern char *bc_history_debug_buf;
+void bc_history_printKeyCodes(BcHistory* l);
+#endif // BC_DEBUG_CODE
+
+#endif // BC_ENABLE_HISTORY
+
+#endif // BC_HISTORY_H
diff --git a/contrib/bc/include/lang.h b/contrib/bc/include/lang.h
new file mode 100644
index 000000000000..a8ab08ad9bf4
--- /dev/null
+++ b/contrib/bc/include/lang.h
@@ -0,0 +1,327 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 program data.
+ *
+ */
+
+#ifndef BC_LANG_H
+#define BC_LANG_H
+
+#include <stdbool.h>
+
+#include <status.h>
+#include <vector.h>
+#include <num.h>
+
+#if BC_ENABLED
+#define BC_INST_IS_ASSIGN(i) \
+ ((i) == BC_INST_ASSIGN || (i) == BC_INST_ASSIGN_NO_VAL)
+#define BC_INST_USE_VAL(i) ((i) <= BC_INST_ASSIGN)
+#else // BC_ENABLED
+#define BC_INST_IS_ASSIGN(i) ((i) == BC_INST_ASSIGN_NO_VAL)
+#define BC_INST_USE_VAL(i) (false)
+#endif // BC_ENABLED
+
+#ifndef NDEBUG
+#define BC_ENABLE_FUNC_FREE (1)
+#else // NDEBUG
+#define BC_ENABLE_FUNC_FREE DC_ENABLED
+#endif // NDEBUG
+
+typedef enum BcInst {
+
+#if BC_ENABLED
+ BC_INST_INC = 0,
+ BC_INST_DEC,
+#endif // BC_ENABLED
+
+ BC_INST_NEG,
+ BC_INST_BOOL_NOT,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_TRUNC,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ BC_INST_POWER,
+ BC_INST_MULTIPLY,
+ BC_INST_DIVIDE,
+ BC_INST_MODULUS,
+ BC_INST_PLUS,
+ BC_INST_MINUS,
+
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_PLACES,
+
+ BC_INST_LSHIFT,
+ BC_INST_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ BC_INST_REL_EQ,
+ BC_INST_REL_LE,
+ BC_INST_REL_GE,
+ BC_INST_REL_NE,
+ BC_INST_REL_LT,
+ BC_INST_REL_GT,
+
+ BC_INST_BOOL_OR,
+ BC_INST_BOOL_AND,
+
+#if BC_ENABLED
+ BC_INST_ASSIGN_POWER,
+ BC_INST_ASSIGN_MULTIPLY,
+ BC_INST_ASSIGN_DIVIDE,
+ BC_INST_ASSIGN_MODULUS,
+ BC_INST_ASSIGN_PLUS,
+ BC_INST_ASSIGN_MINUS,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_ASSIGN_PLACES,
+ BC_INST_ASSIGN_LSHIFT,
+ BC_INST_ASSIGN_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_INST_ASSIGN,
+
+ BC_INST_ASSIGN_POWER_NO_VAL,
+ BC_INST_ASSIGN_MULTIPLY_NO_VAL,
+ BC_INST_ASSIGN_DIVIDE_NO_VAL,
+ BC_INST_ASSIGN_MODULUS_NO_VAL,
+ BC_INST_ASSIGN_PLUS_NO_VAL,
+ BC_INST_ASSIGN_MINUS_NO_VAL,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_ASSIGN_PLACES_NO_VAL,
+ BC_INST_ASSIGN_LSHIFT_NO_VAL,
+ BC_INST_ASSIGN_RSHIFT_NO_VAL,
+#endif // BC_ENABLE_EXTRA_MATH
+#endif // BC_ENABLED
+ BC_INST_ASSIGN_NO_VAL,
+
+ BC_INST_NUM,
+ BC_INST_VAR,
+ BC_INST_ARRAY_ELEM,
+#if BC_ENABLED
+ BC_INST_ARRAY,
+#endif // BC_ENABLED
+
+ BC_INST_ZERO,
+ BC_INST_ONE,
+
+#if BC_ENABLED
+ BC_INST_LAST,
+#endif // BC_ENABLED
+ BC_INST_IBASE,
+ BC_INST_OBASE,
+ BC_INST_SCALE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_SEED,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_LENGTH,
+ BC_INST_SCALE_FUNC,
+ BC_INST_SQRT,
+ BC_INST_ABS,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_IRAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_READ,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_RAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_MAXIBASE,
+ BC_INST_MAXOBASE,
+ BC_INST_MAXSCALE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_MAXRAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+ BC_INST_PRINT,
+ BC_INST_PRINT_POP,
+ BC_INST_STR,
+ BC_INST_PRINT_STR,
+
+#if BC_ENABLED
+ BC_INST_JUMP,
+ BC_INST_JUMP_ZERO,
+
+ BC_INST_CALL,
+
+ BC_INST_RET,
+ BC_INST_RET0,
+ BC_INST_RET_VOID,
+
+ BC_INST_HALT,
+#endif // BC_ENABLED
+
+ BC_INST_POP,
+
+#if DC_ENABLED
+ BC_INST_POP_EXEC,
+ BC_INST_MODEXP,
+ BC_INST_DIVMOD,
+
+ BC_INST_EXECUTE,
+ BC_INST_EXEC_COND,
+
+ BC_INST_ASCIIFY,
+ BC_INST_PRINT_STREAM,
+
+ BC_INST_PRINT_STACK,
+ BC_INST_CLEAR_STACK,
+ BC_INST_STACK_LEN,
+ BC_INST_DUPLICATE,
+ BC_INST_SWAP,
+
+ BC_INST_LOAD,
+ BC_INST_PUSH_VAR,
+ BC_INST_PUSH_TO_VAR,
+
+ BC_INST_QUIT,
+ BC_INST_NQUIT,
+#endif // DC_ENABLED
+
+ BC_INST_INVALID = UCHAR_MAX,
+
+} BcInst;
+
+typedef struct BcId {
+ char *name;
+ size_t idx;
+} BcId;
+
+typedef struct BcLoc {
+ size_t loc;
+ size_t idx;
+} BcLoc;
+
+typedef struct BcConst {
+ char *val;
+ BcBigDig base;
+ BcNum num;
+} BcConst;
+
+typedef struct BcFunc {
+
+ BcVec code;
+#if BC_ENABLED
+ BcVec labels;
+ BcVec autos;
+ size_t nparams;
+#endif // BC_ENABLED
+
+ BcVec strs;
+ BcVec consts;
+
+ const char *name;
+#if BC_ENABLED
+ bool voidfn;
+#endif // BC_ENABLED
+
+} BcFunc;
+
+typedef enum BcResultType {
+
+ BC_RESULT_VAR,
+ BC_RESULT_ARRAY_ELEM,
+#if BC_ENABLED
+ BC_RESULT_ARRAY,
+#endif // BC_ENABLED
+
+ BC_RESULT_STR,
+
+ BC_RESULT_TEMP,
+
+ BC_RESULT_ZERO,
+ BC_RESULT_ONE,
+
+#if BC_ENABLED
+ BC_RESULT_LAST,
+ BC_RESULT_VOID,
+#endif // BC_ENABLED
+ BC_RESULT_IBASE,
+ BC_RESULT_OBASE,
+ BC_RESULT_SCALE,
+#if BC_ENABLE_EXTRA_MATH
+ BC_RESULT_SEED,
+#endif // BC_ENABLE_EXTRA_MATH
+
+} BcResultType;
+
+typedef union BcResultData {
+ BcNum n;
+ BcVec v;
+ BcLoc loc;
+} BcResultData;
+
+typedef struct BcResult {
+ BcResultType t;
+ BcResultData d;
+} BcResult;
+
+typedef struct BcInstPtr {
+ size_t func;
+ size_t idx;
+ size_t len;
+} BcInstPtr;
+
+typedef enum BcType {
+ BC_TYPE_VAR,
+ BC_TYPE_ARRAY,
+#if BC_ENABLED
+ BC_TYPE_REF,
+#endif // BC_ENABLED
+} BcType;
+
+struct BcProgram;
+
+void bc_func_init(BcFunc *f, const char* name);
+void bc_func_insert(BcFunc *f, struct BcProgram* p, char* name,
+ BcType type, size_t line);
+void bc_func_reset(BcFunc *f);
+void bc_func_free(void *func);
+
+void bc_array_init(BcVec *a, bool nums);
+void bc_array_copy(BcVec *d, const BcVec *s);
+
+void bc_string_free(void *string);
+void bc_const_free(void *constant);
+void bc_id_free(void *id);
+void bc_result_clear(BcResult *r);
+void bc_result_copy(BcResult *d, BcResult *src);
+void bc_result_free(void *result);
+
+void bc_array_expand(BcVec *a, size_t len);
+int bc_id_cmp(const BcId *e1, const BcId *e2);
+
+#if BC_DEBUG_CODE
+extern const char* bc_inst_names[];
+#endif // BC_DEBUG_CODE
+
+extern const char bc_func_main[];
+extern const char bc_func_read[];
+
+#endif // BC_LANG_H
diff --git a/contrib/bc/include/lex.h b/contrib/bc/include/lex.h
new file mode 100644
index 000000000000..ff9592b6e928
--- /dev/null
+++ b/contrib/bc/include/lex.h
@@ -0,0 +1,247 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 bc's lexer.
+ *
+ */
+
+#ifndef BC_LEX_H
+#define BC_LEX_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <status.h>
+#include <vector.h>
+#include <lang.h>
+
+#define bc_lex_err(l, e) (bc_vm_handleError((e), (l)->line))
+#define bc_lex_verr(l, e, ...) (bc_vm_handleError((e), (l)->line, __VA_ARGS__))
+
+#if BC_ENABLED
+
+#if DC_ENABLED
+#define BC_LEX_NEG_CHAR (BC_IS_BC ? '-' : '_')
+#define BC_LEX_LAST_NUM_CHAR (BC_IS_BC ? 'Z' : 'F')
+#else // DC_ENABLED
+#define BC_LEX_NEG_CHAR ('-')
+#define BC_LEX_LAST_NUM_CHAR ('Z')
+#endif // DC_ENABLED
+
+#else // BC_ENABLED
+
+#define BC_LEX_NEG_CHAR ('_')
+#define BC_LEX_LAST_NUM_CHAR ('F')
+
+#endif // BC_ENABLED
+
+#define BC_LEX_NUM_CHAR(c, pt, int_only) \
+ (isdigit(c) || ((c) >= 'A' && (c) <= BC_LEX_LAST_NUM_CHAR) || \
+ ((c) == '.' && !(pt) && !(int_only)))
+
+// BC_LEX_NEG is not used in lexing; it is only for parsing.
+typedef enum BcLexType {
+
+ BC_LEX_EOF,
+ BC_LEX_INVALID,
+
+#if BC_ENABLED
+ BC_LEX_OP_INC,
+ BC_LEX_OP_DEC,
+#endif // BC_ENABLED
+
+ BC_LEX_NEG,
+ BC_LEX_OP_BOOL_NOT,
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_TRUNC,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ BC_LEX_OP_POWER,
+ BC_LEX_OP_MULTIPLY,
+ BC_LEX_OP_DIVIDE,
+ BC_LEX_OP_MODULUS,
+ BC_LEX_OP_PLUS,
+ BC_LEX_OP_MINUS,
+
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_PLACES,
+
+ BC_LEX_OP_LSHIFT,
+ BC_LEX_OP_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ BC_LEX_OP_REL_EQ,
+ BC_LEX_OP_REL_LE,
+ BC_LEX_OP_REL_GE,
+ BC_LEX_OP_REL_NE,
+ BC_LEX_OP_REL_LT,
+ BC_LEX_OP_REL_GT,
+
+ BC_LEX_OP_BOOL_OR,
+ BC_LEX_OP_BOOL_AND,
+
+#if BC_ENABLED
+ BC_LEX_OP_ASSIGN_POWER,
+ BC_LEX_OP_ASSIGN_MULTIPLY,
+ BC_LEX_OP_ASSIGN_DIVIDE,
+ BC_LEX_OP_ASSIGN_MODULUS,
+ BC_LEX_OP_ASSIGN_PLUS,
+ BC_LEX_OP_ASSIGN_MINUS,
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_ASSIGN_PLACES,
+ BC_LEX_OP_ASSIGN_LSHIFT,
+ BC_LEX_OP_ASSIGN_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+#endif // BC_ENABLED
+ BC_LEX_OP_ASSIGN,
+
+ BC_LEX_NLINE,
+ BC_LEX_WHITESPACE,
+
+ BC_LEX_LPAREN,
+ BC_LEX_RPAREN,
+
+ BC_LEX_LBRACKET,
+ BC_LEX_COMMA,
+ BC_LEX_RBRACKET,
+
+ BC_LEX_LBRACE,
+ BC_LEX_SCOLON,
+ BC_LEX_RBRACE,
+
+ BC_LEX_STR,
+ BC_LEX_NAME,
+ BC_LEX_NUMBER,
+
+#if BC_ENABLED
+ BC_LEX_KW_AUTO,
+ BC_LEX_KW_BREAK,
+ BC_LEX_KW_CONTINUE,
+ BC_LEX_KW_DEFINE,
+ BC_LEX_KW_FOR,
+ BC_LEX_KW_IF,
+ BC_LEX_KW_LIMITS,
+ BC_LEX_KW_RETURN,
+ BC_LEX_KW_WHILE,
+ BC_LEX_KW_HALT,
+ BC_LEX_KW_LAST,
+#endif // BC_ENABLED
+ BC_LEX_KW_IBASE,
+ BC_LEX_KW_OBASE,
+ BC_LEX_KW_SCALE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_SEED,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_LENGTH,
+ BC_LEX_KW_PRINT,
+ BC_LEX_KW_SQRT,
+ BC_LEX_KW_ABS,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_IRAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_QUIT,
+ BC_LEX_KW_READ,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_RAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_MAXIBASE,
+ BC_LEX_KW_MAXOBASE,
+ BC_LEX_KW_MAXSCALE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_MAXRAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ELSE,
+
+#if DC_ENABLED
+ BC_LEX_EQ_NO_REG,
+ BC_LEX_OP_MODEXP,
+ BC_LEX_OP_DIVMOD,
+
+ BC_LEX_COLON,
+ BC_LEX_EXECUTE,
+ BC_LEX_PRINT_STACK,
+ BC_LEX_CLEAR_STACK,
+ BC_LEX_STACK_LEVEL,
+ BC_LEX_DUPLICATE,
+ BC_LEX_SWAP,
+ BC_LEX_POP,
+
+ BC_LEX_ASCIIFY,
+ BC_LEX_PRINT_STREAM,
+
+ BC_LEX_STORE_IBASE,
+ BC_LEX_STORE_OBASE,
+ BC_LEX_STORE_SCALE,
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_STORE_SEED,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_LOAD,
+ BC_LEX_LOAD_POP,
+ BC_LEX_STORE_PUSH,
+ BC_LEX_PRINT_POP,
+ BC_LEX_NQUIT,
+ BC_LEX_SCALE_FACTOR,
+#endif // DC_ENABLED
+
+} BcLexType;
+
+struct BcLex;
+typedef void (*BcLexNext)(struct BcLex*);
+
+typedef struct BcLex {
+
+ const char *buf;
+ size_t i;
+ size_t line;
+ size_t len;
+
+ BcLexType t;
+ BcLexType last;
+ BcVec str;
+
+} BcLex;
+
+void bc_lex_init(BcLex *l);
+void bc_lex_free(BcLex *l);
+void bc_lex_file(BcLex *l, const char *file);
+void bc_lex_text(BcLex *l, const char *text);
+void bc_lex_next(BcLex *l);
+
+void bc_lex_lineComment(BcLex *l);
+void bc_lex_comment(BcLex *l);
+void bc_lex_whitespace(BcLex *l);
+void bc_lex_number(BcLex *l, char start);
+void bc_lex_name(BcLex *l);
+void bc_lex_commonTokens(BcLex *l, char c);
+
+void bc_lex_invalidChar(BcLex *l, char c);
+
+#endif // BC_LEX_H
diff --git a/contrib/bc/include/library.h b/contrib/bc/include/library.h
new file mode 100644
index 000000000000..17c3f572caee
--- /dev/null
+++ b/contrib/bc/include/library.h
@@ -0,0 +1,165 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The private header for the bc library.
+ *
+ */
+
+#ifndef LIBBC_PRIVATE_H
+#define LIBBC_PRIVATE_H
+
+#include <bcl.h>
+
+#include <num.h>
+
+#define BC_FUNC_HEADER_LOCK(l) \
+ do { \
+ BC_SIG_LOCK; \
+ BC_SETJMP_LOCKED(l); \
+ vm.err = BCL_ERROR_NONE; \
+ vm.running = 1; \
+ } while (0)
+
+#define BC_FUNC_FOOTER_UNLOCK(e) \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ e = vm.err; \
+ vm.running = 0; \
+ BC_UNSETJMP; \
+ BC_LONGJMP_STOP; \
+ vm.sig_lock = 0; \
+ } while (0)
+
+#define BC_FUNC_HEADER(l) \
+ do { \
+ BC_SETJMP(l); \
+ vm.err = BCL_ERROR_NONE; \
+ vm.running = 1; \
+ } while (0)
+
+#define BC_FUNC_HEADER_INIT(l) \
+ do { \
+ BC_SETJMP_LOCKED(l); \
+ vm.err = BCL_ERROR_NONE; \
+ vm.running = 1; \
+ } while (0)
+
+#define BC_FUNC_FOOTER_NO_ERR \
+ do { \
+ vm.running = 0; \
+ BC_UNSETJMP; \
+ BC_LONGJMP_STOP; \
+ vm.sig_lock = 0; \
+ } while (0)
+
+#define BC_FUNC_FOOTER(e) \
+ do { \
+ e = vm.err; \
+ BC_FUNC_FOOTER_NO_ERR; \
+ } while (0)
+
+#define BC_FUNC_RESETJMP(l) \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ BC_UNSETJMP; \
+ BC_SETJMP_LOCKED(l); \
+ } while (0)
+
+#define BC_MAYBE_SETUP(c, e, n, idx) \
+ do { \
+ if (BC_ERR((e) != BCL_ERROR_NONE)) { \
+ if ((n).num != NULL) bc_num_free(&(n)); \
+ idx.i = 0 - (size_t) (e); \
+ } \
+ else idx = bcl_num_insert(c, &(n)); \
+ } while (0)
+
+#define BC_CHECK_CTXT(c) \
+ do { \
+ c = bcl_context(); \
+ if (BC_ERR(c == NULL)) { \
+ BclNumber n_num; \
+ n_num.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \
+ return n_num; \
+ } \
+ } while (0)
+
+#define BC_CHECK_CTXT_ERR(c) \
+ do { \
+ c = bcl_context(); \
+ if (BC_ERR(c == NULL)) { \
+ return BCL_ERROR_INVALID_CONTEXT; \
+ } \
+ } while (0)
+
+#define BC_CHECK_CTXT_ASSERT(c) \
+ do { \
+ c = bcl_context(); \
+ assert(c != NULL); \
+ } while (0)
+
+#define BC_CHECK_NUM(c, n) \
+ do { \
+ if (BC_ERR((n).i >= (c)->nums.len)) { \
+ if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) return (n); \
+ else { \
+ BclNumber n_num; \
+ n_num.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \
+ return n_num; \
+ } \
+ } \
+ } while (0)
+
+#define BC_CHECK_NUM_ERR(c, n) \
+ do { \
+ if (BC_ERR((n).i >= (c)->nums.len)) { \
+ if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) \
+ return (BclError) (0 - (n).i); \
+ else return BCL_ERROR_INVALID_NUM; \
+ } \
+ } while (0)
+
+#define BC_NUM(c, n) ((BcNum*) bc_vec_item(&(c)->nums, (n).i))
+
+typedef size_t (*BcReqOp)(const BcNum*, const BcNum*, size_t);
+
+typedef struct BclCtxt {
+
+ size_t scale;
+ size_t ibase;
+ size_t obase;
+
+ BcVec nums;
+ BcVec free_nums;
+
+} BclCtxt;
+
+#endif // LIBBC_PRIVATE_H
diff --git a/contrib/bc/include/num.h b/contrib/bc/include/num.h
new file mode 100644
index 000000000000..4868ae3de6a8
--- /dev/null
+++ b/contrib/bc/include/num.h
@@ -0,0 +1,261 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 the num type.
+ *
+ */
+
+#ifndef BC_NUM_H
+#define BC_NUM_H
+
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/types.h>
+
+#include <status.h>
+#include <vector.h>
+#include <bcl.h>
+
+#ifndef BC_ENABLE_EXTRA_MATH
+#define BC_ENABLE_EXTRA_MATH (1)
+#endif // BC_ENABLE_EXTRA_MATH
+
+#define BC_BASE (10)
+
+typedef unsigned long ulong;
+
+typedef BclBigDig BcBigDig;
+
+#if BC_LONG_BIT >= 64
+
+#define BC_NUM_BIGDIG_MAX ((BcBigDig) UINT64_MAX)
+
+#define BC_BASE_DIGS (9)
+#define BC_BASE_POW (1000000000)
+
+#define BC_NUM_BIGDIG_C UINT64_C
+
+typedef int_least32_t BcDig;
+
+#elif BC_LONG_BIT >= 32
+
+#define BC_NUM_BIGDIG_MAX ((BcBigDig) UINT32_MAX)
+
+#define BC_BASE_DIGS (4)
+#define BC_BASE_POW (10000)
+
+#define BC_NUM_BIGDIG_C UINT32_C
+
+typedef int_least16_t BcDig;
+
+#else
+
+#error BC_LONG_BIT must be at least 32
+
+#endif // BC_LONG_BIT >= 64
+
+#define BC_NUM_DEF_SIZE (8)
+
+typedef struct BcNum {
+ BcDig *restrict num;
+ size_t rdx;
+ size_t scale;
+ size_t len;
+ size_t cap;
+} BcNum;
+
+#if BC_ENABLE_EXTRA_MATH
+
+#ifndef BC_ENABLE_RAND
+#define BC_ENABLE_RAND (1)
+#endif // BC_ENABLE_RAND
+
+#if BC_ENABLE_RAND
+// Forward declaration
+struct BcRNG;
+#endif // BC_ENABLE_RAND
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+#define BC_NUM_MIN_BASE (BC_NUM_BIGDIG_C(2))
+#define BC_NUM_MAX_POSIX_IBASE (BC_NUM_BIGDIG_C(16))
+#define BC_NUM_MAX_IBASE (BC_NUM_BIGDIG_C(36))
+// This is the max base allowed by bc_num_parseChar().
+#define BC_NUM_MAX_LBASE (BC_NUM_BIGDIG_C('Z' + BC_BASE + 1))
+#define BC_NUM_PRINT_WIDTH (BC_NUM_BIGDIG_C(69))
+
+#ifndef BC_NUM_KARATSUBA_LEN
+#define BC_NUM_KARATSUBA_LEN (BC_NUM_BIGDIG_C(32))
+#elif BC_NUM_KARATSUBA_LEN < 16
+#error BC_NUM_KARATSUBA_LEN must be at least 16.
+#endif // BC_NUM_KARATSUBA_LEN
+
+// A crude, but always big enough, calculation of
+// the size required for ibase and obase BcNum's.
+#define BC_NUM_BIGDIG_LOG10 (BC_NUM_DEF_SIZE)
+
+#define BC_NUM_NONZERO(n) ((n)->len)
+#define BC_NUM_ZERO(n) (!BC_NUM_NONZERO(n))
+#define BC_NUM_ONE(n) ((n)->len == 1 && (n)->rdx == 0 && (n)->num[0] == 1)
+
+#define BC_NUM_NUM_LETTER(c) ((c) - 'A' + BC_BASE)
+
+#define BC_NUM_KARATSUBA_ALLOCS (6)
+
+#define BC_NUM_ROUND_POW(s) (bc_vm_growSize((s), BC_BASE_DIGS - 1))
+#define BC_NUM_RDX(s) (BC_NUM_ROUND_POW(s) / BC_BASE_DIGS)
+
+#define BC_NUM_RDX_VAL(n) ((n)->rdx >> 1)
+#define BC_NUM_RDX_VAL_NP(n) ((n).rdx >> 1)
+#define BC_NUM_RDX_SET(n, v) \
+ ((n)->rdx = (((v) << 1) | ((n)->rdx & (BcBigDig) 1)))
+#define BC_NUM_RDX_SET_NP(n, v) \
+ ((n).rdx = (((v) << 1) | ((n).rdx & (BcBigDig) 1)))
+#define BC_NUM_RDX_SET_NEG(n, v, neg) \
+ ((n)->rdx = (((v) << 1) | (neg)))
+
+#define BC_NUM_RDX_VALID(n) \
+ (BC_NUM_ZERO(n) || BC_NUM_RDX_VAL(n) * BC_BASE_DIGS >= (n)->scale)
+#define BC_NUM_RDX_VALID_NP(n) \
+ ((!(n).len) || BC_NUM_RDX_VAL_NP(n) * BC_BASE_DIGS >= (n).scale)
+
+#define BC_NUM_NEG(n) ((n)->rdx & ((BcBigDig) 1))
+#define BC_NUM_NEG_NP(n) ((n).rdx & ((BcBigDig) 1))
+#define BC_NUM_NEG_CLR(n) ((n)->rdx &= ~((BcBigDig) 1))
+#define BC_NUM_NEG_CLR_NP(n) ((n).rdx &= ~((BcBigDig) 1))
+#define BC_NUM_NEG_SET(n) ((n)->rdx |= ((BcBigDig) 1))
+#define BC_NUM_NEG_TGL(n) ((n)->rdx ^= ((BcBigDig) 1))
+#define BC_NUM_NEG_TGL_NP(n) ((n).rdx ^= ((BcBigDig) 1))
+#define BC_NUM_NEG_VAL(n, v) (((n)->rdx & ~((BcBigDig) 1)) | (v))
+#define BC_NUM_NEG_VAL_NP(n, v) (((n).rdx & ~((BcBigDig) 1)) | (v))
+
+#define BC_NUM_SIZE(n) ((n) * sizeof(BcDig))
+
+#if BC_DEBUG_CODE
+#define BC_NUM_PRINT(x) fprintf(stderr, "%s = %lu\n", #x, (unsigned long)(x))
+#define DUMP_NUM bc_num_dump
+#else // BC_DEBUG_CODE
+#undef DUMP_NUM
+#define DUMP_NUM(x,y)
+#define BC_NUM_PRINT(x)
+#endif // BC_DEBUG_CODE
+
+typedef void (*BcNumBinaryOp)(BcNum*, BcNum*, BcNum*, size_t);
+typedef size_t (*BcNumBinaryOpReq)(const BcNum*, const BcNum*, size_t);
+typedef void (*BcNumDigitOp)(size_t, size_t, bool);
+typedef void (*BcNumShiftAddOp)(BcDig*, const BcDig*, size_t);
+
+void bc_num_init(BcNum *restrict n, size_t req);
+void bc_num_setup(BcNum *restrict n, BcDig *restrict num, size_t cap);
+void bc_num_copy(BcNum *d, const BcNum *s);
+void bc_num_createCopy(BcNum *d, const BcNum *s);
+void bc_num_createFromBigdig(BcNum *n, BcBigDig val);
+void bc_num_clear(BcNum *restrict n);
+void bc_num_free(void *num);
+
+size_t bc_num_scale(const BcNum *restrict n);
+size_t bc_num_len(const BcNum *restrict n);
+
+void bc_num_bigdig(const BcNum *restrict n, BcBigDig *result);
+void bc_num_bigdig2(const BcNum *restrict n, BcBigDig *result);
+void bc_num_bigdig2num(BcNum *restrict n, BcBigDig val);
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+void bc_num_irand(const BcNum *restrict a, BcNum *restrict b,
+ struct BcRNG *restrict rng);
+void bc_num_rng(const BcNum *restrict n, struct BcRNG *rng);
+void bc_num_createFromRNG(BcNum *restrict n, struct BcRNG *rng);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+void bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+void bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+void bc_num_mul(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+void bc_num_div(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+void bc_num_mod(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+void bc_num_pow(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+#if BC_ENABLE_EXTRA_MATH
+void bc_num_places(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+void bc_num_lshift(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+void bc_num_rshift(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+#endif // BC_ENABLE_EXTRA_MATH
+void bc_num_sqrt(BcNum *restrict a, BcNum *restrict b, size_t scale);
+void bc_num_sr(BcNum *restrict a, BcNum *restrict b, size_t scale);
+void bc_num_divmod(BcNum *a, BcNum *b, BcNum *c, BcNum *d, size_t scale);
+
+size_t bc_num_addReq(const BcNum* a, const BcNum* b, size_t scale);
+
+size_t bc_num_mulReq(const BcNum *a, const BcNum *b, size_t scale);
+size_t bc_num_divReq(const BcNum *a, const BcNum *b, size_t scale);
+size_t bc_num_powReq(const BcNum *a, const BcNum *b, size_t scale);
+#if BC_ENABLE_EXTRA_MATH
+size_t bc_num_placesReq(const BcNum *a, const BcNum *b, size_t scale);
+#endif // BC_ENABLE_EXTRA_MATH
+
+void bc_num_truncate(BcNum *restrict n, size_t places);
+void bc_num_extend(BcNum *restrict n, size_t places);
+void bc_num_shiftRight(BcNum *restrict n, size_t places);
+
+ssize_t bc_num_cmp(const BcNum *a, const BcNum *b);
+
+#if DC_ENABLED
+void bc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d);
+#endif // DC_ENABLED
+
+void bc_num_zero(BcNum *restrict n);
+void bc_num_one(BcNum *restrict n);
+ssize_t bc_num_cmpZero(const BcNum *n);
+
+bool bc_num_strValid(const char *restrict val);
+void bc_num_parse(BcNum *restrict n, const char *restrict val, BcBigDig base);
+void bc_num_print(BcNum *restrict n, BcBigDig base, bool newline);
+#if DC_ENABLED
+void bc_num_stream(BcNum *restrict n, BcBigDig base);
+#endif // DC_ENABLED
+
+#if BC_DEBUG_CODE
+void bc_num_printDebug(const BcNum *n, const char *name, bool emptyline);
+void bc_num_printDigs(const BcDig* n, size_t len, bool emptyline);
+void bc_num_printWithDigs(const BcNum *n, const char *name, bool emptyline);
+void bc_num_dump(const char *varname, const BcNum *n);
+#endif // BC_DEBUG_CODE
+
+extern const char bc_num_hex_digits[];
+extern const BcBigDig bc_num_pow10[BC_BASE_DIGS + 1];
+
+extern const BcDig bc_num_bigdigMax[];
+extern const BcDig bc_num_bigdigMax2[];
+extern const size_t bc_num_bigdigMax_size;
+extern const size_t bc_num_bigdigMax2_size;
+
+#endif // BC_NUM_H
diff --git a/contrib/bc/include/opt.h b/contrib/bc/include/opt.h
new file mode 100644
index 000000000000..eb3d5959adc0
--- /dev/null
+++ b/contrib/bc/include/opt.h
@@ -0,0 +1,79 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Adapted from https://github.com/skeeto/optparse
+ *
+ * *****************************************************************************
+ *
+ * Definitions for getopt_long() replacement.
+ *
+ */
+
+#ifndef BC_OPT_H
+#define BC_OPT_H
+
+#include <stdbool.h>
+
+typedef struct BcOpt {
+ char **argv;
+ size_t optind;
+ int optopt;
+ int subopt;
+ char *optarg;
+} BcOpt;
+
+typedef enum BcOptType {
+ BC_OPT_NONE,
+ BC_OPT_REQUIRED,
+ BC_OPT_BC_ONLY,
+ BC_OPT_DC_ONLY,
+} BcOptType;
+
+typedef struct BcOptLong {
+ const char *name;
+ BcOptType type;
+ int val;
+} BcOptLong;
+
+void bc_opt_init(BcOpt *o, char **argv);
+
+int bc_opt_parse(BcOpt *o, const BcOptLong *longopts);
+
+#define BC_OPT_ISDASHDASH(a) \
+ ((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] == '\0')
+
+#define BC_OPT_ISSHORTOPT(a) \
+ ((a) != NULL && (a)[0] == '-' && (a)[1] != '-' && (a)[1] != '\0')
+
+#define BC_OPT_ISLONGOPT(a) \
+ ((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] != '\0')
+
+#endif // BC_OPT_H
diff --git a/contrib/bc/include/parse.h b/contrib/bc/include/parse.h
new file mode 100644
index 000000000000..7f59885346dc
--- /dev/null
+++ b/contrib/bc/include/parse.h
@@ -0,0 +1,117 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 bc's parser.
+ *
+ */
+
+#ifndef BC_PARSE_H
+#define BC_PARSE_H
+
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <status.h>
+#include <vector.h>
+#include <lex.h>
+#include <lang.h>
+
+#define BC_PARSE_REL (UINTMAX_C(1)<<0)
+#define BC_PARSE_PRINT (UINTMAX_C(1)<<1)
+#define BC_PARSE_NOCALL (UINTMAX_C(1)<<2)
+#define BC_PARSE_NOREAD (UINTMAX_C(1)<<3)
+#define BC_PARSE_ARRAY (UINTMAX_C(1)<<4)
+#define BC_PARSE_NEEDVAL (UINTMAX_C(1)<<5)
+
+#if BC_ENABLED
+#define BC_PARSE_CAN_PARSE(p) \
+ ((p).l.t != BC_LEX_EOF && (p).l.t != BC_LEX_KW_DEFINE)
+#else // BC_ENABLED
+#define BC_PARSE_CAN_PARSE(p) ((p).l.t != BC_LEX_EOF)
+#endif // BC_ENABLED
+
+#define bc_parse_push(p, i) (bc_vec_pushByte(&(p)->func->code, (uchar) (i)))
+#define bc_parse_pushIndex(p, idx) (bc_vec_pushIndex(&(p)->func->code, (idx)))
+
+#define bc_parse_err(p, e) (bc_vm_handleError((e), (p)->l.line))
+#define bc_parse_verr(p, e, ...) \
+ (bc_vm_handleError((e), (p)->l.line, __VA_ARGS__))
+
+typedef struct BcParseNext {
+ uchar len;
+ uchar tokens[4];
+} BcParseNext;
+
+#define BC_PARSE_NEXT_TOKENS(...) .tokens = { __VA_ARGS__ }
+#define BC_PARSE_NEXT(a, ...) \
+ { .len = (uchar) (a), BC_PARSE_NEXT_TOKENS(__VA_ARGS__) }
+
+struct BcParse;
+struct BcProgram;
+
+typedef void (*BcParseParse)(struct BcParse*);
+typedef void (*BcParseExpr)(struct BcParse*, uint8_t);
+
+typedef struct BcParse {
+
+ BcLex l;
+
+#if BC_ENABLED
+ BcVec flags;
+ BcVec exits;
+ BcVec conds;
+ BcVec ops;
+ BcVec buf;
+#endif // BC_ENABLED
+
+ struct BcProgram *prog;
+ BcFunc *func;
+ size_t fidx;
+
+ bool auto_part;
+
+} BcParse;
+
+void bc_parse_init(BcParse *p, struct BcProgram *prog, size_t func);
+void bc_parse_free(BcParse *p);
+void bc_parse_reset(BcParse *p);
+
+void bc_parse_addString(BcParse *p);
+void bc_parse_number(BcParse *p);
+void bc_parse_updateFunc(BcParse *p, size_t fidx);
+void bc_parse_pushName(const BcParse* p, char *name, bool var);
+void bc_parse_text(BcParse *p, const char *text);
+
+extern const char bc_parse_zero[2];
+extern const char bc_parse_one[2];
+
+#endif // BC_PARSE_H
diff --git a/contrib/bc/include/program.h b/contrib/bc/include/program.h
new file mode 100644
index 000000000000..a9805fbfb316
--- /dev/null
+++ b/contrib/bc/include/program.h
@@ -0,0 +1,187 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 bc programs.
+ *
+ */
+
+#ifndef BC_PROGRAM_H
+#define BC_PROGRAM_H
+
+#include <stddef.h>
+
+#include <status.h>
+#include <parse.h>
+#include <lang.h>
+#include <num.h>
+#include <rand.h>
+
+#define BC_PROG_GLOBALS_IBASE (0)
+#define BC_PROG_GLOBALS_OBASE (1)
+#define BC_PROG_GLOBALS_SCALE (2)
+
+#if BC_ENABLE_EXTRA_MATH
+#define BC_PROG_MAX_RAND (3)
+#endif // BC_ENABLE_EXTRA_MATH
+
+#define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)
+
+#define BC_PROG_ONE_CAP (1)
+
+typedef struct BcProgram {
+
+ BcBigDig globals[BC_PROG_GLOBALS_LEN];
+ BcVec globals_v[BC_PROG_GLOBALS_LEN];
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BcRNG rng;
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+ BcVec results;
+ BcVec stack;
+
+ BcVec *consts;
+ BcVec *strs;
+
+ BcVec fns;
+ BcVec fn_map;
+
+ BcVec vars;
+ BcVec var_map;
+
+ BcVec arrs;
+ BcVec arr_map;
+
+#if DC_ENABLED
+ BcVec strs_v;
+
+ BcVec tail_calls;
+
+ BcBigDig strm;
+ BcNum strmb;
+#endif // DC_ENABLED
+
+ BcNum zero;
+ BcNum one;
+
+#if BC_ENABLED
+ BcNum last;
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+ // This uses BC_NUM_LONG_LOG10 because it is used in bc_num_ulong2num(),
+ // which attempts to realloc, unless it is big enough. This is big enough.
+ BcDig strmb_num[BC_NUM_BIGDIG_LOG10];
+#endif // DC_ENABLED
+
+ BcDig zero_num[BC_PROG_ONE_CAP];
+ BcDig one_num[BC_PROG_ONE_CAP];
+
+} BcProgram;
+
+#define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
+
+#define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
+#define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
+
+#define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
+#define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
+#define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
+
+#define BC_PROG_MAIN (0)
+#define BC_PROG_READ (1)
+
+#define bc_program_retire(p, nres, nops) \
+ (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops)))
+
+#if DC_ENABLED
+#define BC_PROG_REQ_FUNCS (2)
+#if !BC_ENABLED
+// For dc only, last is always true.
+#define bc_program_copyToVar(p, name, t, last) \
+ bc_program_copyToVar(p, name, t)
+#endif // !BC_ENABLED
+#else // DC_ENABLED
+// For bc, 'pop' and 'copy' are always false.
+#define bc_program_pushVar(p, code, bgn, pop, copy) \
+ bc_program_pushVar(p, code, bgn)
+#ifdef NDEBUG
+#define BC_PROG_NO_STACK_CHECK
+#endif // NDEBUG
+#endif // DC_ENABLED
+
+#define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
+#if BC_ENABLED
+#define BC_PROG_NUM(r, n) \
+ ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
+#else // BC_ENABLED
+#define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
+// For dc, inst is always BC_INST_ARRAY_ELEM.
+#define bc_program_pushArray(p, code, bgn, inst) \
+ bc_program_pushArray(p, code, bgn)
+#endif // BC_ENABLED
+
+typedef void (*BcProgramUnary)(BcResult*, BcNum*);
+
+void bc_program_init(BcProgram *p);
+void bc_program_free(BcProgram *p);
+
+#if BC_DEBUG_CODE
+#if BC_ENABLED && DC_ENABLED
+void bc_program_code(const BcProgram *p);
+void bc_program_printInst(const BcProgram *p, const char *code,
+ size_t *restrict bgn);
+void bc_program_printStackDebug(BcProgram* p);
+#endif // BC_ENABLED && DC_ENABLED
+#endif // BC_DEBUG_CODE
+
+size_t bc_program_search(BcProgram *p, const char* id, bool var);
+size_t bc_program_insertFunc(BcProgram *p, const char *name);
+void bc_program_reset(BcProgram *p);
+void bc_program_exec(BcProgram *p);
+
+void bc_program_negate(BcResult *r, BcNum *n);
+void bc_program_not(BcResult *r, BcNum *n);
+#if BC_ENABLE_EXTRA_MATH
+void bc_program_trunc(BcResult *r, BcNum *n);
+#endif // BC_ENABLE_EXTRA_MATH
+
+extern const BcNumBinaryOp bc_program_ops[];
+extern const BcNumBinaryOpReq bc_program_opReqs[];
+extern const BcProgramUnary bc_program_unarys[];
+extern const char bc_program_exprs_name[];
+extern const char bc_program_stdin_name[];
+extern const char bc_program_ready_msg[];
+extern const size_t bc_program_ready_msg_len;
+extern const char bc_program_esc_chars[];
+extern const char bc_program_esc_seqs[];
+
+#endif // BC_PROGRAM_H
diff --git a/contrib/bc/include/rand.h b/contrib/bc/include/rand.h
new file mode 100644
index 000000000000..a2fb713803ee
--- /dev/null
+++ b/contrib/bc/include/rand.h
@@ -0,0 +1,234 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2019 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.
+ *
+ * *****************************************************************************
+ *
+ * Parts of this code are adapted from the following:
+ *
+ * PCG, A Family of Better Random Number Generators.
+ *
+ * You can find the original source code at:
+ * https://github.com/imneme/pcg-c
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Parts of this code are also under the following license:
+ *
+ * Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for the RNG.
+ *
+ */
+
+#ifndef BC_RAND_H
+#define BC_RAND_H
+
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <vector.h>
+#include <num.h>
+
+#if BC_ENABLE_EXTRA_MATH
+
+#if BC_ENABLE_RAND
+
+typedef ulong (*BcRandUlong)(void*);
+
+#if BC_LONG_BIT >= 64
+
+#ifdef BC_RAND_BUILTIN
+#if BC_RAND_BUILTIN
+#ifndef __SIZEOF_INT128__
+#undef BC_RAND_BUILTIN
+#define BC_RAND_BUILTIN (0)
+#endif // __SIZEOF_INT128__
+#endif // BC_RAND_BUILTIN
+#endif // BC_RAND_BUILTIN
+
+#ifndef BC_RAND_BUILTIN
+#ifdef __SIZEOF_INT128__
+#define BC_RAND_BUILTIN (1)
+#else // __SIZEOF_INT128__
+#define BC_RAND_BUILTIN (0)
+#endif // __SIZEOF_INT128__
+#endif // BC_RAND_BUILTIN
+
+typedef uint64_t BcRand;
+
+#define BC_RAND_ROTC (63)
+
+#if BC_RAND_BUILTIN
+
+typedef __uint128_t BcRandState;
+
+#define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+#define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+#define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+#define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+#define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
+#define BC_RAND_ZERO(r) (!(r)->state)
+
+#define BC_RAND_CONSTANT(h, l) ((((BcRandState) (h)) << 64) + (BcRandState) (l))
+
+#define BC_RAND_TRUNC(s) ((uint64_t) (s))
+#define BC_RAND_CHOP(s) ((uint64_t) ((s) >> 64UL))
+#define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 122UL))
+
+#else // BC_RAND_BUILTIN
+
+typedef struct BcRandState {
+
+ uint_fast64_t lo;
+ uint_fast64_t hi;
+
+} BcRandState;
+
+#define bc_rand_mul(a, b) (bc_rand_multiply((a), (b)))
+#define bc_rand_add(a, b) (bc_rand_addition((a), (b)))
+
+#define bc_rand_mul2(a, b) (bc_rand_multiply2((a), (b)))
+#define bc_rand_add2(a, b) (bc_rand_addition2((a), (b)))
+
+#define BC_RAND_NOTMODIFIED(r) (((r)->inc.lo & 1) == 0)
+#define BC_RAND_ZERO(r) (!(r)->state.lo && !(r)->state.hi)
+
+#define BC_RAND_CONSTANT(h, l) { .lo = (l), .hi = (h) }
+
+#define BC_RAND_TRUNC(s) ((s).lo)
+#define BC_RAND_CHOP(s) ((s).hi)
+#define BC_RAND_ROTAMT(s) ((unsigned int) ((s).hi >> 58UL))
+
+#define BC_RAND_BOTTOM32 (((uint_fast64_t) 0xffffffffULL))
+#define BC_RAND_TRUNC32(n) ((n) & BC_RAND_BOTTOM32)
+#define BC_RAND_CHOP32(n) ((n) >> 32)
+
+#endif // BC_RAND_BUILTIN
+
+#define BC_RAND_MULTIPLIER \
+ BC_RAND_CONSTANT(2549297995355413924ULL, 4865540595714422341ULL)
+
+#define BC_RAND_FOLD(s) ((BcRand) (BC_RAND_CHOP(s) ^ BC_RAND_TRUNC(s)))
+
+#else // BC_LONG_BIT >= 64
+
+#undef BC_RAND_BUILTIN
+#define BC_RAND_BUILTIN (1)
+
+typedef uint32_t BcRand;
+
+#define BC_RAND_ROTC (31)
+
+typedef uint_fast64_t BcRandState;
+
+#define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+#define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+#define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+#define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+#define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
+#define BC_RAND_ZERO(r) (!(r)->state)
+
+#define BC_RAND_CONSTANT UINT64_C
+#define BC_RAND_MULTIPLIER BC_RAND_CONSTANT(6364136223846793005)
+
+#define BC_RAND_TRUNC(s) ((uint32_t) (s))
+#define BC_RAND_CHOP(s) ((uint32_t) ((s) >> 32UL))
+#define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 59UL))
+
+#define BC_RAND_FOLD(s) ((BcRand) ((((s) >> 18U) ^ (s)) >> 27U))
+
+#endif // BC_LONG_BIT >= 64
+
+#define BC_RAND_ROT(v, r) \
+ ((BcRand) (((v) >> (r)) | ((v) << ((0 - (r)) & BC_RAND_ROTC))))
+
+#define BC_RAND_BITS (sizeof(BcRand) * CHAR_BIT)
+#define BC_RAND_STATE_BITS (sizeof(BcRandState) * CHAR_BIT)
+
+#define BC_RAND_NUM_SIZE (BC_NUM_BIGDIG_LOG10 * 2 + 2)
+
+#define BC_RAND_SRAND_BITS ((1 << CHAR_BIT) - 1)
+
+typedef struct BcRNGData {
+
+ BcRandState state;
+ BcRandState inc;
+
+} BcRNGData;
+
+typedef struct BcRNG {
+
+ BcVec v;
+
+} BcRNG;
+
+void bc_rand_init(BcRNG *r);
+#ifndef NDEBUG
+void bc_rand_free(BcRNG *r);
+#endif // NDEBUG
+
+BcRand bc_rand_int(BcRNG *r);
+BcRand bc_rand_bounded(BcRNG *r, BcRand bound);
+void bc_rand_seed(BcRNG *r, ulong state1, ulong state2, ulong inc1, ulong inc2);
+void bc_rand_push(BcRNG *r);
+void bc_rand_pop(BcRNG *r, bool reset);
+void bc_rand_getRands(BcRNG *r, BcRand *s1, BcRand *s2, BcRand *i1, BcRand *i2);
+void bc_rand_srand(BcRNGData *rng);
+
+extern const BcRandState bc_rand_multiplier;
+
+#endif // BC_ENABLE_RAND
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+#endif // BC_RAND_H
diff --git a/contrib/bc/include/read.h b/contrib/bc/include/read.h
new file mode 100644
index 000000000000..664ff983e522
--- /dev/null
+++ b/contrib/bc/include/read.h
@@ -0,0 +1,60 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code to handle special I/O for bc.
+ *
+ */
+
+#ifndef BC_READ_H
+#define BC_READ_H
+
+#include <stdlib.h>
+
+#include <status.h>
+#include <vector.h>
+
+#ifndef BC_ENABLE_PROMPT
+#define BC_ENABLE_PROMPT (1)
+#endif // BC_ENABLE_PROMPT
+
+#if !BC_ENABLE_PROMPT
+#define bc_read_line(vec, prompt) bc_read_line(vec)
+#define bc_read_chars(vec, prompt) bc_read_chars(vec)
+#endif // BC_ENABLE_PROMPT
+
+#define BC_READ_BIN_CHAR(c) (((c) < ' ' && !isspace((c))) || ((uchar) c) > '~')
+
+BcStatus bc_read_line(BcVec *vec, const char *prompt);
+void bc_read_file(const char *path, char **buf);
+BcStatus bc_read_chars(BcVec *vec, const char *prompt);
+bool bc_read_buf(BcVec *vec, char *buf, size_t *buf_len);
+
+#endif // BC_READ_H
diff --git a/contrib/bc/include/status.h b/contrib/bc/include/status.h
new file mode 100644
index 000000000000..2807a28af4ef
--- /dev/null
+++ b/contrib/bc/include/status.h
@@ -0,0 +1,198 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * All bc status codes.
+ *
+ */
+
+#ifndef BC_STATUS_H
+#define BC_STATUS_H
+
+#include <stdint.h>
+
+#ifndef BC_ENABLED
+#define BC_ENABLED (1)
+#endif // BC_ENABLED
+
+#ifndef DC_ENABLED
+#define DC_ENABLED (1)
+#endif // DC_ENABLED
+
+#include <bcl.h>
+
+typedef enum BcStatus {
+
+ BC_STATUS_SUCCESS = 0,
+ BC_STATUS_ERROR_MATH,
+ BC_STATUS_ERROR_PARSE,
+ BC_STATUS_ERROR_EXEC,
+ BC_STATUS_ERROR_FATAL,
+ BC_STATUS_EOF,
+ BC_STATUS_QUIT,
+
+} BcStatus;
+
+typedef enum BcErr {
+
+ BC_ERR_MATH_NEGATIVE,
+ BC_ERR_MATH_NON_INTEGER,
+ BC_ERR_MATH_OVERFLOW,
+ BC_ERR_MATH_DIVIDE_BY_ZERO,
+
+ BC_ERR_FATAL_ALLOC_ERR,
+ BC_ERR_FATAL_IO_ERR,
+ BC_ERR_FATAL_FILE_ERR,
+ BC_ERR_FATAL_BIN_FILE,
+ BC_ERR_FATAL_PATH_DIR,
+ BC_ERR_FATAL_OPTION,
+ BC_ERR_FATAL_OPTION_NO_ARG,
+ BC_ERR_FATAL_OPTION_ARG,
+
+ BC_ERR_EXEC_IBASE,
+ BC_ERR_EXEC_OBASE,
+ BC_ERR_EXEC_SCALE,
+ BC_ERR_EXEC_READ_EXPR,
+ BC_ERR_EXEC_REC_READ,
+ BC_ERR_EXEC_TYPE,
+
+ BC_ERR_EXEC_STACK,
+
+ BC_ERR_EXEC_PARAMS,
+ BC_ERR_EXEC_UNDEF_FUNC,
+ BC_ERR_EXEC_VOID_VAL,
+
+ BC_ERR_PARSE_EOF,
+ BC_ERR_PARSE_CHAR,
+ BC_ERR_PARSE_STRING,
+ BC_ERR_PARSE_COMMENT,
+ BC_ERR_PARSE_TOKEN,
+#if BC_ENABLED
+ BC_ERR_PARSE_EXPR,
+ BC_ERR_PARSE_EMPTY_EXPR,
+ BC_ERR_PARSE_PRINT,
+ BC_ERR_PARSE_FUNC,
+ BC_ERR_PARSE_ASSIGN,
+ BC_ERR_PARSE_NO_AUTO,
+ BC_ERR_PARSE_DUP_LOCAL,
+ BC_ERR_PARSE_BLOCK,
+ BC_ERR_PARSE_RET_VOID,
+ BC_ERR_PARSE_REF_VAR,
+
+ BC_ERR_POSIX_NAME_LEN,
+ BC_ERR_POSIX_COMMENT,
+ BC_ERR_POSIX_KW,
+ BC_ERR_POSIX_DOT,
+ BC_ERR_POSIX_RET,
+ BC_ERR_POSIX_BOOL,
+ BC_ERR_POSIX_REL_POS,
+ BC_ERR_POSIX_MULTIREL,
+ BC_ERR_POSIX_FOR,
+ BC_ERR_POSIX_EXP_NUM,
+ BC_ERR_POSIX_REF,
+ BC_ERR_POSIX_VOID,
+ BC_ERR_POSIX_BRACE,
+#endif // BC_ENABLED
+
+ BC_ERR_NELEMS,
+
+#if BC_ENABLED
+ BC_ERR_POSIX_START = BC_ERR_POSIX_NAME_LEN,
+ BC_ERR_POSIX_END = BC_ERR_POSIX_BRACE,
+#endif // BC_ENABLED
+
+} BcErr;
+
+#define BC_ERR_IDX_MATH (0)
+#define BC_ERR_IDX_PARSE (1)
+#define BC_ERR_IDX_EXEC (2)
+#define BC_ERR_IDX_FATAL (3)
+#define BC_ERR_IDX_NELEMS (4)
+
+#if BC_ENABLED
+#define BC_ERR_IDX_WARN (BC_ERR_IDX_NELEMS)
+#endif // BC_ENABLED
+
+#define BC_UNUSED(e) ((void) (e))
+
+#ifndef BC_LIKELY
+#define BC_LIKELY(e) (e)
+#endif // BC_LIKELY
+
+#ifndef BC_UNLIKELY
+#define BC_UNLIKELY(e) (e)
+#endif // BC_UNLIKELY
+
+#define BC_ERR(e) BC_UNLIKELY(e)
+#define BC_NO_ERR(s) BC_LIKELY(s)
+
+#ifndef BC_DEBUG_CODE
+#define BC_DEBUG_CODE (0)
+#endif // BC_DEBUG_CODE
+
+#if __STDC_VERSION__ >= 201100L
+#include <stdnoreturn.h>
+#define BC_NORETURN _Noreturn
+#else // __STDC_VERSION__
+#define BC_NORETURN
+#define BC_MUST_RETURN
+#endif // __STDC_VERSION__
+
+#if defined(__clang__) || defined(__GNUC__)
+#if defined(__has_attribute) && __has_attribute(fallthrough)
+#define BC_FALLTHROUGH __attribute__((fallthrough));
+#else // defined(__has_attribute) && __has_attribute(fallthrough)
+#define BC_FALLTHROUGH
+#endif // defined(__has_attribute) && __has_attribute(fallthrough)
+#else // defined(__clang__) || defined(__GNUC__)
+#define BC_FALLTHROUGH
+#endif //defined(__clang__) || defined(__GNUC__)
+
+// Workarounds for AIX's POSIX incompatibility.
+#ifndef SIZE_MAX
+#define SIZE_MAX __SIZE_MAX__
+#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/contrib/bc/include/vector.h b/contrib/bc/include/vector.h
new file mode 100644
index 000000000000..fdfb85d58228
--- /dev/null
+++ b/contrib/bc/include/vector.h
@@ -0,0 +1,102 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 bc vectors (resizable arrays).
+ *
+ */
+
+#ifndef BC_VECTOR_H
+#define BC_VECTOR_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <status.h>
+
+#define BC_VEC_INVALID_IDX (SIZE_MAX)
+#define BC_VEC_START_CAP (UINTMAX_C(1)<<5)
+
+typedef unsigned char uchar;
+
+typedef void (*BcVecFree)(void*);
+
+// Forward declaration.
+struct BcId;
+
+typedef struct BcVec {
+ char *v;
+ size_t len;
+ size_t cap;
+ size_t size;
+ BcVecFree dtor;
+} BcVec;
+
+void bc_vec_init(BcVec *restrict v, size_t esize, BcVecFree dtor);
+void bc_vec_expand(BcVec *restrict v, size_t req);
+void bc_vec_grow(BcVec *restrict v, size_t n);
+
+void bc_vec_npop(BcVec *restrict v, size_t n);
+void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx);
+
+void bc_vec_push(BcVec *restrict v, const void *data);
+void bc_vec_npush(BcVec *restrict v, size_t n, const void *data);
+void bc_vec_pushByte(BcVec *restrict v, uchar data);
+void bc_vec_pushIndex(BcVec *restrict v, size_t idx);
+void bc_vec_string(BcVec *restrict v, size_t len, const char *restrict str);
+void bc_vec_concat(BcVec *restrict v, const char *restrict str);
+void bc_vec_empty(BcVec *restrict v);
+
+#if BC_ENABLE_HISTORY
+void bc_vec_replaceAt(BcVec *restrict v, size_t idx, const void *data);
+#endif // BC_ENABLE_HISTORY
+
+void* bc_vec_item(const BcVec *restrict v, size_t idx);
+void* bc_vec_item_rev(const BcVec *restrict v, size_t idx);
+
+void bc_vec_clear(BcVec *restrict v);
+
+void bc_vec_free(void *vec);
+
+bool bc_map_insert(BcVec *restrict v, const char *name,
+ size_t idx, size_t *restrict i);
+size_t bc_map_index(const BcVec *restrict v, const char *name);
+
+#define bc_vec_pop(v) (bc_vec_npop((v), 1))
+#define bc_vec_top(v) (bc_vec_item_rev((v), 0))
+
+#ifndef NDEBUG
+#define bc_map_init(v) (bc_vec_init((v), sizeof(BcId), bc_id_free))
+#else // NDEBUG
+#define bc_map_init(v) (bc_vec_init((v), sizeof(BcId), NULL))
+#endif // NDEBUG
+
+#endif // BC_VECTOR_H
diff --git a/contrib/bc/include/vm.h b/contrib/bc/include/vm.h
new file mode 100644
index 000000000000..72a5150266a1
--- /dev/null
+++ b/contrib/bc/include/vm.h
@@ -0,0 +1,453 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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 bc's VM.
+ *
+ */
+
+#ifndef BC_VM_H
+#define BC_VM_H
+
+#include <assert.h>
+#include <stddef.h>
+#include <limits.h>
+
+#include <signal.h>
+
+#if BC_ENABLE_NLS
+
+# ifdef _WIN32
+# error NLS is not supported on Windows.
+# endif // _WIN32
+
+#include <nl_types.h>
+
+#endif // BC_ENABLE_NLS
+
+#include <status.h>
+#include <num.h>
+#include <parse.h>
+#include <program.h>
+#include <history.h>
+
+#if !BC_ENABLE_LIBRARY
+#include <file.h>
+#endif // !BC_ENABLE_LIBRARY
+
+#if !BC_ENABLED && !DC_ENABLED
+#error Must define BC_ENABLED, DC_ENABLED, or both
+#endif
+
+// CHAR_BIT must be at least 6.
+#if CHAR_BIT < 6
+#error CHAR_BIT must be at least 6.
+#endif
+
+#ifndef BC_ENABLE_NLS
+#define BC_ENABLE_NLS (0)
+#endif // BC_ENABLE_NLS
+
+#ifndef MAINEXEC
+#define MAINEXEC bc
+#endif
+
+#ifndef EXECPREFIX
+#define EXECPREFIX
+#endif
+
+#define GEN_STR(V) #V
+#define GEN_STR2(V) GEN_STR(V)
+
+#define BC_VERSION GEN_STR2(VERSION)
+#define BC_EXECPREFIX GEN_STR2(EXECPREFIX)
+#define BC_MAINEXEC GEN_STR2(MAINEXEC)
+
+// Windows has deprecated isatty().
+#ifdef _WIN32
+#define isatty _isatty
+#endif // _WIN32
+
+#if !BC_ENABLE_LIBRARY
+
+#if DC_ENABLED
+#define DC_FLAG_X (UINTMAX_C(1)<<0)
+#endif // DC_ENABLED
+
+#if BC_ENABLED
+#define BC_FLAG_W (UINTMAX_C(1)<<1)
+#define BC_FLAG_S (UINTMAX_C(1)<<2)
+#define BC_FLAG_L (UINTMAX_C(1)<<3)
+#define BC_FLAG_G (UINTMAX_C(1)<<4)
+#endif // BC_ENABLED
+
+#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_TTYIN (vm.flags & BC_FLAG_TTYIN)
+#define BC_TTY (vm.flags & BC_FLAG_TTY)
+
+#if BC_ENABLED
+
+#define BC_S (vm.flags & BC_FLAG_S)
+#define BC_W (vm.flags & BC_FLAG_W)
+#define BC_L (vm.flags & BC_FLAG_L)
+#define BC_G (vm.flags & BC_FLAG_G)
+
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+#define DC_X (vm.flags & DC_FLAG_X)
+#endif // DC_ENABLED
+
+#define BC_I (vm.flags & BC_FLAG_I)
+#define BC_P (vm.flags & BC_FLAG_P)
+
+#if BC_ENABLED
+
+#define BC_IS_POSIX (BC_S || BC_W)
+
+#if DC_ENABLED
+#define BC_IS_BC (vm.name[0] != 'd')
+#define BC_IS_DC (vm.name[0] == 'd')
+#else // DC_ENABLED
+#define BC_IS_BC (1)
+#define BC_IS_DC (0)
+#endif // DC_ENABLED
+
+#else // BC_ENABLED
+#define BC_IS_POSIX (0)
+#define BC_IS_BC (0)
+#define BC_IS_DC (1)
+#endif // BC_ENABLED
+
+#if BC_ENABLED
+#define BC_USE_PROMPT (!BC_P && BC_TTY && !BC_IS_POSIX)
+#else // BC_ENABLED
+#define BC_USE_PROMPT (!BC_P && BC_TTY)
+#endif // BC_ENABLED
+
+#endif // !BC_ENABLE_LIBRARY
+
+#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+#define BC_MAX_OBASE ((BcBigDig) (BC_BASE_POW))
+#define BC_MAX_DIM ((BcBigDig) (SIZE_MAX - 1))
+#define BC_MAX_SCALE ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
+#define BC_MAX_STRING ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
+#define BC_MAX_NAME BC_MAX_STRING
+#define BC_MAX_NUM BC_MAX_SCALE
+
+#if BC_ENABLE_EXTRA_MATH
+#define BC_MAX_RAND ((BcBigDig) (((BcRand) 0) - 1))
+#endif // BC_ENABLE_EXTRA_MATH
+
+#define BC_MAX_EXP ((ulong) (BC_NUM_BIGDIG_MAX))
+#define BC_MAX_VARS ((ulong) (SIZE_MAX - 1))
+
+#if BC_DEBUG_CODE
+#define BC_VM_JMP bc_vm_jmp(__func__)
+#else // BC_DEBUG_CODE
+#define BC_VM_JMP bc_vm_jmp()
+#endif // BC_DEBUG_CODE
+
+#define BC_SIG_EXC \
+ BC_UNLIKELY(vm.status != (sig_atomic_t) BC_STATUS_SUCCESS || vm.sig)
+#define BC_NO_SIG_EXC \
+ BC_LIKELY(vm.status == (sig_atomic_t) BC_STATUS_SUCCESS && !vm.sig)
+
+#ifndef NDEBUG
+#define BC_SIG_ASSERT_LOCKED do { assert(vm.sig_lock); } while (0)
+#define BC_SIG_ASSERT_NOT_LOCKED do { assert(vm.sig_lock == 0); } while (0)
+#else // NDEBUG
+#define BC_SIG_ASSERT_LOCKED
+#define BC_SIG_ASSERT_NOT_LOCKED
+#endif // NDEBUG
+
+#define BC_SIG_LOCK \
+ do { \
+ BC_SIG_ASSERT_NOT_LOCKED; \
+ vm.sig_lock = 1; \
+ } while (0)
+
+#define BC_SIG_UNLOCK \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ vm.sig_lock = 0; \
+ if (BC_SIG_EXC) BC_VM_JMP; \
+ } while (0)
+
+#define BC_SIG_MAYLOCK \
+ do { \
+ vm.sig_lock = 1; \
+ } while (0)
+
+#define BC_SIG_MAYUNLOCK \
+ do { \
+ vm.sig_lock = 0; \
+ if (BC_SIG_EXC) BC_VM_JMP; \
+ } while (0)
+
+#define BC_SIG_TRYLOCK(v) \
+ do { \
+ v = vm.sig_lock; \
+ vm.sig_lock = 1; \
+ } while (0)
+
+#define BC_SIG_TRYUNLOCK(v) \
+ do { \
+ vm.sig_lock = (v); \
+ if (!(v) && BC_SIG_EXC) BC_VM_JMP; \
+ } while (0)
+
+#define BC_SETJMP(l) \
+ do { \
+ sigjmp_buf sjb; \
+ BC_SIG_LOCK; \
+ if (sigsetjmp(sjb, 0)) { \
+ assert(BC_SIG_EXC); \
+ goto l; \
+ } \
+ bc_vec_push(&vm.jmp_bufs, &sjb); \
+ BC_SIG_UNLOCK; \
+ } while (0)
+
+#define BC_SETJMP_LOCKED(l) \
+ do { \
+ sigjmp_buf sjb; \
+ BC_SIG_ASSERT_LOCKED; \
+ if (sigsetjmp(sjb, 0)) { \
+ assert(BC_SIG_EXC); \
+ goto l; \
+ } \
+ bc_vec_push(&vm.jmp_bufs, &sjb); \
+ } while (0)
+
+#define BC_LONGJMP_CONT \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ if (!vm.sig_pop) bc_vec_pop(&vm.jmp_bufs); \
+ BC_SIG_UNLOCK; \
+ } while (0)
+
+#define BC_UNSETJMP \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ bc_vec_pop(&vm.jmp_bufs); \
+ } while (0)
+
+#define BC_LONGJMP_STOP \
+ do { \
+ vm.sig_pop = 0; \
+ vm.sig = 0; \
+ } while (0)
+
+#define BC_VM_BUF_SIZE (1<<12)
+#define BC_VM_STDOUT_BUF_SIZE (1<<11)
+#define BC_VM_STDERR_BUF_SIZE (1<<10)
+#define BC_VM_STDIN_BUF_SIZE (BC_VM_STDERR_BUF_SIZE - 1)
+
+#define BC_VM_SAFE_RESULT(r) ((r)->t >= BC_RESULT_TEMP)
+
+#if BC_ENABLE_LIBRARY
+#define bc_vm_error(e, l, ...) (bc_vm_handleError((e)))
+#define bc_vm_err(e) (bc_vm_handleError((e)))
+#define bc_vm_verr(e, ...) (bc_vm_handleError((e)))
+#else // BC_ENABLE_LIBRARY
+#define bc_vm_error(e, l, ...) (bc_vm_handleError((e), (l), __VA_ARGS__))
+#define bc_vm_err(e) (bc_vm_handleError((e), 0))
+#define bc_vm_verr(e, ...) (bc_vm_handleError((e), 0, __VA_ARGS__))
+#endif // BC_ENABLE_LIBRARY
+
+#define BC_STATUS_IS_ERROR(s) \
+ ((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL)
+
+#define BC_VM_INVALID_CATALOG ((nl_catd) -1)
+
+#if BC_DEBUG_CODE
+#define BC_VM_FUNC_ENTER \
+ do { \
+ bc_file_printf(&vm.ferr, "Entering %s\n", __func__); \
+ bc_file_flush(&vm.ferr); \
+ } while (0);
+
+#define BC_VM_FUNC_EXIT \
+ do { \
+ bc_file_printf(&vm.ferr, "Leaving %s\n", __func__); \
+ bc_file_flush(&vm.ferr); \
+ } while (0);
+#else // BC_DEBUG_CODE
+#define BC_VM_FUNC_ENTER
+#define BC_VM_FUNC_EXIT
+#endif // BC_DEBUG_CODE
+
+typedef struct BcVm {
+
+ volatile sig_atomic_t status;
+ volatile sig_atomic_t sig_pop;
+
+#if !BC_ENABLE_LIBRARY
+ BcParse prs;
+ BcProgram prog;
+#endif // BC_ENABLE_LIBRARY
+
+ BcVec jmp_bufs;
+
+ BcVec temps;
+
+#if BC_ENABLE_LIBRARY
+
+ BcVec ctxts;
+ BcVec out;
+
+ BcRNG rng;
+
+ BclError err;
+ bool abrt;
+
+ unsigned int refs;
+
+ volatile sig_atomic_t running;
+#endif // BC_ENABLE_LIBRARY
+
+#if !BC_ENABLE_LIBRARY
+ const char* file;
+
+ const char *sigmsg;
+#endif // BC_ENABLE_LIBRARY
+ volatile sig_atomic_t sig_lock;
+ volatile sig_atomic_t sig;
+#if !BC_ENABLE_LIBRARY
+ uchar siglen;
+
+ uchar read_ret;
+ uint16_t flags;
+
+ uint16_t nchars;
+ uint16_t line_len;
+
+ bool no_exit_exprs;
+ bool eof;
+#endif // BC_ENABLE_LIBRARY
+
+ BcBigDig maxes[BC_PROG_GLOBALS_LEN + BC_ENABLE_EXTRA_MATH];
+
+#if !BC_ENABLE_LIBRARY
+ BcVec files;
+ BcVec exprs;
+
+ const char *name;
+ const char *help;
+
+#if BC_ENABLE_HISTORY
+ BcHistory history;
+#endif // BC_ENABLE_HISTORY
+
+ BcLexNext next;
+ BcParseParse parse;
+ BcParseExpr expr;
+
+ const char *func_header;
+
+ const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED];
+ const char *err_msgs[BC_ERR_NELEMS];
+
+ const char *locale;
+#endif // BC_ENABLE_LIBRARY
+
+ BcBigDig last_base;
+ BcBigDig last_pow;
+ BcBigDig last_exp;
+ BcBigDig last_rem;
+
+#if !BC_ENABLE_LIBRARY
+ char *env_args_buffer;
+ BcVec env_args;
+#endif // BC_ENABLE_LIBRARY
+
+ BcNum max;
+ BcNum max2;
+ BcDig max_num[BC_NUM_BIGDIG_LOG10];
+ BcDig max2_num[BC_NUM_BIGDIG_LOG10];
+
+#if !BC_ENABLE_LIBRARY
+ BcFile fout;
+ BcFile ferr;
+
+#if BC_ENABLE_NLS
+ nl_catd catalog;
+#endif // BC_ENABLE_NLS
+
+ char *buf;
+ size_t buf_len;
+#endif // !BC_ENABLE_LIBRARY
+
+} BcVm;
+
+void bc_vm_info(const char* const help);
+void bc_vm_boot(int argc, char *argv[], const char *env_len,
+ const char* const env_args);
+void bc_vm_init(void);
+void bc_vm_shutdown(void);
+void bc_vm_freeTemps(void);
+
+void bc_vm_printf(const char *fmt, ...);
+void bc_vm_putchar(int c);
+size_t bc_vm_arraySize(size_t n, size_t size);
+size_t bc_vm_growSize(size_t a, size_t b);
+void* bc_vm_malloc(size_t n);
+void* bc_vm_realloc(void *ptr, size_t n);
+char* bc_vm_strdup(const char *str);
+
+#if BC_DEBUG_CODE
+void bc_vm_jmp(const char *f);
+#else // BC_DEBUG_CODE
+void bc_vm_jmp(void);
+#endif // BC_DEBUG_CODE
+
+#if BC_ENABLE_LIBRARY
+void bc_vm_handleError(BcErr e);
+#else // BC_ENABLE_LIBRARY
+void bc_vm_handleError(BcErr e, size_t line, ...);
+#endif // BC_ENABLE_LIBRARY
+
+extern const char bc_copyright[];
+extern const char* const bc_err_line;
+extern const char* const bc_err_func_header;
+extern const char *bc_errs[];
+extern const uchar bc_err_ids[];
+extern const char* const bc_err_msgs[];
+
+extern BcVm vm;
+extern char output_bufs[BC_VM_BUF_SIZE];
+
+#endif // BC_VM_H
diff --git a/contrib/bc/karatsuba.py b/contrib/bc/karatsuba.py
new file mode 100755
index 000000000000..a3cc8e6eed40
--- /dev/null
+++ b/contrib/bc/karatsuba.py
@@ -0,0 +1,232 @@
+#! /usr/bin/python3 -B
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+import os
+import sys
+import subprocess
+import time
+
+def usage():
+ print("usage: {} [num_iterations test_num exe]".format(script))
+ print("\n num_iterations is the number of times to run each karatsuba number; default is 4")
+ print("\n test_num is the last Karatsuba number to run through tests")
+ sys.exit(1)
+
+def run(cmd, env=None):
+ return subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
+
+script = sys.argv[0]
+testdir = os.path.dirname(script)
+
+if testdir == "":
+ testdir = os.getcwd()
+
+print("\nWARNING: This script is for distro and package maintainers.")
+print("It is for finding the optimal Karatsuba number.")
+print("Though it only needs to be run once per release/platform,")
+print("it takes forever to run.")
+print("You have been warned.\n")
+print("Note: If you send an interrupt, it will report the current best number.\n")
+
+if __name__ != "__main__":
+ usage()
+
+mx = 520
+mx2 = mx // 2
+mn = 16
+
+num = "9" * mx
+
+args_idx = 4
+
+if len(sys.argv) >= 2:
+ num_iterations = int(sys.argv[1])
+else:
+ num_iterations = 4
+
+if len(sys.argv) >= 3:
+ test_num = int(sys.argv[2])
+else:
+ test_num = 0
+
+if len(sys.argv) >= args_idx:
+ exe = sys.argv[3]
+else:
+ exe = testdir + "/bin/bc"
+
+exedir = os.path.dirname(exe)
+
+indata = "for (i = 0; i < 100; ++i) {} * {}\n"
+indata += "1.23456789^100000\n1.23456789^100000\nhalt"
+indata = indata.format(num, num).encode()
+
+times = []
+nums = []
+runs = []
+nruns = num_iterations + 1
+
+for i in range(0, nruns):
+ runs.append(0)
+
+tests = [ "multiply", "modulus", "power", "sqrt" ]
+scripts = [ "multiply" ]
+
+print("Testing CFLAGS=\"-flto\"...")
+
+flags = dict(os.environ)
+try:
+ flags["CFLAGS"] = flags["CFLAGS"] + " " + "-flto"
+except KeyError:
+ flags["CFLAGS"] = "-flto"
+
+p = run([ "./configure.sh", "-O3" ], flags)
+if p.returncode != 0:
+ print("configure.sh returned an error ({}); exiting...".format(p.returncode))
+ sys.exit(p.returncode)
+
+p = run([ "make" ])
+
+if p.returncode == 0:
+ config_env = flags
+ print("Using CFLAGS=\"-flto\"")
+else:
+ config_env = os.environ
+ print("Not using CFLAGS=\"-flto\"")
+
+p = run([ "make", "clean" ])
+
+print("Testing \"make -j4\"")
+
+if p.returncode != 0:
+ print("make returned an error ({}); exiting...".format(p.returncode))
+ sys.exit(p.returncode)
+
+p = run([ "make", "-j4" ])
+
+if p.returncode == 0:
+ makecmd = [ "make", "-j4" ]
+ print("Using \"make -j4\"")
+else:
+ makecmd = [ "make" ]
+ print("Not using \"make -j4\"")
+
+if test_num != 0:
+ mx2 = test_num
+
+try:
+
+ for i in range(mn, mx2 + 1):
+
+ print("\nCompiling...\n")
+
+ p = run([ "./configure.sh", "-O3", "-k{}".format(i) ], config_env)
+
+ if p.returncode != 0:
+ print("configure.sh returned an error ({}); exiting...".format(p.returncode))
+ sys.exit(p.returncode)
+
+ p = run(makecmd)
+
+ if p.returncode != 0:
+ print("make returned an error ({}); exiting...".format(p.returncode))
+ sys.exit(p.returncode)
+
+ if (test_num >= i):
+
+ print("Running tests for Karatsuba Num: {}\n".format(i))
+
+ for test in tests:
+
+ cmd = [ "{}/tests/test.sh".format(testdir), "bc", test, "0", "0", exe ]
+
+ p = subprocess.run(cmd + sys.argv[args_idx:], stderr=subprocess.PIPE)
+
+ if p.returncode != 0:
+ print("{} test failed:\n".format(test, p.returncode))
+ print(p.stderr.decode())
+ print("\nexiting...")
+ sys.exit(p.returncode)
+
+ print("")
+
+ for script in scripts:
+
+ cmd = [ "{}/tests/script.sh".format(testdir), "bc", script + ".bc",
+ "0", "1", "1", "0", exe ]
+
+ p = subprocess.run(cmd + sys.argv[args_idx:], stderr=subprocess.PIPE)
+
+ if p.returncode != 0:
+ print("{} test failed:\n".format(test, p.returncode))
+ print(p.stderr.decode())
+ print("\nexiting...")
+ sys.exit(p.returncode)
+
+ print("")
+
+ elif test_num == 0:
+
+ print("Timing Karatsuba Num: {}".format(i), end='', flush=True)
+
+ for j in range(0, nruns):
+
+ cmd = [ exe, "{}/tests/bc/power.txt".format(testdir) ]
+
+ start = time.perf_counter()
+ p = subprocess.run(cmd, input=indata, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ end = time.perf_counter()
+
+ if p.returncode != 0:
+ print("bc returned an error; exiting...")
+ sys.exit(p.returncode)
+
+ runs[j] = end - start
+
+ run_times = runs[1:]
+ avg = sum(run_times) / len(run_times)
+
+ times.append(avg)
+ nums.append(i)
+ print(", Time: {}".format(times[i - mn]))
+
+except KeyboardInterrupt:
+ nums = nums[0:i]
+ times = times[0:i]
+
+if test_num == 0:
+
+ opt = nums[times.index(min(times))]
+
+ print("\n\nOptimal Karatsuba Num (for this machine): {}".format(opt))
+ print("Run the following:\n")
+ if "-flto" in config_env["CFLAGS"]:
+ print("CFLAGS=\"-flto\" ./configure.sh -O3 -k {}".format(opt))
+ else:
+ print("./configure.sh -O3 -k {}".format(opt))
+ print("make")
diff --git a/contrib/bc/link.sh b/contrib/bc/link.sh
new file mode 100755
index 000000000000..6f235c0920da
--- /dev/null
+++ b/contrib/bc/link.sh
@@ -0,0 +1,60 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+usage() {
+ printf "usage: %s bin_dir link\n" "$0" 1>&2
+ exit 1
+}
+
+test "$#" -gt 1 || usage
+
+bindir="$1"
+shift
+
+link="$1"
+shift
+
+
+for exe in "$bindir"/*; do
+
+ if [ ! -L "$exe" ]; then
+
+ base=$(basename "$exe")
+ ext="${base##*.}"
+
+ if [ "$ext" != "$base" ]; then
+ name="$link.$ext"
+ else
+ name="$link"
+ fi
+
+ ln -fs "$base" "$bindir/$name"
+ fi
+
+done
diff --git a/contrib/bc/locale_install.sh b/contrib/bc/locale_install.sh
new file mode 100755
index 000000000000..38863d2b2969
--- /dev/null
+++ b/contrib/bc/locale_install.sh
@@ -0,0 +1,252 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+usage() {
+ if [ $# -eq 1 ]; then
+ printf '%s\n' "$1"
+ fi
+ printf "usage: %s NLSPATH main_exec [DESTDIR]\n" "$0" 1>&2
+ exit 1
+}
+
+gencatfile() {
+
+ _gencatfile_loc="$1"
+ shift
+
+ _gencatfile_file="$1"
+ shift
+
+ mkdir -p $(dirname "$_gencatfile_loc")
+ gencat "$_gencatfile_loc" "$_gencatfile_file" > /dev/null 2>&1
+}
+
+localeexists() {
+
+ _localeexists_locales="$1"
+ shift
+
+ _localeexists_locale="$1"
+ shift
+
+ _localeexists_destdir="$1"
+ shift
+
+ if [ "$_localeexists_destdir" != "" ]; then
+ _localeexists_char="@"
+ _localeexists_locale="${_localeexists_locale%%_localeexists_char*}"
+ _localeexists_char="."
+ _localeexists_locale="${_localeexists_locale##*$_localeexists_char}"
+ fi
+
+ test ! -z "${_localeexists_locales##*$_localeexists_locale*}"
+ return $?
+}
+
+splitpath() {
+
+ _splitpath_path="$1"
+ shift
+
+ if [ "$_splitpath_path" = "${_splitpath_path#/}" ]; then
+ printf 'Must use absolute paths\n'
+ exit 1
+ fi
+
+ if [ "${_splitpath_path#\n*}" != "$_splitpath_path" ]; then
+ exit 1
+ fi
+
+ _splitpath_list=""
+ _splitpath_item=""
+
+ while [ "$_splitpath_path" != "/" ]; do
+ _splitpath_item=$(basename "$_splitpath_path")
+ _splitpath_list=$(printf '\n%s%s' "$_splitpath_item" "$_splitpath_list")
+ _splitpath_path=$(dirname "$_splitpath_path")
+ done
+
+ if [ "$_splitpath_list" != "/" ]; then
+ _splitpath_list="${_splitpath_list#?}"
+ fi
+
+ printf '%s' "$_splitpath_list"
+}
+
+relpath() {
+
+ _relpath_path1="$1"
+ shift
+
+ _relpath_path2="$1"
+ shift
+
+ _relpath_nl=$(printf '\nx')
+ _relpath_nl="${_relpath_nl%x}"
+
+ _relpath_splitpath1=`splitpath "$_relpath_path1"`
+ _relpath_splitpath2=`splitpath "$_relpath_path2"`
+
+ _relpath_path=""
+ _relpath_temp1="$_relpath_splitpath1"
+
+ IFS="$_relpath_nl"
+
+ for _relpath_part in $_relpath_temp1; do
+
+ _relpath_temp2="${_relpath_splitpath2#$_relpath_part$_relpath_nl}"
+
+ if [ "$_relpath_temp2" = "$_relpath_splitpath2" ]; then
+ break
+ fi
+
+ _relpath_splitpath2="$_relpath_temp2"
+ _relpath_splitpath1="${_relpath_splitpath1#$_relpath_part$_relpath_nl}"
+
+ done
+
+ for _relpath_part in $_relpath_splitpath2; do
+ _relpath_path="../$_relpath_path"
+ done
+
+ _relpath_path="${_relpath_path%../}"
+
+ for _relpath_part in $_relpath_splitpath1; do
+ _relpath_path="$_relpath_path$_relpath_part/"
+ done
+
+ _relpath_path="${_relpath_path%/}"
+
+ unset IFS
+
+ printf '%s\n' "$_relpath_path"
+}
+
+script="$0"
+scriptdir=$(dirname "$script")
+
+. "$scriptdir/functions.sh"
+
+all_locales=0
+
+while getopts "l" opt; do
+
+ case "$opt" in
+ l) all_locales=1 ; shift ;;
+ ?) usage "Invalid option $opt" ;;
+ esac
+
+done
+
+test "$#" -ge 2 || usage
+
+nlspath="$1"
+shift
+
+main_exec="$1"
+shift
+
+if [ "$#" -ge 1 ]; then
+ destdir="$1"
+ shift
+else
+ destdir=""
+fi
+
+"$scriptdir/locale_uninstall.sh" "$nlspath" "$main_exec" "$destdir"
+
+locales_dir="$scriptdir/locales"
+
+# What this does is if installing to a package, it installs all locales that
+# match supported charsets instead of installing all directly supported locales.
+if [ "$destdir" = "" ]; then
+ locales=$(locale -a)
+else
+ locales=$(locale -m)
+fi
+
+for file in $locales_dir/*.msg; do
+
+ locale=$(basename "$file" ".msg")
+
+ if [ "$all_locales" -eq 0 ]; then
+
+ localeexists "$locales" "$locale" "$destdir"
+ err="$?"
+
+ if [ "$err" -eq 0 ]; then
+ continue
+ fi
+ fi
+
+ if [ -L "$file" ]; then
+ continue
+ fi
+
+ loc=$(gen_nlspath "$destdir/$nlspath" "$locale" "$main_exec")
+
+ gencatfile "$loc" "$file"
+
+done
+
+for file in $locales_dir/*.msg; do
+
+ locale=$(basename "$file" ".msg")
+
+ if [ "$all_locales" -eq 0 ]; then
+
+ localeexists "$locales" "$locale" "$destdir"
+ err="$?"
+
+ if [ "$err" -eq 0 ]; then
+ continue
+ fi
+ fi
+
+ loc=$(gen_nlspath "$destdir/$nlspath" "$locale" "$main_exec")
+
+ mkdir -p $(dirname "$loc")
+
+ if [ -L "$file" ]; then
+
+ link=$(readlink "$file")
+ linkdir=$(dirname "$file")
+ locale=$(basename "$link" .msg)
+ linksrc=$(gen_nlspath "$nlspath" "$locale" "$main_exec")
+ relloc="${loc##$destdir/}"
+ rel=$(relpath "$linksrc" "$relloc")
+
+ if [ ! -f "$destdir/$linksrc" ]; then
+ gencatfile "$destdir/$linksrc" "$linkdir/$link"
+ fi
+
+ ln -fs "$rel" "$loc"
+ fi
+
+done
diff --git a/contrib/bc/locale_uninstall.sh b/contrib/bc/locale_uninstall.sh
new file mode 100755
index 000000000000..d38a5470e791
--- /dev/null
+++ b/contrib/bc/locale_uninstall.sh
@@ -0,0 +1,66 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+usage() {
+ printf "usage: %s NLSPATH main_exec [DESTDIR]\n" "$0" 1>&2
+ exit 1
+}
+
+script="$0"
+scriptdir=$(dirname "$script")
+
+. "$scriptdir/functions.sh"
+
+INSTALL="$scriptdir/safe-install.sh"
+
+test "$#" -ge 2 || usage
+
+nlspath="$1"
+shift
+
+main_exec="$1"
+shift
+
+if [ "$#" -ge 1 ]; then
+ destdir="$1"
+ shift
+else
+ destdir=""
+fi
+
+# I do something clever here. I am replacing the locale spot with
+# a wildcard, which should make it search all locale directories.
+# This way, we can delete catalogs for locales that we had to install
+# because they are symlinks.
+locales=$(gen_nlspath "$destdir/$nlspath" "*" "$main_exec")
+locales=$(ls $locales 2> /dev/null)
+
+for l in $locales; do
+ rm -f "$l"
+done
diff --git a/contrib/bc/locales/de_AT.ISO8859-1.msg b/contrib/bc/locales/de_AT.ISO8859-1.msg
new file mode 120000
index 000000000000..9f46cfac71ad
--- /dev/null
+++ b/contrib/bc/locales/de_AT.ISO8859-1.msg
@@ -0,0 +1 @@
+de_DE.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_AT.ISO8859-15.msg b/contrib/bc/locales/de_AT.ISO8859-15.msg
new file mode 120000
index 000000000000..9f46cfac71ad
--- /dev/null
+++ b/contrib/bc/locales/de_AT.ISO8859-15.msg
@@ -0,0 +1 @@
+de_DE.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_AT.UTF-8.msg b/contrib/bc/locales/de_AT.UTF-8.msg
new file mode 120000
index 000000000000..db4becd11216
--- /dev/null
+++ b/contrib/bc/locales/de_AT.UTF-8.msg
@@ -0,0 +1 @@
+de_DE.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_AT.utf8.msg b/contrib/bc/locales/de_AT.utf8.msg
new file mode 120000
index 000000000000..a97d36394b35
--- /dev/null
+++ b/contrib/bc/locales/de_AT.utf8.msg
@@ -0,0 +1 @@
+de_AT.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_CH.ISO8859-1.msg b/contrib/bc/locales/de_CH.ISO8859-1.msg
new file mode 120000
index 000000000000..9f46cfac71ad
--- /dev/null
+++ b/contrib/bc/locales/de_CH.ISO8859-1.msg
@@ -0,0 +1 @@
+de_DE.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_CH.ISO8859-15.msg b/contrib/bc/locales/de_CH.ISO8859-15.msg
new file mode 120000
index 000000000000..9f46cfac71ad
--- /dev/null
+++ b/contrib/bc/locales/de_CH.ISO8859-15.msg
@@ -0,0 +1 @@
+de_DE.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_CH.UTF-8.msg b/contrib/bc/locales/de_CH.UTF-8.msg
new file mode 120000
index 000000000000..db4becd11216
--- /dev/null
+++ b/contrib/bc/locales/de_CH.UTF-8.msg
@@ -0,0 +1 @@
+de_DE.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_CH.utf8.msg b/contrib/bc/locales/de_CH.utf8.msg
new file mode 120000
index 000000000000..2a8e0d24d58d
--- /dev/null
+++ b/contrib/bc/locales/de_CH.utf8.msg
@@ -0,0 +1 @@
+de_CH.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_DE.ISO8859-1.msg b/contrib/bc/locales/de_DE.ISO8859-1.msg
new file mode 100644
index 000000000000..518ddf0cf473
--- /dev/null
+++ b/contrib/bc/locales/de_DE.ISO8859-1.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Headers for printing errors/warnings.
+$set 1
+
+1 "Funktion:"
+
+$ Error types.
+$set 2
+
+1 "Rechenfehler:"
+2 "Analysefehler:"
+3 "Laufzeitfehler:"
+4 "Fataler Fehler:"
+5 "Warnung:"
+
+$ Math errors.
+$set 3
+
+1 "negative Zahl"
+2 "Nicht-Ganzzahl-Wert"
+3 "Überlauf: Zahl passt nicht in Register"
+4 "Division durch 0"
+
+$ Parse errors.
+$set 4
+
+1 "Ende der Datei"
+2 "ungültiges Zeichen: '%c'"
+3 "Zeichenketten-Ende konnte nicht gefunden werden"
+4 "Kommentar-Ende konnte nicht gefunden werden"
+5 "ungültiges Token"
+6 "ungültiger Ausdruck"
+7 "leerer Ausdruck"
+8 "Ungültige Druckanweisung"
+9 "Ungültige Funktionsdefinition"
+10 "Ungültige Zuweisung: Die linke Seite muss \"scale\", \"ibase\", \"obase\", \"seed\", \"last\", \"var\" oder \"array element\" sein"
+11 "keine automatische Variable gefunden"
+12 "Funktionsparameter oder Variable \"%s%s\" existiert bereits"
+13 "Blockende konnte nicht gefunden werden"
+14 "eine \"void-Funktion\" kann keinen Wert zurückgeben: %s()"
+15 "Variable kann keine Referenz sein: %s"
+16 "POSIX erlaubt keine Namen mit mehr als 1 Zeichen Länge: %s"
+17 "POSIX erlaubt keine '#'-Skriptkommentare"
+18 "POSIX erlaubt das Schlüsselwort \"%s\" nicht"
+19 "POSIX erlaubt keinen Punkt ('.') als Abkürzung für das letzte Ergebnis"
+20 "POSIX benötigt Klammern um Rückgabeausdrücke"
+21 "POSIX erlaubt den Operator \"%s\" nicht"
+22 "POSIX erlaubt keine Vergleichsoperatoren außerhalb von if-Anweisungen oder Schleifen"
+23 "POSIX benötigt 0 oder 1 Vergleichsoperatoren pro Bedingung"
+24 "POSIX erlaubt keinen leeren Ausdruck in einer for-Schleife"
+25 "POSIX erlaubt keine exponentielle Notation"
+26 "POSIX erlaubt keine Feld-Referenzen als Funktionsparameter"
+27 "POSIX erfordert, dass die linke Klammer auf der gleichen Linie wie der Funktionskopf steht"
+
+$ Runtime errors.
+$set 5
+
+1 "ungültige \"ibase\": muss im Intervall [%lu, %lu] liegen"
+2 "ungültige \"obase\": muss im Intervall [%lu, %lu] liegen"
+3 "ungültige \"scale\": muss im Intervall [%lu, %lu] liegen"
+4 "ungültiger read()-Ausdruck"
+5 "rekursiver read()-Aufruf"
+6 "Variable oder Feld-Element hat den falschen Typ"
+7 "Stapel hat zu wenig Elemente"
+8 "falsche Anzahl der Parameter: benötigt %zu, hat %zu"
+9 "undefinierte Funktion: %s()"
+10 "kann keinen ungültigen Wert in einem Ausdruck verwenden"
+
+$ Fatal errors.
+$set 6
+
+1 "Speicherzuweisung fehlgeschlagen"
+2 "Ein-Ausgabe-Fehler"
+3 "konnte die Datei nicht öffnen: %s"
+4 "Datei ist nicht ASCII: %s"
+5 "Pfad ist ein Verzeichnis: %s"
+6 "ungültige Befehlszeilenoption: \"%s\""
+7 "Option erfordert ein Argument: '%c' (\"%s\")"
+8 "Option benutzt keine Argumente: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/de_DE.ISO8859-15.msg b/contrib/bc/locales/de_DE.ISO8859-15.msg
new file mode 120000
index 000000000000..9f46cfac71ad
--- /dev/null
+++ b/contrib/bc/locales/de_DE.ISO8859-15.msg
@@ -0,0 +1 @@
+de_DE.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/de_DE.UTF-8.msg b/contrib/bc/locales/de_DE.UTF-8.msg
new file mode 100644
index 000000000000..2e3cd675b451
--- /dev/null
+++ b/contrib/bc/locales/de_DE.UTF-8.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Headers for printing errors/warnings.
+$set 1
+
+1 "Funktion:"
+
+$ Error types.
+$set 2
+
+1 "Rechenfehler:"
+2 "Analysefehler:"
+3 "Laufzeitfehler:"
+4 "Fataler Fehler:"
+5 "Warnung:"
+
+$ Math errors.
+$set 3
+
+1 "negative Zahl"
+2 "Nicht-Ganzzahl-Wert"
+3 "Ãœberlauf: Zahl passt nicht in Register"
+4 "Division durch 0"
+
+$ Parse errors.
+$set 4
+
+1 "Ende der Datei"
+2 "ungültiges Zeichen: '%c'"
+3 "Zeichenketten-Ende konnte nicht gefunden werden"
+4 "Kommentar-Ende konnte nicht gefunden werden"
+5 "ungültiges Token"
+6 "ungültiger Ausdruck"
+7 "leerer Ausdruck"
+8 "Ungültige Druckanweisung"
+9 "Ungültige Funktionsdefinition"
+10 "Ungültige Zuweisung: Die linke Seite muss \"scale\", \"ibase\", \"obase\", \"seed\", \"last\", \"var\" oder \"array element\" sein"
+11 "keine automatische Variable gefunden"
+12 "Funktionsparameter oder Variable \"%s%s\" existiert bereits"
+13 "Blockende konnte nicht gefunden werden"
+14 "eine \"void-Funktion\" kann keinen Wert zurückgeben: %s()"
+15 "Variable kann keine Referenz sein: %s"
+16 "POSIX erlaubt keine Namen mit mehr als 1 Zeichen Länge: %s"
+17 "POSIX erlaubt keine '#'-Skriptkommentare"
+18 "POSIX erlaubt das Schlüsselwort \"%s\" nicht"
+19 "POSIX erlaubt keinen Punkt ('.') als Abkürzung für das letzte Ergebnis"
+20 "POSIX benötigt Klammern um Rückgabeausdrücke"
+21 "POSIX erlaubt den Operator \"%s\" nicht"
+22 "POSIX erlaubt keine Vergleichsoperatoren außerhalb von if-Anweisungen oder Schleifen"
+23 "POSIX benötigt 0 oder 1 Vergleichsoperatoren pro Bedingung"
+24 "POSIX erlaubt keinen leeren Ausdruck in einer for-Schleife"
+25 "POSIX erlaubt keine exponentielle Notation"
+26 "POSIX erlaubt keine Feld-Referenzen als Funktionsparameter"
+27 "POSIX erfordert, dass die linke Klammer auf der gleichen Linie wie der Funktionskopf steht"
+
+$ Runtime errors.
+$set 5
+
+1 "ungültige \"ibase\": muss im Intervall [%lu, %lu] liegen"
+2 "ungültige \"obase\": muss im Intervall [%lu, %lu] liegen"
+3 "ungültige \"scale\"; muss im Intervall [%lu, %lu] liegen"
+4 "ungültiger read()-Ausdruck"
+5 "rekursiver read()-Aufruf"
+6 "Variable oder Feld-Element hat den falschen Typ"
+7 "Stapel hat zu wenig Elemente"
+8 "falsche Anzahl der Parameter: benötigt %zu, hat %zu"
+9 "undefinierte Funktion: %s()"
+10 "kann keinen ungültigen Wert in einem Ausdruck verwenden"
+
+$ Fatal errors.
+$set 6
+
+1 "Speicherzuweisung fehlgeschlagen"
+2 "Ein-Ausgabe-Fehler"
+3 "konnte die Datei nicht öffnen: %s"
+4 "Datei ist nicht ASCII: %s"
+5 "Pfad ist ein Verzeichnis: %s"
+6 "ungültige Befehlszeilenoption: \"%s\""
+7 "Option erfordert ein Argument: '%c' (\"%s\")"
+8 "Option benutzt keine Argumente: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/de_DE.utf8.msg b/contrib/bc/locales/de_DE.utf8.msg
new file mode 120000
index 000000000000..db4becd11216
--- /dev/null
+++ b/contrib/bc/locales/de_DE.utf8.msg
@@ -0,0 +1 @@
+de_DE.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_AU.ISO8859-1.msg b/contrib/bc/locales/en_AU.ISO8859-1.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_AU.ISO8859-1.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_AU.ISO8859-15.msg b/contrib/bc/locales/en_AU.ISO8859-15.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_AU.ISO8859-15.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_AU.US-ASCII.msg b/contrib/bc/locales/en_AU.US-ASCII.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_AU.US-ASCII.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_AU.UTF-8.msg b/contrib/bc/locales/en_AU.UTF-8.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_AU.UTF-8.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_AU.utf8.msg b/contrib/bc/locales/en_AU.utf8.msg
new file mode 120000
index 000000000000..bd2c02c017c0
--- /dev/null
+++ b/contrib/bc/locales/en_AU.utf8.msg
@@ -0,0 +1 @@
+en_AU.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_CA.ISO8859-1.msg b/contrib/bc/locales/en_CA.ISO8859-1.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_CA.ISO8859-1.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_CA.ISO8859-15.msg b/contrib/bc/locales/en_CA.ISO8859-15.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_CA.ISO8859-15.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_CA.US-ASCII.msg b/contrib/bc/locales/en_CA.US-ASCII.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_CA.US-ASCII.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_CA.UTF-8.msg b/contrib/bc/locales/en_CA.UTF-8.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_CA.UTF-8.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_CA.utf8.msg b/contrib/bc/locales/en_CA.utf8.msg
new file mode 120000
index 000000000000..b97fb4d8d41f
--- /dev/null
+++ b/contrib/bc/locales/en_CA.utf8.msg
@@ -0,0 +1 @@
+en_CA.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_GB.ISO8859-1.msg b/contrib/bc/locales/en_GB.ISO8859-1.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_GB.ISO8859-1.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_GB.ISO8859-15.msg b/contrib/bc/locales/en_GB.ISO8859-15.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_GB.ISO8859-15.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_GB.US-ASCII.msg b/contrib/bc/locales/en_GB.US-ASCII.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_GB.US-ASCII.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_GB.UTF-8.msg b/contrib/bc/locales/en_GB.UTF-8.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_GB.UTF-8.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_GB.utf8.msg b/contrib/bc/locales/en_GB.utf8.msg
new file mode 120000
index 000000000000..8eb23d97fab6
--- /dev/null
+++ b/contrib/bc/locales/en_GB.utf8.msg
@@ -0,0 +1 @@
+en_GB.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_IE.ISO8859-1.msg b/contrib/bc/locales/en_IE.ISO8859-1.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_IE.ISO8859-1.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_IE.ISO8859-15.msg b/contrib/bc/locales/en_IE.ISO8859-15.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_IE.ISO8859-15.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_IE.US_ASCII.msg b/contrib/bc/locales/en_IE.US_ASCII.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_IE.US_ASCII.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_IE.UTF-8.msg b/contrib/bc/locales/en_IE.UTF-8.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_IE.UTF-8.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_IE.utf8.msg b/contrib/bc/locales/en_IE.utf8.msg
new file mode 120000
index 000000000000..1a219bb5f9d5
--- /dev/null
+++ b/contrib/bc/locales/en_IE.utf8.msg
@@ -0,0 +1 @@
+en_IE.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_NZ.ISO8859-1.msg b/contrib/bc/locales/en_NZ.ISO8859-1.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_NZ.ISO8859-1.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_NZ.ISO8859-15.msg b/contrib/bc/locales/en_NZ.ISO8859-15.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_NZ.ISO8859-15.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_NZ.US-ASCII.msg b/contrib/bc/locales/en_NZ.US-ASCII.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_NZ.US-ASCII.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_NZ.UTF-8.msg b/contrib/bc/locales/en_NZ.UTF-8.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_NZ.UTF-8.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_NZ.utf8.msg b/contrib/bc/locales/en_NZ.utf8.msg
new file mode 120000
index 000000000000..ce97e789a832
--- /dev/null
+++ b/contrib/bc/locales/en_NZ.utf8.msg
@@ -0,0 +1 @@
+en_NZ.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_US.ISO8859-1.msg b/contrib/bc/locales/en_US.ISO8859-1.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_US.ISO8859-1.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_US.ISO8859-15.msg b/contrib/bc/locales/en_US.ISO8859-15.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_US.ISO8859-15.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_US.US-ASCII.msg b/contrib/bc/locales/en_US.US-ASCII.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_US.US-ASCII.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_US.US_ASCII.msg b/contrib/bc/locales/en_US.US_ASCII.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_US.US_ASCII.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_US.UTF-8.msg b/contrib/bc/locales/en_US.UTF-8.msg
new file mode 120000
index 000000000000..8118b73a6e95
--- /dev/null
+++ b/contrib/bc/locales/en_US.UTF-8.msg
@@ -0,0 +1 @@
+en_US.msg \ No newline at end of file
diff --git a/contrib/bc/locales/en_US.msg b/contrib/bc/locales/en_US.msg
new file mode 100644
index 000000000000..3d0ca99ac8cc
--- /dev/null
+++ b/contrib/bc/locales/en_US.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Function:"
+
+$ Error types.
+$set 2
+
+1 "Math error:"
+2 "Parse error:"
+3 "Runtime error:"
+4 "Fatal error:"
+5 "Warning:"
+
+$ Math errors.
+$set 3
+
+1 "negative number"
+2 "non-integer number"
+3 "overflow: number does not fit into a hardware number"
+4 "divide by 0"
+
+$ Parse errors.
+$set 4
+
+1 "end of file"
+2 "invalid character '%c'"
+3 "string end cannot be found"
+4 "comment end cannot be found"
+5 "invalid token"
+6 "invalid expression"
+7 "empty expression"
+8 "invalid print statement"
+9 "invalid function definition"
+10 "invalid assignment: left side must be scale, ibase, obase, seed, last, var, or array element"
+11 "no auto variable found"
+12 "function parameter or auto \"%s%s\" already exists"
+13 "block end cannot be found"
+14 "cannot return a value from void function: %s()"
+15 "var cannot be a reference: %s"
+16 "POSIX does not allow names longer than 1 character: %s"
+17 "POSIX does not allow '#' script comments"
+18 "POSIX does not allow the following keyword: %s"
+19 "POSIX does not allow a period ('.') as a shortcut for the last result"
+20 "POSIX requires parentheses around return expressions"
+21 "POSIX does not allow the following operator: %s"
+22 "POSIX does not allow comparison operators outside if statements or loops"
+23 "POSIX requires 0 or 1 comparison operators per condition"
+24 "POSIX requires all 3 parts of a for loop to be non-empty"
+25 "POSIX does not allow exponential notation"
+26 "POSIX does not allow array references as function parameters"
+27 "POSIX requires the left brace be on the same line as the function header"
+
+$ Runtime errors.
+$set 5
+
+1 "invalid ibase: must be [%lu, %lu]"
+2 "invalid obase: must be [%lu, %lu]"
+3 "invalid scale: must be [%lu, %lu]"
+4 "invalid read() expression"
+5 "recursive read() call"
+6 "variable or array element is the wrong type"
+7 "stack has too few elements"
+8 "wrong number of parameters; need %zu, have %zu"
+9 "undefined function: %s()"
+10 "cannot use a void value in an expression"
+
+$ Fatal errors.
+$set 6
+
+1 "memory allocation failed"
+2 "I/O error"
+3 "cannot open file: %s"
+4 "file is not ASCII: %s"
+5 "path is a directory: %s"
+6 "invalid command-line option: \"%s\""
+7 "option requires an argument: '%c' (\"%s\")"
+8 "option takes no arguments: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/en_US.utf8.msg b/contrib/bc/locales/en_US.utf8.msg
new file mode 120000
index 000000000000..a5cacfcf7cfe
--- /dev/null
+++ b/contrib/bc/locales/en_US.utf8.msg
@@ -0,0 +1 @@
+en_US.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/es_ES.ISO8859-1.msg b/contrib/bc/locales/es_ES.ISO8859-1.msg
new file mode 100644
index 000000000000..5a66561e9758
--- /dev/null
+++ b/contrib/bc/locales/es_ES.ISO8859-1.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Función:"
+
+$ Error types.
+$set 2
+
+1 "Error de matemática:"
+2 "Error de syntaxis:"
+3 "Error de ejecución:"
+4 "Error fatal:"
+5 "Advertencia:"
+
+$ Math errors.
+$set 3
+
+1 "número negativo"
+2 "número no es entero"
+3 "desbordamiento de enteros: no se puede encajar el el hardware"
+4 "división por cero"
+
+$ Parse errors.
+$set 4
+
+1 "fin de archivo"
+2 "no válido '%c'"
+3 "no puede encontrar el fine de la cadena"
+4 "no puede encontrar el fine del comentario"
+5 "el token no es válido"
+6 "la expresión no es válida"
+7 "la expresión es vacía"
+8 "la expresión de print no es válida"
+9 "la definición de función no es válida"
+10 "la asignación no es valida: en la izquierda debe ser scale, ibase, obase, last, var, o un elemento de matriz"
+11 "no se encontró ninguna variable automática"
+12 "ya hay un parámetro de función o variable automatica que se llama \"%s%s\""
+13 "no se puede encontrar el final de del bloque de código"
+14 "no puede haber un valor de retorno de una función \"void\": %s()"
+15 "var no puede ser una referencia: %s"
+16 "POSIX no permite nombres de más de 1 carácter: %s"
+17 "POSIX no permite '#' script comentarios"
+18 "POSIX no permite este palabra clave %s"
+19 "POSIX no permite un punto ('.') como un atajo del resultado previoso"
+20 "POSIX requieres paréntesis en el expresión del \"return\""
+21 "POSIX no permite este operador: %s"
+22 "POSIX no permite operadores de comparación aparte de \"if\" expresión o bucles"
+23 "POSIX requiere 0 o 1 operadores de comparisón para cada condición"
+24 "POSIX requiere todos 3 partes de una bucla que no esta vacío"
+25 "POSIX no permite una notación exponencial"
+26 "POSIX no permite una referencia a una matriz como un parámetro de función"
+27 "POSIX requiere el llave de la izquierda que sea en la misma línea que los parámetros de la función"
+
+$ Runtime errors.
+$set 5
+
+1 "\"ibase\" no es válido: debe ser [%lu, %lu]"
+2 "\"obase\" no es válido: debe ser [%lu, %lu]"
+3 "\"scale\" no es válido: debe ser [%lu, %lu]"
+4 "read() expresión no es válido"
+5 "recursion en la invocación de read()"
+6 "variable o elemento del matriz de tipo equivocado"
+7 "la pila no ha demaciado elementos"
+8 "la función no tiene un número de argumentos correcto; necessita %zu, tiene %zu"
+9 "la función no esta definida: %s()"
+10 "no puede utilizar un valor vacío en una expresión"
+
+$ Fatal errors.
+$set 6
+
+1 "error en la asignación de memoria"
+2 "error de I/O"
+3 "no puede abrir el archivo: %s"
+4 "el archivo no es ASCII: %s"
+5 "el ruta es un directorio: %s"
+6 "una opción de línea de comandos no es válida: \"%s\""
+7 "una opción requiere un argumento: '%c' (\"%s\")"
+8 "una opción no tiene argumento: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/es_ES.ISO8859-15.msg b/contrib/bc/locales/es_ES.ISO8859-15.msg
new file mode 120000
index 000000000000..0eb18677652d
--- /dev/null
+++ b/contrib/bc/locales/es_ES.ISO8859-15.msg
@@ -0,0 +1 @@
+es_ES.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/es_ES.UTF-8.msg b/contrib/bc/locales/es_ES.UTF-8.msg
new file mode 100644
index 000000000000..ab33b973f675
--- /dev/null
+++ b/contrib/bc/locales/es_ES.UTF-8.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Función:"
+
+$ Error types.
+$set 2
+
+1 "Error de matemática:"
+2 "Error de syntaxis:"
+3 "Error de ejecución:"
+4 "Error fatal:"
+5 "Advertencia:"
+
+$ Math errors.
+$set 3
+
+1 "número negativo"
+2 "número no es entero"
+3 "desbordamiento de enteros: no se puede encajar el el hardware"
+4 "división por cero"
+
+$ Parse errors.
+$set 4
+
+1 "fin de archivo"
+2 "no válido '%c'"
+3 "no puede encontrar el fine de la cadena"
+4 "no puede encontrar el fine del comentario"
+5 "el token no es válido"
+6 "la expresión no es válida"
+7 "la expresión es vacía"
+8 "la expresión de print no es válida"
+9 "la definición de función no es válida"
+10 "la asignación no es valida: en la izquierda debe ser scale, ibase, obase, last, var, o un elemento de matriz"
+11 "no se encontró ninguna variable automática"
+12 "ya hay un parámetro de función o variable automatica que se llama \"%s%s\""
+13 "no se puede encontrar el final de del bloque de código"
+14 "no puede haber un valor de retorno de una función \"void\": %s()"
+15 "var no puede ser una referencia: %s"
+16 "POSIX no permite nombres de más de 1 carácter: %s"
+17 "POSIX no permite '#' script comentarios"
+18 "POSIX no permite este palabra clave %s"
+19 "POSIX no permite un punto ('.') como un atajo del resultado previoso"
+20 "POSIX requieres paréntesis en el expresión del \"return\""
+21 "POSIX no permite este operador: %s"
+22 "POSIX no permite operadores de comparación aparte de \"if\" expresión o bucles"
+23 "POSIX requiere 0 o 1 operadores de comparisón para cada condición"
+24 "POSIX requiere todos 3 partes de una bucla que no esta vacío"
+25 "POSIX no permite una notación exponencial"
+26 "POSIX no permite una referencia a una matriz como un parámetro de función"
+27 "POSIX requiere el llave de la izquierda que sea en la misma línea que los parámetros de la función"
+
+$ Runtime errors.
+$set 5
+
+1 "\"ibase\" no es válido: debe ser [%lu, %lu]"
+2 "\"obase\" no es válido: debe ser [%lu, %lu]"
+3 "\"scale\" no es válido: debe ser [%lu, %lu]"
+4 "read() expresión no es válido"
+5 "recursion en la invocación de read()"
+6 "variable o elemento del matriz de tipo equivocado"
+7 "la pila no ha demaciado elementos"
+8 "la función no tiene un número de argumentos correcto; necessita %zu, tiene %zu"
+9 "la función no esta definida: %s()"
+10 "no puede utilizar un valor vacío en una expresión"
+
+$ Fatal errors.
+$set 6
+
+1 "error en la asignación de memoria"
+2 "error de I/O"
+3 "no puede abrir el archivo: %s"
+4 "el archivo no es ASCII: %s"
+5 "el ruta es un directorio: %s"
+6 "una opción de línea de comandos no es válida: \"%s\""
+7 "una opción requiere un argumento: '%c' (\"%s\")"
+8 "una opción no tiene argumento: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/es_ES.utf8.msg b/contrib/bc/locales/es_ES.utf8.msg
new file mode 120000
index 000000000000..9015906bb528
--- /dev/null
+++ b/contrib/bc/locales/es_ES.utf8.msg
@@ -0,0 +1 @@
+es_ES.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_BE.ISO8859-1.msg b/contrib/bc/locales/fr_BE.ISO8859-1.msg
new file mode 120000
index 000000000000..132ab00965ea
--- /dev/null
+++ b/contrib/bc/locales/fr_BE.ISO8859-1.msg
@@ -0,0 +1 @@
+fr_FR.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_BE.ISO8859-15.msg b/contrib/bc/locales/fr_BE.ISO8859-15.msg
new file mode 120000
index 000000000000..132ab00965ea
--- /dev/null
+++ b/contrib/bc/locales/fr_BE.ISO8859-15.msg
@@ -0,0 +1 @@
+fr_FR.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_BE.UTF-8.msg b/contrib/bc/locales/fr_BE.UTF-8.msg
new file mode 120000
index 000000000000..a927f182c45c
--- /dev/null
+++ b/contrib/bc/locales/fr_BE.UTF-8.msg
@@ -0,0 +1 @@
+fr_FR.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_BE.utf8.msg b/contrib/bc/locales/fr_BE.utf8.msg
new file mode 120000
index 000000000000..f4845d7d8d95
--- /dev/null
+++ b/contrib/bc/locales/fr_BE.utf8.msg
@@ -0,0 +1 @@
+fr_BE.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CA.ISO8859-1.msg b/contrib/bc/locales/fr_CA.ISO8859-1.msg
new file mode 120000
index 000000000000..132ab00965ea
--- /dev/null
+++ b/contrib/bc/locales/fr_CA.ISO8859-1.msg
@@ -0,0 +1 @@
+fr_FR.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CA.ISO8859-15.msg b/contrib/bc/locales/fr_CA.ISO8859-15.msg
new file mode 120000
index 000000000000..132ab00965ea
--- /dev/null
+++ b/contrib/bc/locales/fr_CA.ISO8859-15.msg
@@ -0,0 +1 @@
+fr_FR.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CA.UTF-8.msg b/contrib/bc/locales/fr_CA.UTF-8.msg
new file mode 120000
index 000000000000..a927f182c45c
--- /dev/null
+++ b/contrib/bc/locales/fr_CA.UTF-8.msg
@@ -0,0 +1 @@
+fr_FR.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CA.utf8.msg b/contrib/bc/locales/fr_CA.utf8.msg
new file mode 120000
index 000000000000..b250cec188b6
--- /dev/null
+++ b/contrib/bc/locales/fr_CA.utf8.msg
@@ -0,0 +1 @@
+fr_CA.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CH.ISO8859-1.msg b/contrib/bc/locales/fr_CH.ISO8859-1.msg
new file mode 120000
index 000000000000..132ab00965ea
--- /dev/null
+++ b/contrib/bc/locales/fr_CH.ISO8859-1.msg
@@ -0,0 +1 @@
+fr_FR.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CH.ISO8859-15.msg b/contrib/bc/locales/fr_CH.ISO8859-15.msg
new file mode 120000
index 000000000000..132ab00965ea
--- /dev/null
+++ b/contrib/bc/locales/fr_CH.ISO8859-15.msg
@@ -0,0 +1 @@
+fr_FR.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CH.UTF-8.msg b/contrib/bc/locales/fr_CH.UTF-8.msg
new file mode 120000
index 000000000000..a927f182c45c
--- /dev/null
+++ b/contrib/bc/locales/fr_CH.UTF-8.msg
@@ -0,0 +1 @@
+fr_FR.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_CH.utf8.msg b/contrib/bc/locales/fr_CH.utf8.msg
new file mode 120000
index 000000000000..33e731642449
--- /dev/null
+++ b/contrib/bc/locales/fr_CH.utf8.msg
@@ -0,0 +1 @@
+fr_CH.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_FR.ISO8859-1.msg b/contrib/bc/locales/fr_FR.ISO8859-1.msg
new file mode 100644
index 000000000000..42c3f26ca5b7
--- /dev/null
+++ b/contrib/bc/locales/fr_FR.ISO8859-1.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Fonction :"
+
+$ Error types.
+$set 2
+
+1 "Erreur de calcul :"
+2 "Erreur d'analyse syntaxique :"
+3 "Erreur d'exécution :"
+4 "Erreur fatale :"
+5 "Avertissement :"
+
+$ Math errors.
+$set 3
+
+1 "nombre strictement négatif"
+2 "nombre non entier"
+3 "dépassement : le nombre ne tient pas dans un type traité par le processeur"
+4 "division par 0"
+
+$ Parse errors.
+$set 4
+
+1 "fin de fichier"
+2 "caractère invalide '%c'"
+3 "fin de chaîne non trouvée"
+4 "fin de commentaire non trouvée"
+5 "symbole invalide"
+6 "expression invalide"
+7 "expression vide"
+8 "instruction d'écriture invalide"
+9 "définition de fonction invalide"
+10 "affectation invalide : la partie gauche doit être 'scale', 'ibase', 'obase', 'seed', 'last', une variable ou une case de tableau"
+11 "aucune variable auto trouvée"
+12 "Le paramètre de fonction ou variable auto \"%s%s\" existe déjà"
+13 "fin de bloc non trouvée"
+14 "une fonction 'void' ne peut pas retourner de valeur : %s()"
+15 "Une variable ne peut pas être une référence : %s"
+16 "POSIX interdit les noms de plus d'un caractère : %s"
+17 "POSIX interdit les commentaires dans les scripts (pas de '#')"
+18 "POSIX interdit le mot-clé '%s'"
+19 "POSIX interdit l'utilisation du point ('.') comme raccourci pour le dernier résultat"
+20 "POSIX impose des parenthèses autour des expressions de retour"
+21 "POSIX interdit l'opérateur '%s'"
+22 "POSIX interdit les opérateurs de comparaison en dehors des expressions 'if' ou des boucles"
+23 "POSIX impose 0 ou 1 opérateur de comparaison par condition"
+24 "POSIX interdit une expression vide dans une boucle 'for'"
+25 "POSIX interdit la notation exponentielle"
+26 "POSIX interdit les références à un tableau dans les paramètres d'une fonction"
+27 "POSIX impose que l'en-tête de la fonction et le '{' soient sur la même ligne"
+
+$ Runtime errors.
+$set 5
+
+1 "ibase invalide : doit être [%lu, %lu]"
+2 "obase invalide : doit être [%lu, %lu]"
+3 "scale invalide : doit être [%lu, %lu]"
+4 "expression read() invalide"
+5 "appel read() récursif"
+6 "mauvais type de variable ou d'élément de tableau"
+7 "pile sous-remplie"
+8 "nombre incorrect de paramètres - attendus : %zu, obtenus : %zu"
+9 "fonction non définie : %s()"
+10 "une valeur 'void' est inutilisable dans une expression"
+
+$ Fatal errors.
+$set 6
+
+1 "échec d'allocation mémoire"
+2 "erreur d'entrée-sortie"
+3 "impossible d'ouvrir le fichier : %s"
+4 "fichier non ASCII : %s"
+5 "le chemin est un répertoire : %s"
+6 "option de ligne de commande invalide : \"%s\""
+7 "l'option '%c' (\"%s\") requiert un argument"
+8 "l'option '%c' (\"%s\") ne prend pas d'argument"
diff --git a/contrib/bc/locales/fr_FR.ISO8859-15.msg b/contrib/bc/locales/fr_FR.ISO8859-15.msg
new file mode 120000
index 000000000000..132ab00965ea
--- /dev/null
+++ b/contrib/bc/locales/fr_FR.ISO8859-15.msg
@@ -0,0 +1 @@
+fr_FR.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/fr_FR.UTF-8.msg b/contrib/bc/locales/fr_FR.UTF-8.msg
new file mode 100644
index 000000000000..42c3f26ca5b7
--- /dev/null
+++ b/contrib/bc/locales/fr_FR.UTF-8.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Fonction :"
+
+$ Error types.
+$set 2
+
+1 "Erreur de calcul :"
+2 "Erreur d'analyse syntaxique :"
+3 "Erreur d'exécution :"
+4 "Erreur fatale :"
+5 "Avertissement :"
+
+$ Math errors.
+$set 3
+
+1 "nombre strictement négatif"
+2 "nombre non entier"
+3 "dépassement : le nombre ne tient pas dans un type traité par le processeur"
+4 "division par 0"
+
+$ Parse errors.
+$set 4
+
+1 "fin de fichier"
+2 "caractère invalide '%c'"
+3 "fin de chaîne non trouvée"
+4 "fin de commentaire non trouvée"
+5 "symbole invalide"
+6 "expression invalide"
+7 "expression vide"
+8 "instruction d'écriture invalide"
+9 "définition de fonction invalide"
+10 "affectation invalide : la partie gauche doit être 'scale', 'ibase', 'obase', 'seed', 'last', une variable ou une case de tableau"
+11 "aucune variable auto trouvée"
+12 "Le paramètre de fonction ou variable auto \"%s%s\" existe déjà"
+13 "fin de bloc non trouvée"
+14 "une fonction 'void' ne peut pas retourner de valeur : %s()"
+15 "Une variable ne peut pas être une référence : %s"
+16 "POSIX interdit les noms de plus d'un caractère : %s"
+17 "POSIX interdit les commentaires dans les scripts (pas de '#')"
+18 "POSIX interdit le mot-clé '%s'"
+19 "POSIX interdit l'utilisation du point ('.') comme raccourci pour le dernier résultat"
+20 "POSIX impose des parenthèses autour des expressions de retour"
+21 "POSIX interdit l'opérateur '%s'"
+22 "POSIX interdit les opérateurs de comparaison en dehors des expressions 'if' ou des boucles"
+23 "POSIX impose 0 ou 1 opérateur de comparaison par condition"
+24 "POSIX interdit une expression vide dans une boucle 'for'"
+25 "POSIX interdit la notation exponentielle"
+26 "POSIX interdit les références à un tableau dans les paramètres d'une fonction"
+27 "POSIX impose que l'en-tête de la fonction et le '{' soient sur la même ligne"
+
+$ Runtime errors.
+$set 5
+
+1 "ibase invalide : doit être [%lu, %lu]"
+2 "obase invalide : doit être [%lu, %lu]"
+3 "scale invalide : doit être [%lu, %lu]"
+4 "expression read() invalide"
+5 "appel read() récursif"
+6 "mauvais type de variable ou d'élément de tableau"
+7 "pile sous-remplie"
+8 "nombre incorrect de paramètres - attendus : %zu, obtenus : %zu"
+9 "fonction non définie : %s()"
+10 "une valeur 'void' est inutilisable dans une expression"
+
+$ Fatal errors.
+$set 6
+
+1 "échec d'allocation mémoire"
+2 "erreur d'entrée-sortie"
+3 "impossible d'ouvrir le fichier : %s"
+4 "fichier non ASCII : %s"
+5 "le chemin est un répertoire : %s"
+6 "option de ligne de commande invalide : \"%s\""
+7 "l'option '%c' (\"%s\") requiert un argument"
+8 "l'option '%c' (\"%s\") ne prend pas d'argument"
diff --git a/contrib/bc/locales/fr_FR.utf8.msg b/contrib/bc/locales/fr_FR.utf8.msg
new file mode 120000
index 000000000000..a927f182c45c
--- /dev/null
+++ b/contrib/bc/locales/fr_FR.utf8.msg
@@ -0,0 +1 @@
+fr_FR.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/ja_JP.UTF-8.msg b/contrib/bc/locales/ja_JP.UTF-8.msg
new file mode 100644
index 000000000000..587c84413aab
--- /dev/null
+++ b/contrib/bc/locales/ja_JP.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ ãã®ä»–ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€‚
+$set 1
+
+1 "関数:"
+
+$ エラーã®ç¨®é¡žã€‚
+$set 2
+
+1 "æ•°å­¦ã®ã‚¨ãƒ©ãƒ¼ï¼š"
+2 "パースエラー:"
+3 "ランタイムエラー:"
+4 "致命的ãªã‚¨ãƒ©ãƒ¼ï¼š"
+5 "警告:"
+
+$ æ•°å­¦ã®ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚
+$set 3
+
+1 "è² ã®æ•°"
+2 "éžæ•´æ•°"
+3 "オーãƒãƒ¼ãƒ•ãƒ­ãƒ¼ï¼šæ•°å­—ãŒãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ç•ªå·ã«åŽã¾ã‚‰ãªã„"
+4 "0ã§å‰²ã‚‹"
+
+$ 構文解æžã®ã‚¨ãƒ©ãƒ¼ã€‚
+$set 4
+
+1 "ファイルã®çµ‚了"
+2 "無効ãªæ–‡å­— '%c'"
+3 "文字列ã®çµ‚端ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+4 "コメントエンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+5 "無効ãªãƒˆãƒ¼ã‚¯ãƒ³"
+6 "無効ãªå¼"
+7 "空ã®å¼"
+8 "無効ãªå°åˆ·æ–‡"
+9 "無効ãªé–¢æ•°å®šç¾©"
+10 "無効ãªä»£å…¥ï¼šå·¦å´ã¯ scale, ibase, obase, last, var, ã¾ãŸã¯é…列è¦ç´ ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+11 "自動変数ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+12 "関数パラメータã¾ãŸã¯è‡ªå‹•\"ï¼…sï¼…s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™"
+13 "ブロックエンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+14 "void 関数ã‹ã‚‰å€¤ã‚’è¿”ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“:%s()"
+15 "varã¯å‚ç…§ã«ã§ãã¾ã›ã‚“:%s"
+16 "POSIX 㯠1 文字より長ã„åå‰ã‚’許å¯ã—ã¾ã›ã‚“:%s"
+17 "POSIX 㯠'#' スクリプトã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’許å¯ã—ã¾ã›ã‚“。"
+18 "POSIX ã¯ä»¥ä¸‹ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’許å¯ã—ã¾ã›ã‚“:%s"
+19 "POSIX ã¯æœ€å¾Œã®çµæžœã®ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã¨ã—ã¦ãƒ”リオド ('.') を許å¯ã—ã¾ã›ã‚“。"
+20 "POSIX ã¯æˆ»ã‚Šå€¤å¼ã®å‘¨ã‚Šã«æ‹¬å¼§ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚"
+21 "POSIX ã¯æ¬¡ã®æ¼”ç®—å­ã‚’許å¯ã—ã¾ã›ã‚“:%s"
+22 "POSIX 㯠if 文やループã®å¤–ã®æ¯”較演算å­ã‚’許å¯ã—ã¾ã›ã‚“。"
+23 "POSIXã¯æ¡ä»¶ã”ã¨ã«0ã¾ãŸã¯1ã®æ¯”較演算å­ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚"
+24 "POSIXã¯forループã®3ã¤ã®éƒ¨åˆ†ãŒã™ã¹ã¦ç©ºã§ãªã„ã“ã¨ã‚’è¦æ±‚ã—ã¾ã™ã€‚"
+25 "POSIXã¯æŒ‡æ•°è¡¨è¨˜ã‚’許å¯ã—ã¾ã›ã‚“。"
+26 "POSIX ã¯é–¢æ•°ãƒ‘ラメータã¨ã—ã¦é…列å‚照を許å¯ã—ã¾ã›ã‚“。"
+27 "POSIXã§ã¯ã€é–¢æ•°ãƒ˜ãƒƒãƒ€ã¨åŒã˜è¡Œã«å·¦ä¸­æ‹¬å¼§ãŒã‚ã‚‹ã“ã¨ãŒå¿…è¦ã§ã™ã€‚"
+
+$ ランタイムエラー。
+$set 5
+
+1 "無効ãªibase:ã¯[ï¼…luã€ï¼…lu]ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+2 "無効ãªobase:ã¯[ï¼…luã€ï¼…lu]ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+3 "無効ãªscale:ã¯[ï¼…luã€ï¼…lu]ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+4 "å¼ãŒç„¡åŠ¹read()"
+5 "å†å¸°çš„読ã¿è¾¼ã¿()呼ã³å‡ºã—"
+6 "変数ã¾ãŸã¯é…列è¦ç´ ã®åž‹ãŒé–“é•ã£ã¦ã„ã‚‹"
+7 "スタックã®è¦ç´ ãŒå°‘ãªã™ãŽã‚‹"
+8 "パラメータã®æ•°ãŒé–“é•ã£ã¦ã„ã¾ã™ã€‚"
+9 "定義ã•ã‚Œã¦ã„ãªã„関数:%s()"
+10 "å¼ã§ã¯ void 値を使用ã§ãã¾ã›ã‚“"
+
+$ 致命的ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+$set 6
+
+1 "メモリã®å‰²ã‚Šå½“ã¦ã«å¤±æ•—ã—ã¾ã—ãŸ"
+2 "I/Oエラー"
+3 "ファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚%s"
+4 "ファイルãŒASCIIã§ã¯ã‚ã‚Šã¾ã›ã‚“:%s"
+5 "パスã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™ï¼š%s"
+6 "無効ãªã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã‚ªãƒ—ション:'ï¼…c'(\"ï¼…s\")"
+
+$set 7
+
+1 "オプションã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™ï¼š'%c' (\"%s\")"
+2 "オプションã¯å¼•æ•°ã‚’å–ã‚Šã¾ã›ã‚“:'%c' (\"%s\")"
diff --git a/contrib/bc/locales/ja_JP.eucJP.msg b/contrib/bc/locales/ja_JP.eucJP.msg
new file mode 100644
index 000000000000..8229c8f5a665
--- /dev/null
+++ b/contrib/bc/locales/ja_JP.eucJP.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ ¤½¤Î¾¤Î¥á¥Ã¥»¡¼¥¸¡£
+$set 1
+
+1 "´Ø¿ô¡§"
+
+$ ¥¨¥é¡¼¤Î¼ïÎà¡£
+$set 2
+
+1 "¿ô³Ø¤Î¥¨¥é¡¼¡§"
+2 "¥Ñ¡¼¥¹¥¨¥é¡¼¡§"
+3 "¥é¥ó¥¿¥¤¥à¥¨¥é¡¼¡§"
+4 "Ã×̿Ū¤Ê¥¨¥é¡¼¡§"
+5 "·Ù¹ð¡§"
+
+$ ¿ô³Ø¤Î¥¨¥é¡¼¤Ç¤¹¡£
+$set 3
+
+1 "Éé¤Î¿ô"
+2 "ÈóÀ°¿ô"
+3 "¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¡§¿ô»ú¤¬¥Ï¡¼¥É¥¦¥§¥¢ÈÖ¹æ¤Ë¼ý¤Þ¤é¤Ê¤¤"
+4 "0¤Ç³ä¤ë"
+
+$ ¹½Ê¸²òÀϤΥ¨¥é¡¼¡£
+$set 4
+
+1 "¥Õ¥¡¥¤¥ë¤Î½ªÎ»"
+2 "̵¸ú¤Êʸ»ú '%c'"
+3 "ʸ»úÎó¤Î½ªÃ¼¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+4 "¥³¥á¥ó¥È¥¨¥ó¥É¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+5 "̵¸ú¤Ê¥È¡¼¥¯¥ó"
+6 "̵¸ú¤Ê¼°"
+7 "¶õ¤Î¼°"
+8 "̵¸ú¤Ê°õºþʸ"
+9 "̵¸ú¤Ê´Ø¿ôÄêµÁ"
+10 "̵¸ú¤ÊÂåÆþ¡§º¸Â¦¤Ï scale, ibase, obase, last, var, ¤Þ¤¿¤ÏÇÛÎóÍ×ÁǤǤʤ±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+11 "¼«Æ°ÊÑ¿ô¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+12 "´Ø¿ô¥Ñ¥é¥á¡¼¥¿¤Þ¤¿¤Ï¼«Æ°\"¡ós¡ós\"¤Ï¤¹¤Ç¤Ë¸ºß¤·¤Þ¤¹"
+13 "¥Ö¥í¥Ã¥¯¥¨¥ó¥É¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+14 "void ´Ø¿ô¤«¤éÃͤòÊÖ¤¹¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡§%s()"
+15 "var¤Ï»²¾È¤Ë¤Ç¤­¤Þ¤»¤ó¡§¡ós"
+16 "POSIX ¤Ï 1 ʸ»ú¤è¤êŤ¤Ì¾Á°¤òµö²Ä¤·¤Þ¤»¤ó¡§%s"
+17 "POSIX ¤Ï '#' ¥¹¥¯¥ê¥×¥È¤Î¥³¥á¥ó¥È¤òµö²Ä¤·¤Þ¤»¤ó¡£"
+18 "POSIX ¤Ï°Ê²¼¤Î¥­¡¼¥ï¡¼¥É¤òµö²Ä¤·¤Þ¤»¤ó¡§%s"
+19 "POSIX ¤ÏºÇ¸å¤Î·ë²Ì¤Î¥·¥ç¡¼¥È¥«¥Ã¥È¤È¤·¤Æ¥Ô¥ê¥ª¥É ('.') ¤òµö²Ä¤·¤Þ¤»¤ó¡£"
+20 "POSIX ¤ÏÌá¤êÃͼ°¤Î¼þ¤ê¤Ë³ç¸Ì¤òɬÍפȤ·¤Þ¤¹¡£"
+21 "POSIX ¤Ï¼¡¤Î±é»»»Ò¤òµö²Ä¤·¤Þ¤»¤ó¡§%s"
+22 "POSIX ¤Ï if ʸ¤ä¥ë¡¼¥×¤Î³°¤ÎÈæ³Ó±é»»»Ò¤òµö²Ä¤·¤Þ¤»¤ó¡£"
+23 "POSIX¤Ï¾ò·ï¤´¤È¤Ë0¤Þ¤¿¤Ï1¤ÎÈæ³Ó±é»»»Ò¤òɬÍפȤ·¤Þ¤¹¡£"
+24 "POSIX¤Ïfor¥ë¡¼¥×¤Î3¤Ä¤ÎÉôʬ¤¬¤¹¤Ù¤Æ¶õ¤Ç¤Ê¤¤¤³¤È¤òÍ׵ᤷ¤Þ¤¹¡£"
+25 "POSIX¤Ï»Ø¿ôɽµ­¤òµö²Ä¤·¤Þ¤»¤ó¡£"
+26 "POSIX ¤Ï´Ø¿ô¥Ñ¥é¥á¡¼¥¿¤È¤·¤ÆÇÛÎ󻲾Ȥòµö²Ä¤·¤Þ¤»¤ó¡£"
+27 "POSIX¤Ç¤Ï¡¢´Ø¿ô¥Ø¥Ã¥À¤ÈƱ¤¸¹Ô¤Ëº¸Ãæ³ç¸Ì¤¬¤¢¤ë¤³¤È¤¬É¬ÍפǤ¹¡£"
+
+$ ¥é¥ó¥¿¥¤¥à¥¨¥é¡¼¡£
+$set 5
+
+1 "̵¸ú¤Êibase¡§¤Ï[¡ólu¡¢¡ólu]¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+2 "̵¸ú¤Êobase¡§¤Ï[¡ólu¡¢¡ólu]¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+3 "̵¸ú¤Êscale¡§¤Ï[¡ólu¡¢¡ólu]¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+4 "¼°¤¬Ìµ¸úread()"
+5 "ºÆµ¢ÅªÆɤ߹þ¤ß()¸Æ¤Ó½Ð¤·"
+6 "ÊÑ¿ô¤Þ¤¿¤ÏÇÛÎóÍ×ÁǤη¿¤¬´Ö°ã¤Ã¤Æ¤¤¤ë"
+7 "¥¹¥¿¥Ã¥¯¤ÎÍ×ÁǤ¬¾¯¤Ê¤¹¤®¤ë"
+8 "¥Ñ¥é¥á¡¼¥¿¤Î¿ô¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹¡£"
+9 "ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤´Ø¿ô¡§%s()"
+10 "¼°¤Ç¤Ï void Ãͤò»ÈÍѤǤ­¤Þ¤»¤ó"
+
+$ Ã×̿Ū¤Ê¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿¡£
+$set 6
+
+1 "¥á¥â¥ê¤Î³ä¤êÅö¤Æ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+2 "I/O¥¨¥é¡¼"
+3 "¥Õ¥¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó¤Ç¤·¤¿¡£%s"
+4 "¥Õ¥¡¥¤¥ë¤¬ASCII¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡§%s"
+5 "¥Ñ¥¹¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡§%s"
+6 "̵¸ú¤Ê¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó¡§'¡óc'¡Ê\"¡ós\")"
+
+$set 7
+
+1 "¥ª¥×¥·¥ç¥ó¤Ë¤Ï°ú¿ô¤¬É¬ÍפǤ¹¡§'%c' (\"%s\")"
+2 "¥ª¥×¥·¥ç¥ó¤Ï°ú¿ô¤ò¼è¤ê¤Þ¤»¤ó¡§'%c' (\"%s\")"
diff --git a/contrib/bc/locales/ja_JP.utf8.msg b/contrib/bc/locales/ja_JP.utf8.msg
new file mode 120000
index 000000000000..104aafff8356
--- /dev/null
+++ b/contrib/bc/locales/ja_JP.utf8.msg
@@ -0,0 +1 @@
+ja_JP.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/nl_BE.ISO8859-1.msg b/contrib/bc/locales/nl_BE.ISO8859-1.msg
new file mode 120000
index 000000000000..cb19bded5504
--- /dev/null
+++ b/contrib/bc/locales/nl_BE.ISO8859-1.msg
@@ -0,0 +1 @@
+nl_NL.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/nl_BE.ISO8859-15.msg b/contrib/bc/locales/nl_BE.ISO8859-15.msg
new file mode 120000
index 000000000000..33f4a25dfbfe
--- /dev/null
+++ b/contrib/bc/locales/nl_BE.ISO8859-15.msg
@@ -0,0 +1 @@
+nl_BE.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/nl_NL.ISO8859-1.msg b/contrib/bc/locales/nl_NL.ISO8859-1.msg
new file mode 100644
index 000000000000..a291baa53963
--- /dev/null
+++ b/contrib/bc/locales/nl_NL.ISO8859-1.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Diversen berichten.
+$set 1
+
+1 "Functie:"
+
+$ Fouttypes.
+$set 2
+
+1 "Rekenfout:"
+2 "Parse error:"
+3 "Runtime error:"
+4 "Fatale fout:"
+5 "Waarschuwing:"
+
+$ Math error.
+$set 3
+
+1 "negatief getal"
+2 "niet-integraal getal"
+3 "overloop: nummer past niet in een hardware-nummer"
+4 "delen door 0"
+
+$ Parsefouten.
+$set 4
+
+1 "einde van het file"
+2 "ongeldig teken '%c'"
+3 "string einde kon niet worden gevonden"
+4 "commentaar einde kon niet worden gevonden"
+5 "ongeldige token"
+6 "ongeldige uitdrukking"
+7 "lege uitdrukking"
+8 "ongeldige afdruk"
+9 "ongeldige functiedefinitie"
+10 "ongeldige toewijzing: linkerzijde moet scale, ibase, obase, last, var of array element zijn"
+11 "geen autovariabele gevonden"
+12 "Functieparameter of automatisch bestaat al"
+13 "blokuiteinde kon niet worden gevonden"
+14 "kan geen waarde uit de nietige functie teruggeven: %s()"
+15 "var kan geen referentie zijn: %s"
+16 "POSIX staat geen namen toe die langer zijn dan 1 teken: %s"
+17 "POSIX staat geen '#'-scriptcommentaar toe"
+18 "POSIX laat het volgende sleutelwoord niet toe: %s"
+19 "POSIX staat geen periode ('.') toe als een kortere weg voor het laatste resultaat"
+20 "POSIX vereist haakjes rond de terugkeeruitdrukkingen"
+21 "POSIX laat de volgende operator niet toe: %s"
+22 "POSIX laat geen vergelijking toe tussen operatoren buiten als verklaringen of lussen"
+23 "POSIX vereist 0 of 1 vergelijkingsoperator per conditie"
+24 "POSIX vereist dat alle 3 de delen van een lus niet leeg zijn"
+25 "POSIX laat geen exponentiële notatie toe"
+26 "POSIX staat geen arrayreferenties toe als functieparameters"
+27 "POSIX vereist dat de linkse beugel op dezelfde regel staat als de functiehoofding"
+
+$ Runtime fouten.
+$set 5
+
+1 "ongeldige ibase: moet [%lu, %lu] zijn"
+2 "ongeldige obase: moet [%lu, %lu] zijn"
+3 "ongeldige schaal: moet [%lu, %lu] zijn"
+4 "ongeldige read() expressie"
+5 "recursieve read() call"
+6 "Variabele of matrix-element is het verkeerde type"
+7 "Stapel heeft te weinig elementen"
+8 "Verkeerd aantal parameters; hebben %zu nodig, hebben %zu"
+9 "ongedefinieerde functie: %s()"
+10 "kan geen nietige waarde in een uitdrukking gebruiken"
+
+$ Fatale fouten.
+$set 6
+
+1 "geheugentoewijzing mislukt"
+2 "I/O-fout"
+3 "kon geen file openen: %s"
+4 "bestand is niet ASCII: %s"
+5 "pad is een directory: %s"
+6 "ongeldige opdrachtregeloptie: '%c' (%s)"
+
+$set 7
+
+1 "optie vereist een argument: '%c' (\"%s\")"
+2 "optie neemt geen argumenten aan: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/nl_NL.ISO8859-15.msg b/contrib/bc/locales/nl_NL.ISO8859-15.msg
new file mode 120000
index 000000000000..cb19bded5504
--- /dev/null
+++ b/contrib/bc/locales/nl_NL.ISO8859-15.msg
@@ -0,0 +1 @@
+nl_NL.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/nl_NL.UTF-8.msg b/contrib/bc/locales/nl_NL.UTF-8.msg
new file mode 100644
index 000000000000..07fdbf248815
--- /dev/null
+++ b/contrib/bc/locales/nl_NL.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Diversen berichten.
+$set 1
+
+1 "Functie:"
+
+$ Fouttypes.
+$set 2
+
+1 "Rekenfout:"
+2 "Parse error:"
+3 "Runtime error:"
+4 "Fatale fout:"
+5 "Waarschuwing:"
+
+$ Math error.
+$set 3
+
+1 "negatief getal"
+2 "niet-integraal getal"
+3 "overloop: nummer past niet in een hardware-nummer"
+4 "delen door 0"
+
+$ Parsefouten.
+$set 4
+
+1 "einde van het file"
+2 "ongeldig teken '%c'"
+3 "string einde kon niet worden gevonden"
+4 "commentaar einde kon niet worden gevonden"
+5 "ongeldige token"
+6 "ongeldige uitdrukking"
+7 "lege uitdrukking"
+8 "ongeldige afdruk"
+9 "ongeldige functiedefinitie"
+10 "ongeldige toewijzing: linkerzijde moet scale, ibase, obase, last, var of array element zijn"
+11 "geen autovariabele gevonden"
+12 "Functieparameter of automatisch bestaat al"
+13 "blokuiteinde kon niet worden gevonden"
+14 "kan geen waarde uit de nietige functie teruggeven: %s()"
+15 "var kan geen referentie zijn: %s"
+16 "POSIX staat geen namen toe die langer zijn dan 1 teken: %s"
+17 "POSIX staat geen '#'-scriptcommentaar toe"
+18 "POSIX laat het volgende sleutelwoord niet toe: %s"
+19 "POSIX staat geen periode ('.') toe als een kortere weg voor het laatste resultaat"
+20 "POSIX vereist haakjes rond de terugkeeruitdrukkingen"
+21 "POSIX laat de volgende operator niet toe: %s"
+22 "POSIX laat geen vergelijking toe tussen operatoren buiten als verklaringen of lussen"
+23 "POSIX vereist 0 of 1 vergelijkingsoperator per conditie"
+24 "POSIX vereist dat alle 3 de delen van een lus niet leeg zijn"
+25 "POSIX laat geen exponentiële notatie toe"
+26 "POSIX staat geen arrayreferenties toe als functieparameters"
+27 "POSIX vereist dat de linkse beugel op dezelfde regel staat als de functiehoofding"
+
+$ Runtime fouten.
+$set 5
+
+1 "ongeldige ibase: moet [%lu, %lu] zijn"
+2 "ongeldige obase: moet [%lu, %lu] zijn"
+3 "ongeldige schaal: moet [%lu, %lu] zijn"
+4 "ongeldige read() expressie"
+5 "recursieve read() call"
+6 "Variabele of matrix-element is het verkeerde type"
+7 "Stapel heeft te weinig elementen"
+8 "Verkeerd aantal parameters; hebben %zu nodig, hebben %zu"
+9 "ongedefinieerde functie: %s()"
+10 "kan geen nietige waarde in een uitdrukking gebruiken"
+
+$ Fatale fouten.
+$set 6
+
+1 "geheugentoewijzing mislukt"
+2 "I/O-fout"
+3 "kon geen file openen: %s"
+4 "bestand is niet ASCII: %s"
+5 "pad is een directory: %s"
+6 "ongeldige opdrachtregeloptie: '%c' (%s)"
+
+$set 7
+
+1 "optie vereist een argument: '%c' (\"%s\")"
+2 "optie neemt geen argumenten aan: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/nl_NL.utf8.msg b/contrib/bc/locales/nl_NL.utf8.msg
new file mode 120000
index 000000000000..8a2e27531d70
--- /dev/null
+++ b/contrib/bc/locales/nl_NL.utf8.msg
@@ -0,0 +1 @@
+nl_NL.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/pl_PL.ISO8859-2.msg b/contrib/bc/locales/pl_PL.ISO8859-2.msg
new file mode 100644
index 000000000000..b1bbca8054e9
--- /dev/null
+++ b/contrib/bc/locales/pl_PL.ISO8859-2.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Ró¿ne wiadomo¶ci.
+$set 1
+
+1 "Funkcja:"
+
+$ Typy b³êdów.
+$set 2
+
+1 "B³±d matematyczny:"
+2 "B³±d parse'a:"
+3 "B³±d biegu:"
+4 "B³±d ¶miertelny:"
+5 "Ostrze¿enie:"
+
+$ B³êdy matematyczne.
+$set 3
+
+1 "liczba ujemna"
+2 "numer nieintegracyjny"
+3 "przelewanie: liczba nie mie¶ci siê w numerze sprzêtowym"
+4 "dzielenie przez 0"
+
+$ B³êdy Parse'a.
+$set 4
+
+1 "koniec akt"
+2 "niewa¿ny znak '%c'"
+3 "koniec sznurka nie móg³ byæ znaleziony"
+4 "koniec komentarza nie móg³ byæ znaleziony"
+5 "niewa¿ny token"
+6 "niewa¿ne wyra¿enie"
+7 "puste wyra¿enie"
+8 "niewa¿ny wyci±g z wydruku"
+9 "nieprawid³owa definicja funkcji"
+10 "nieprawid³owe przyporz±dkowanie: lewa strona musi byæ elementem scale, ibase, obase, last, var lub element array"
+11 "nie znaleziono zmiennej automatycznej"
+12 "parametr funkcji lub auto \"%s%s\" ju¿ istnieje"
+13 "koñca bloku nie mo¿na by³o znale¼æ"
+14 "nie mo¿e zwróciæ warto¶ci z funkcji void: %s()"
+15 "var nie mo¿e byæ odniesieniem: %s"
+16 "POSIX nie zezwala na nazwy d³u¿sze ni¿ 1 znak: %s"
+17 "POSIX nie pozwala na komentarze skryptu '#'"
+18 "POSIX nie pozwala na u¿ycie nastêpuj±cego s³owa kluczowego: %s"
+19 "POSIX nie dopuszcza kropki ('.') jako skrótu do ostatniego wyniku"
+20 "POSIX wymaga nawiasów wokó³ wyra¿eñ zwrotnych"
+21 "POSIX nie pozwala nastêpuj±cemu operatorowi: %s"
+22 "POSIX nie pozwala na porównywanie operatorów na zewn±trz, je¶li deklaracje lub pêtle"
+23 "POSIX wymaga 0 lub 1 operatora porównawczego na jeden warunek"
+24 "POSIX wymaga, aby wszystkie 3 czê¶ci pêtli nie by³y puste"
+25 "POSIX nie pozwala na notacjê wyk³adnicz±"
+26 "POSIX nie zezwala na odniesienia do tablicy jako parametrów funkcji"
+27 "POSIX wymaga, aby lewe usztywnienie znajdowa³o siê na tej samej linii co nag³ówek funkcji"
+
+$ B³êdy Runtime'u.
+$set 5
+
+1 "nieprawid³owa ibase: musi byæ [%lu, %lu]"
+2 "nieprawid³owa obase: musi byæ [%lu, %lu]"
+3 "nieprawid³owa scale: musi byæ [%lu, %lu]"
+4 "nieprawid³owe wyra¿enie read()"
+5 "powtarzalne wywo³anie read()"
+6 "element zmienny lub tablicowy jest niew³a¶ciwym typem"
+7 "stos ma zbyt ma³o elementów"
+8 "niew³a¶ciwa liczba parametrów; potrzeba %zu, maj± %zu"
+9 "niezdefiniowana funkcja: %s()"
+10 "nie mo¿e u¿yæ warto¶ci pustej w wyra¿eniu"
+
+$ Fatalne b³êdy.
+$set 6
+
+1 "Alokacja pamiêci nie powiod³a siê"
+2 "B³±d we/wy"
+3 "nie móg³ otworzyæ pliku: %s"
+4 "plik nie jest ASCII: %s"
+5 "¶cie¿ka to katalog: %s"
+6 "nieprawid³owa opcja wiersza poleceñ: '%c' (\"%s\")"
+
+$set 7
+
+1 "opcja wymaga argumentu: '%c' (\"%s\")"
+2 "opcja nie wymaga ¿adnych argumentów: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/pl_PL.UTF-8.msg b/contrib/bc/locales/pl_PL.UTF-8.msg
new file mode 100644
index 000000000000..58eee21267d1
--- /dev/null
+++ b/contrib/bc/locales/pl_PL.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Różne wiadomości.
+$set 1
+
+1 "Funkcja:"
+
+$ Typy błędów.
+$set 2
+
+1 "BÅ‚Ä…d matematyczny:"
+2 "BÅ‚Ä…d parse'a:"
+3 "BÅ‚Ä…d biegu:"
+4 "Błąd śmiertelny:"
+5 "Ostrzeżenie:"
+
+$ Błędy matematyczne.
+$set 3
+
+1 "liczba ujemna"
+2 "numer nieintegracyjny"
+3 "przelewanie: liczba nie mieści się w numerze sprzętowym"
+4 "dzielenie przez 0"
+
+$ Błędy Parse'a.
+$set 4
+
+1 "koniec akt"
+2 "nieważny znak '%c'"
+3 "koniec sznurka nie mógł być znaleziony"
+4 "koniec komentarza nie mógł być znaleziony"
+5 "nieważny token"
+6 "nieważne wyrażenie"
+7 "puste wyrażenie"
+8 "nieważny wyciąg z wydruku"
+9 "nieprawidłowa definicja funkcji"
+10 "nieprawidłowe przyporządkowanie: lewa strona musi być elementem scale, ibase, obase, last, var lub element array"
+11 "nie znaleziono zmiennej automatycznej"
+12 "parametr funkcji lub auto \"%s%s\" już istnieje"
+13 "końca bloku nie można było znaleźć"
+14 "nie może zwrócić wartości z funkcji void: %s()"
+15 "var nie może być odniesieniem: %s"
+16 "POSIX nie zezwala na nazwy dłuższe niż 1 znak: %s"
+17 "POSIX nie pozwala na komentarze skryptu '#'"
+18 "POSIX nie pozwala na użycie następującego słowa kluczowego: %s"
+19 "POSIX nie dopuszcza kropki ('.') jako skrótu do ostatniego wyniku"
+20 "POSIX wymaga nawiasów wokół wyrażeń zwrotnych"
+21 "POSIX nie pozwala następującemu operatorowi: %s"
+22 "POSIX nie pozwala na porównywanie operatorów na zewnątrz, jeśli deklaracje lub pętle"
+23 "POSIX wymaga 0 lub 1 operatora porównawczego na jeden warunek"
+24 "POSIX wymaga, aby wszystkie 3 części pętli nie były puste"
+25 "POSIX nie pozwala na notację wykładniczą"
+26 "POSIX nie zezwala na odniesienia do tablicy jako parametrów funkcji"
+27 "POSIX wymaga, aby lewe usztywnienie znajdowało się na tej samej linii co nagłówek funkcji"
+
+$ Błędy Runtime'u.
+$set 5
+
+1 "nieprawidłowa ibase: musi być [%lu, %lu]"
+2 "nieprawidłowa obase: musi być [%lu, %lu]"
+3 "nieprawidłowa scale: musi być [%lu, %lu]"
+4 "nieprawidłowe wyrażenie read()"
+5 "powtarzalne wywołanie read()"
+6 "element zmienny lub tablicowy jest niewłaściwym typem"
+7 "stos ma zbyt mało elementów"
+8 "niewłaściwa liczba parametrów; potrzeba %zu, mają %zu"
+9 "niezdefiniowana funkcja: %s()"
+10 "nie może użyć wartości pustej w wyrażeniu"
+
+$ Fatalne błędy.
+$set 6
+
+1 "Alokacja pamięci nie powiodła się"
+2 "BÅ‚Ä…d we/wy"
+3 "nie mógł otworzyć pliku: %s"
+4 "plik nie jest ASCII: %s"
+5 "ścieżka to katalog: %s"
+6 "nieprawidłowa opcja wiersza poleceń: '%c' (\"%s\")"
+
+$set 7
+
+1 "opcja wymaga argumentu: '%c' (\"%s\")"
+2 "opcja nie wymaga żadnych argumentów: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/pl_PL.utf8.msg b/contrib/bc/locales/pl_PL.utf8.msg
new file mode 120000
index 000000000000..319bdb87f39d
--- /dev/null
+++ b/contrib/bc/locales/pl_PL.utf8.msg
@@ -0,0 +1 @@
+pl_PL.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/pt_BR.ISO8859-1.msg b/contrib/bc/locales/pt_BR.ISO8859-1.msg
new file mode 120000
index 000000000000..b3c9b106ae13
--- /dev/null
+++ b/contrib/bc/locales/pt_BR.ISO8859-1.msg
@@ -0,0 +1 @@
+pt_PT.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/pt_BR.ISO8859-15.msg b/contrib/bc/locales/pt_BR.ISO8859-15.msg
new file mode 120000
index 000000000000..b3c9b106ae13
--- /dev/null
+++ b/contrib/bc/locales/pt_BR.ISO8859-15.msg
@@ -0,0 +1 @@
+pt_PT.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/pt_BR.UTF-8.msg b/contrib/bc/locales/pt_BR.UTF-8.msg
new file mode 120000
index 000000000000..7364db017fbf
--- /dev/null
+++ b/contrib/bc/locales/pt_BR.UTF-8.msg
@@ -0,0 +1 @@
+pt_PT.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/pt_BR.utf8.msg b/contrib/bc/locales/pt_BR.utf8.msg
new file mode 120000
index 000000000000..7364db017fbf
--- /dev/null
+++ b/contrib/bc/locales/pt_BR.utf8.msg
@@ -0,0 +1 @@
+pt_PT.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/pt_PT.ISO8859-1.msg b/contrib/bc/locales/pt_PT.ISO8859-1.msg
new file mode 100644
index 000000000000..055a8f48d47e
--- /dev/null
+++ b/contrib/bc/locales/pt_PT.ISO8859-1.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Função:"
+
+$ Error types.
+$set 2
+
+1 "Erro de cálculo:"
+2 "Erro de análise de sintaxe:"
+3 "Erro de execução:"
+4 "Erro fatal:"
+5 "Aviso:"
+
+$ Math errors.
+$set 3
+
+1 "número negativo"
+2 "número não inteiro"
+3 "Estouro: número não cabe no registro"
+4 "dividir por 0"
+
+$ Parse errors.
+$set 4
+
+1 "fim do arquivo"
+2 "caractere inválido '%c'"
+3 "Não foi possível encontrar o final da string"
+4 "Não foi possível encontrar o final do comentário"
+5 "token inválido"
+6 "expressão inválida"
+7 "expressão vazia"
+8 "instrução de gravação inválida"
+9 "definição de função inválida"
+10 "atribuição inválida: a parte esquerda deve ser 'scale', 'ibase', 'obase', 'last', uma variável ou um elemento da matriz"
+11 "nenhuma variável automática encontrada"
+12 "parâmetro de função ou variável automática \"%s%s\" já existe"
+13 "fim do bloco não encontrado"
+14 "uma função 'void' não pode retornar um valor: %s()"
+15 "Uma variável não pode ser uma referência: %s"
+16 "POSIX não permite nomes com mais de 1 caractere: %s"
+17 "POSIX não permite comentários de script '#'"
+18 "POSIX não permite a seguinte palavra-chave: %s"
+19 "POSIX não permite um ponto ('.') como um atalho para o último resultado"
+20 "POSIX requer parênteses em torno de expressões de retorno"
+21 "POSIX não permite o seguinte operador: %s"
+22 "POSIX não permite operadores de comparação fora das expressões 'if' ou loops"
+23 "POSIX requer operadores 0 ou 1 de comparação por condição"
+24 "POSIX não permite uma expressão vazia em um loop 'for'"
+25 "POSIX não permite notação exponencial"
+26 "POSIX não permite referências de matriz como parâmetros de função"
+27 "POSIX requer que o cabeçalho da função '{' estejam na mesma linha"
+
+$ Runtime errors.
+$set 5
+
+1 "ibase inválido: deve ser [%lu, %lu]"
+2 "obase inválido: deve ser [%lu, %lu]"
+3 "scale inválida: deve ser [%lu, %lu]"
+4 "expressão read() inválida"
+5 "chamada read() recursiva"
+6 "tipo errado de variável ou elemento de matriz"
+7 "pilha tem poucos elementos"
+8 "número incorreto de parâmetros - esperado: %zu, obtido: %zu"
+9 "função indefinida: %s()"
+10 "um valor 'void' não pode ser usado em uma expressão"
+
+$ Fatal errors.
+$set 6
+
+1 "falha na alocação de memória"
+2 "erro de entrada-saída"
+3 "impossível abrir o arquivo: %s"
+4 "arquivo não é ASCII: %s"
+5 "caminho é um diretório: %s"
+6 "opção de linha de comando inválida: \"%s\""
+7 "opção requer um argumento: '%c' (\"%s\")"
+8 "a opção não aceita argumentos: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/pt_PT.ISO8859-15.msg b/contrib/bc/locales/pt_PT.ISO8859-15.msg
new file mode 120000
index 000000000000..b3c9b106ae13
--- /dev/null
+++ b/contrib/bc/locales/pt_PT.ISO8859-15.msg
@@ -0,0 +1 @@
+pt_PT.ISO8859-1.msg \ No newline at end of file
diff --git a/contrib/bc/locales/pt_PT.UTF-8.msg b/contrib/bc/locales/pt_PT.UTF-8.msg
new file mode 100644
index 000000000000..b07e58228eb3
--- /dev/null
+++ b/contrib/bc/locales/pt_PT.UTF-8.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Função:"
+
+$ Error types.
+$set 2
+
+1 "Erro de cálculo:"
+2 "Erro de análise de sintaxe:"
+3 "Erro de execução:"
+4 "Erro fatal:"
+5 "Aviso:"
+
+$ Math errors.
+$set 3
+
+1 "número negativo"
+2 "número não inteiro"
+3 "Estouro: número não cabe no registro"
+4 "dividir por 0"
+
+$ Parse errors.
+$set 4
+
+1 "fim do arquivo"
+2 "caractere inválido '%c'"
+3 "Não foi possível encontrar o final da string"
+4 "Não foi possível encontrar o final do comentário"
+5 "token inválido"
+6 "expressão inválida"
+7 "expressão vazia"
+8 "instrução de gravação inválida"
+9 "definição de função inválida"
+10 "atribuição inválida: a parte esquerda deve ser 'scale', 'ibase', 'obase', 'last', uma variável ou um elemento da matriz"
+11 "nenhuma variável automática encontrada"
+12 "parâmetro de função ou variável automática \"%s%s\" já existe"
+13 "fim do bloco não encontrado"
+14 "uma função 'void' não pode retornar um valor: %s()"
+15 "Uma variável não pode ser uma referência: %s"
+16 "POSIX não permite nomes com mais de 1 caractere: %s"
+17 "POSIX não permite comentários de script '#'"
+18 "POSIX não permite a seguinte palavra-chave: %s"
+19 "POSIX não permite um ponto ('.') como um atalho para o último resultado"
+20 "POSIX requer parênteses em torno de expressões de retorno"
+21 "POSIX não permite o seguinte operador: %s"
+22 "POSIX não permite operadores de comparação fora das expressões 'if' ou loops"
+23 "POSIX requer operadores 0 ou 1 de comparação por condição"
+24 "POSIX não permite uma expressão vazia em um loop 'for'"
+25 "POSIX não permite notação exponencial"
+26 "POSIX não permite referências de matriz como parâmetros de função"
+27 "POSIX requer que o cabeçalho da função '{' estejam na mesma linha"
+
+$ Runtime errors.
+$set 5
+
+1 "ibase inválido: deve ser [%lu, %lu]"
+2 "obase inválido: deve ser [%lu, %lu]"
+3 "scale inválida: deve ser [%lu, %lu]"
+4 "expressão read() inválida"
+5 "chamada read() recursiva"
+6 "tipo errado de variável ou elemento de matriz"
+7 "pilha tem poucos elementos"
+8 "número incorreto de parâmetros - esperado: %zu, obtido: %zu"
+9 "função indefinida: %s()"
+10 "um valor 'void' não pode ser usado em uma expressão"
+
+$ Fatal errors.
+$set 6
+
+1 "falha na alocação de memória"
+2 "erro de entrada-saída"
+3 "impossível abrir o arquivo: %s"
+4 "arquivo não é ASCII: %s"
+5 "caminho é um diretório: %s"
+6 "opção de linha de comando inválida: \"%s\""
+7 "opção requer um argumento: '%c' (\"%s\")"
+8 "a opção não aceita argumentos: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/pt_PT.utf8.msg b/contrib/bc/locales/pt_PT.utf8.msg
new file mode 120000
index 000000000000..7364db017fbf
--- /dev/null
+++ b/contrib/bc/locales/pt_PT.utf8.msg
@@ -0,0 +1 @@
+pt_PT.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/ru_RU.CP1251.msg b/contrib/bc/locales/ru_RU.CP1251.msg
new file mode 100644
index 000000000000..d54a7bf51fda
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.CP1251.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Ðàçíûå ñîîáùåíèÿ.
+$set 1
+
+1 "Ôóíêöèÿ:"
+
+$ Òèïû îøèáîê.
+$set 2
+
+1 "Ìàòåìàòè÷åñêàÿ îøèáêà:"
+2 "Îøèáêà ïðè ðàçáîðå:"
+3 "Îøèáêà âûïîëíåíèÿ:"
+4 "Ôàòàëüíàÿ îøèáêà:"
+5 "Ïðåäóïðåæäåíèå:"
+
+$ Ìàòåìàòè÷åñêèå îøèáêè.
+$set 3
+
+1 "îòðèöàòåëüíîå ÷èñëî"
+2 "íåèíòåãðèðîâàííîå ÷èñëî"
+3 "ïåðåïîëíåíèå: íîìåð íå ïîìåùàåòñÿ â àïïàðàòíûé íîìåð"
+4 "äåëèòü íà 0"
+
+$ Îøèáêè ïðè ðàçáîðå.
+$set 4
+
+1 "êîíåö ôàéëà"
+2 "íåäîïóñòèìûé ñèìâîë '%c'"
+3 "êîíåö ñòðîêè íå íàéäåí"
+4 "êîíåö êîììåíòàðèÿ íå íàéäåí"
+5 "íåäåéñòâèòåëüíûé æåòîí"
+6 "íåïðàâèëüíîå âûðàæåíèå"
+7 "ïóñòîå âûðàæåíèå"
+8 "çàÿâëåíèå î íåäåéñòâèòåëüíîñòè ïå÷àòè"
+9 "îïðåäåëåíèå íåäåéñòâèòåëüíîé ôóíêöèè"
+10 "íåâåðíîå ïðèñâîåíèå: ëåâàÿ ñòîðîíà äîëæíà áûòü scale, ibase, obase, last, âàðîì èëè ýëåìåíòîì ìàññèâà"
+11 "àâòîìàòè÷åñêàÿ ïåðåìåííàÿ íå íàéäåíà"
+12 "ïàðàìåòð ôóíêöèè èëè auto \"%s%s\" óæå ñóùåñòâóåò"
+13 "êîíåö áëîêà íå íàéäåí"
+14 "íå ìîæåò âåðíóòü çíà÷åíèå èç ôóíêöèè void: %s()"
+15 "var íå ìîæåò áûòü ññûëêîé: %s"
+16 "POSIX íå äîïóñêàåò èìåí äëèííåå 1 ñèìâîëà: %s"
+17 "POSIX íå äîïóñêàåò êîììåíòàðèåâ ê ñöåíàðèþ '#'"
+18 "POSIX íå äîïóñêàåò ñëåäóþùåå êëþ÷åâîå ñëîâî: %s"
+19 "POSIX íå äîïóñêàåò òî÷êó ('.') â êà÷åñòâå ÿðëûêà äëÿ ïîñëåäíåãî ðåçóëüòàòà"
+20 "POSIX òðåáóåò ñêîáîê âîêðóã âûðàæåíèé âîçâðàòà"
+21 "POSIX íå ðàçðåøàåò èñïîëüçîâàòü ñëåäóþùèé îïåðàòîð: %s"
+22 "POSIX íå ðàçðåøàåò îïåðàòîðàì ñðàâíåíèÿ âûõîäèòü çà ïðåäåëû, åñëè óòâåðæäåíèÿ èëè öèêëû"
+23 "POSIX òðåáóåò 0 èëè 1 îïåðàòîðà ñðàâíåíèÿ íà óñëîâèå"
+24 "POSIX òðåáóåò, ÷òîáû âñå 3 ÷àñòè ïåòëè áûëè íåïóñòûìè"
+25 "POSIX íå äîïóñêàåò ýêñïîíåíöèàëüíîé íîòàöèè"
+26 "POSIX íå äîïóñêàåò ññûëêè íà ìàññèâ â êà÷åñòâå ïàðàìåòðîâ ôóíêöèè"
+27 "POSIX òðåáóåò, ÷òîáû ëåâàÿ ñêîáêà áûëà íà òîé æå ëèíèè, ÷òî è çàãîëîâîê ôóíêöèè"
+
+$ Îøèáêè âûïîëíåíèÿ.
+$set 5
+
+1 "Íåäåéñòâèòåëüíûé ibase: äîëæåí áûòü [%lu, %lu]"
+2 "Íåäåéñòâèòåëüíûé obase: äîëæåí áûòü [%lu, %lu]"
+3 "íåäåéñòâèòåëüíàÿ scale: äîëæíà áûòü [%lu, %lu]"
+4 "íåäåéñòâèòåëüíîå âûðàæåíèå read()"
+5 "ðåêóðñèâíûé âûçîâ read()"
+6 "ïåðåìåííàÿ èëè ýëåìåíò ìàññèâà ÿâëÿåòñÿ íåïðàâèëüíûì òèïîì"
+7 "ñòîïêà èìååò ñëèøêîì ìàëî ýëåìåíòîâ"
+8 "íåïðàâèëüíîå êîëè÷åñòâî ïàðàìåòðîâ; íóæíî %zu, íóæíî %zu"
+9 "íåîïðåäåëåííàÿ ôóíêöèÿ: %s()"
+10 "íå ìîæåò èñïîëüçîâàòü ïóñòîå çíà÷åíèå â âûðàæåíèè"
+
+$ Ôàòàëüíûå îøèáêè.
+$set 6
+
+1 "Íå óäàëîñü âûäåëèòü ïàìÿòü"
+2 "Îøèáêà ââîäà/âûâîäà"
+3 "íå ñìîã îòêðûòü ôàéë: %s"
+4 "ôàéë íå ASCII: %s"
+5 "ïóòü - ýòî êàòàëîã: %s"
+6 "íåâåðíàÿ îïöèÿ êîìàíäíîé ñòðîêè: '%c' (\"%s\")"
+
+$set 7
+
+1 "îïöèÿ òðåáóåò àðãóìåíòà: '%c' (\"%s\")"
+2 "îïöèÿ íå ïðèíèìàåò àðãóìåíòîâ: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/ru_RU.CP866.msg b/contrib/bc/locales/ru_RU.CP866.msg
new file mode 100644
index 000000000000..44325a832dcd
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.CP866.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$  §­ë¥ á®®¡é¥­¨ï.
+$set 1
+
+1 "”ã­ªæ¨ï:"
+
+$ ’¨¯ë ®è¨¡®ª.
+$set 2
+
+1 "Œ â¥¬ â¨ç¥áª ï ®è¨¡ª :"
+2 "Žè¨¡ª  ¯à¨ à §¡®à¥:"
+3 "Žè¨¡ª  ¢ë¯®«­¥­¨ï:"
+4 "” â «ì­ ï ®è¨¡ª :"
+5 "।ã¯à¥¦¤¥­¨¥:"
+
+$ Œ â¥¬ â¨ç¥áª¨¥ ®è¨¡ª¨.
+$set 3
+
+1 "®âà¨æ â¥«ì­®¥ ç¨á«®"
+2 "­¥¨­â¥£à¨à®¢ ­­®¥ ç¨á«®"
+3 "¯¥à¥¯®«­¥­¨¥: ­®¬¥à ­¥ ¯®¬¥é ¥âáï ¢  ¯¯ à â­ë© ­®¬¥à"
+4 "¤¥«¨âì ­  0"
+
+$ Žè¨¡ª¨ ¯à¨ à §¡®à¥.
+$set 4
+
+1 "ª®­¥æ ä ©« "
+2 "­¥¤®¯ãáâ¨¬ë© á¨¬¢®« '%c'"
+3 "ª®­¥æ áâப¨ ­¥ ­ ©¤¥­"
+4 "ª®­¥æ ª®¬¬¥­â à¨ï ­¥ ­ ©¤¥­"
+5 "­¥¤¥©á⢨⥫ì­ë© ¦¥â®­"
+6 "­¥¯à ¢¨«ì­®¥ ¢ëà ¦¥­¨¥"
+7 "¯ãá⮥ ¢ëà ¦¥­¨¥"
+8 "§ ï¢«¥­¨¥ ® ­¥¤¥©á⢨⥫쭮á⨠¯¥ç â¨"
+9 "®¯à¥¤¥«¥­¨¥ ­¥¤¥©á⢨⥫쭮© ä㭪樨"
+10 "­¥¢¥à­®¥ ¯à¨á¢®¥­¨¥: «¥¢ ï áâ®à®­  ¤®«¦­  ¡ëâì scale, ibase, obase, last, ¢ à®¬ ¨«¨ í«¥¬¥­â®¬ ¬ áᨢ "
+11 " ¢â®¬ â¨ç¥áª ï ¯¥à¥¬¥­­ ï ­¥ ­ ©¤¥­ "
+12 "¯ à ¬¥âà ä㭪樨 ¨«¨ auto \"%s%s\" 㦥 áãé¥áâ¢ã¥â"
+13 "ª®­¥æ ¡«®ª  ­¥ ­ ©¤¥­"
+14 "­¥ ¬®¦¥â ¢¥à­ãâì §­ ç¥­¨¥ ¨§ ä㭪樨 void: %s()"
+15 "var ­¥ ¬®¦¥â ¡ëâì áá뫪®©: %s"
+16 "POSIX ­¥ ¤®¯ã᪠¥â ¨¬¥­ ¤«¨­­¥¥ 1 ᨬ¢®« : %s"
+17 "POSIX ­¥ ¤®¯ã᪠¥â ª®¬¬¥­â à¨¥¢ ª á業 à¨î '#'"
+18 "POSIX ­¥ ¤®¯ã᪠¥â á«¥¤ãî饥 ª«î祢®¥ á«®¢®: %s"
+19 "POSIX ­¥ ¤®¯ã᪠¥â â®çªã ('.') ¢ ª ç¥á⢥ ïà«ëª  ¤«ï ¯®á«¥¤­¥£® १ã«ìâ â "
+20 "POSIX âॡã¥â ᪮¡®ª ¢®ªà㣠¢ëà ¦¥­¨© ¢®§¢à â "
+21 "POSIX ­¥ à §à¥è ¥â ¨á¯®«ì§®¢ âì á«¥¤ãî騩 ®¯¥à â®à: %s"
+22 "POSIX ­¥ à §à¥è ¥â ®¯¥à â®à ¬ áà ¢­¥­¨ï ¢ë室¨âì §  ¯à¥¤¥«ë, ¥á«¨ ã⢥ত¥­¨ï ¨«¨ 横«ë"
+23 "POSIX âॡã¥â 0 ¨«¨ 1 ®¯¥à â®à  áà ¢­¥­¨ï ­  ãá«®¢¨¥"
+24 "POSIX âॡã¥â, çâ®¡ë ¢á¥ 3 ç á⨠¯¥â«¨ ¡ë«¨ ­¥¯ãáâ묨"
+25 "POSIX ­¥ ¤®¯ã᪠¥â íªá¯®­¥­æ¨ «ì­®© ­®â æ¨¨"
+26 "POSIX ­¥ ¤®¯ã᪠¥â áá뫪¨ ­  ¬ áᨢ ¢ ª ç¥á⢥ ¯ à ¬¥â஢ ä㭪樨"
+27 "POSIX âॡã¥â, çâ®¡ë «¥¢ ï ᪮¡ª  ¡ë«  ­  ⮩ ¦¥ «¨­¨¨, çâ® ¨ § £®«®¢®ª ä㭪樨"
+
+$ Žè¨¡ª¨ ¢ë¯®«­¥­¨ï.
+$set 5
+
+1 "¥¤¥©á⢨⥫ì­ë© ibase: ¤®«¦¥­ ¡ëâì [%lu, %lu]"
+2 "¥¤¥©á⢨⥫ì­ë© obase: ¤®«¦¥­ ¡ëâì [%lu, %lu]"
+3 "­¥¤¥©á⢨⥫쭠ï scale: ¤®«¦­  ¡ëâì [%lu, %lu]"
+4 "­¥¤¥©á⢨⥫쭮¥ ¢ëà ¦¥­¨¥ read()"
+5 "४ãàᨢ­ë© ¢ë§®¢ read()"
+6 "¯¥à¥¬¥­­ ï ¨«¨ í«¥¬¥­â ¬ áᨢ  ï¥âáï ­¥¯à ¢¨«ì­ë¬ ⨯®¬"
+7 "á⮯ª  ¨¬¥¥â ᫨誮¬ ¬ «® í«¥¬¥­â®¢"
+8 "­¥¯à ¢¨«ì­®¥ ª®«¨ç¥á⢮ ¯ à ¬¥â஢; ­ã¦­® %zu, ­ã¦­® %zu"
+9 "­¥®¯à¥¤¥«¥­­ ï äã­ªæ¨ï: %s()"
+10 "­¥ ¬®¦¥â ¨á¯®«ì§®¢ âì ¯ãá⮥ §­ ç¥­¨¥ ¢ ¢ëà ¦¥­¨¨"
+
+$ ” â «ì­ë¥ ®è¨¡ª¨.
+$set 6
+
+1 "¥ 㤠«®áì ¢ë¤¥«¨âì ¯ ¬ïâì"
+2 "Žè¨¡ª  ¢¢®¤ /¢ë¢®¤ "
+3 "­¥ ᬮ£ ®âªàëâì ä ©«: %s"
+4 "ä ©« ­¥ ASCII: %s"
+5 "¯ãâì - íâ® ª â «®£: %s"
+6 "­¥¢¥à­ ï ®¯æ¨ï ª®¬ ­¤­®© áâப¨: '%c' (\"%s\")"
+
+$set 7
+
+1 "®¯æ¨ï âॡã¥â  à£ã¬¥­â : '%c' (\"%s\")"
+2 "®¯æ¨ï ­¥ ¯à¨­¨¬ ¥â  à£ã¬¥­â®¢: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/ru_RU.ISO8859-5.msg b/contrib/bc/locales/ru_RU.ISO8859-5.msg
new file mode 100644
index 000000000000..c4f314c5c32b
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.ISO8859-5.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ ÀÐ×ÝëÕ áÞÞÑéÕÝØï.
+$set 1
+
+1 "ÄãÝÚæØï:"
+
+$ ÂØßë ÞèØÑÞÚ.
+$set 2
+
+1 "¼ÐâÕÜÐâØçÕáÚÐï ÞèØÑÚÐ:"
+2 "¾èØÑÚÐ ßàØ àÐ×ÑÞàÕ:"
+3 "¾èØÑÚÐ ÒëßÞÛÝÕÝØï:"
+4 "ÄÐâÐÛìÝÐï ÞèØÑÚÐ:"
+5 "¿àÕÔãßàÕÖÔÕÝØÕ:"
+
+$ ¼ÐâÕÜÐâØçÕáÚØÕ ÞèØÑÚØ.
+$set 3
+
+1 "ÞâàØæÐâÕÛìÝÞÕ çØáÛÞ"
+2 "ÝÕØÝâÕÓàØàÞÒÐÝÝÞÕ çØáÛÞ"
+3 "ßÕàÕßÞÛÝÕÝØÕ: ÝÞÜÕà ÝÕ ßÞÜÕéÐÕâáï Ò ÐßßÐàÐâÝëÙ ÝÞÜÕà"
+4 "ÔÕÛØâì ÝÐ 0"
+
+$ ¾èØÑÚØ ßàØ àÐ×ÑÞàÕ.
+$set 4
+
+1 "ÚÞÝÕæ äÐÙÛÐ"
+2 "ÝÕÔÞßãáâØÜëÙ áØÜÒÞÛ '%c'"
+3 "ÚÞÝÕæ áâàÞÚØ ÝÕ ÝÐÙÔÕÝ"
+4 "ÚÞÝÕæ ÚÞÜÜÕÝâÐàØï ÝÕ ÝÐÙÔÕÝ"
+5 "ÝÕÔÕÙáâÒØâÕÛìÝëÙ ÖÕâÞÝ"
+6 "ÝÕßàÐÒØÛìÝÞÕ ÒëàÐÖÕÝØÕ"
+7 "ßãáâÞÕ ÒëàÐÖÕÝØÕ"
+8 "×ÐïÒÛÕÝØÕ Þ ÝÕÔÕÙáâÒØâÕÛìÝÞáâØ ßÕçÐâØ"
+9 "ÞßàÕÔÕÛÕÝØÕ ÝÕÔÕÙáâÒØâÕÛìÝÞÙ äãÝÚæØØ"
+10 "ÝÕÒÕàÝÞÕ ßàØáÒÞÕÝØÕ: ÛÕÒÐï áâÞàÞÝÐ ÔÞÛÖÝÐ Ñëâì scale, ibase, obase, last, ÒÐàÞÜ ØÛØ íÛÕÜÕÝâÞÜ ÜÐááØÒÐ"
+11 "ÐÒâÞÜÐâØçÕáÚÐï ßÕàÕÜÕÝÝÐï ÝÕ ÝÐÙÔÕÝÐ"
+12 "ßÐàÐÜÕâà äãÝÚæØØ ØÛØ auto \"%s%s\" ãÖÕ áãéÕáâÒãÕâ"
+13 "ÚÞÝÕæ ÑÛÞÚÐ ÝÕ ÝÐÙÔÕÝ"
+14 "ÝÕ ÜÞÖÕâ ÒÕàÝãâì ×ÝÐçÕÝØÕ Ø× äãÝÚæØØ void: %s()"
+15 "var ÝÕ ÜÞÖÕâ Ñëâì ááëÛÚÞÙ: %s"
+16 "POSIX ÝÕ ÔÞßãáÚÐÕâ ØÜÕÝ ÔÛØÝÝÕÕ 1 áØÜÒÞÛÐ: %s"
+17 "POSIX ÝÕ ÔÞßãáÚÐÕâ ÚÞÜÜÕÝâÐàØÕÒ Ú áæÕÝÐàØî '#'"
+18 "POSIX ÝÕ ÔÞßãáÚÐÕâ áÛÕÔãîéÕÕ ÚÛîçÕÒÞÕ áÛÞÒÞ: %s"
+19 "POSIX ÝÕ ÔÞßãáÚÐÕâ âÞçÚã ('.') Ò ÚÐçÕáâÒÕ ïàÛëÚÐ ÔÛï ßÞáÛÕÔÝÕÓÞ àÕ×ãÛìâÐâÐ"
+20 "POSIX âàÕÑãÕâ áÚÞÑÞÚ ÒÞÚàãÓ ÒëàÐÖÕÝØÙ ÒÞ×ÒàÐâÐ"
+21 "POSIX ÝÕ àÐ×àÕèÐÕâ ØáßÞÛì×ÞÒÐâì áÛÕÔãîéØÙ ÞßÕàÐâÞà: %s"
+22 "POSIX ÝÕ àÐ×àÕèÐÕâ ÞßÕàÐâÞàÐÜ áàÐÒÝÕÝØï ÒëåÞÔØâì ×Ð ßàÕÔÕÛë, ÕáÛØ ãâÒÕàÖÔÕÝØï ØÛØ æØÚÛë"
+23 "POSIX âàÕÑãÕâ 0 ØÛØ 1 ÞßÕàÐâÞàÐ áàÐÒÝÕÝØï ÝÐ ãáÛÞÒØÕ"
+24 "POSIX âàÕÑãÕâ, çâÞÑë ÒáÕ 3 çÐáâØ ßÕâÛØ ÑëÛØ ÝÕßãáâëÜØ"
+25 "POSIX ÝÕ ÔÞßãáÚÐÕâ íÚáßÞÝÕÝæØÐÛìÝÞÙ ÝÞâÐæØØ"
+26 "POSIX ÝÕ ÔÞßãáÚÐÕâ ááëÛÚØ ÝÐ ÜÐááØÒ Ò ÚÐçÕáâÒÕ ßÐàÐÜÕâàÞÒ äãÝÚæØØ"
+27 "POSIX âàÕÑãÕâ, çâÞÑë ÛÕÒÐï áÚÞÑÚÐ ÑëÛÐ ÝÐ âÞÙ ÖÕ ÛØÝØØ, çâÞ Ø ×ÐÓÞÛÞÒÞÚ äãÝÚæØØ"
+
+$ ¾èØÑÚØ ÒëßÞÛÝÕÝØï.
+$set 5
+
+1 "½ÕÔÕÙáâÒØâÕÛìÝëÙ ibase: ÔÞÛÖÕÝ Ñëâì [%lu, %lu]"
+2 "½ÕÔÕÙáâÒØâÕÛìÝëÙ obase: ÔÞÛÖÕÝ Ñëâì [%lu, %lu]"
+3 "ÝÕÔÕÙáâÒØâÕÛìÝÐï scale: ÔÞÛÖÝÐ Ñëâì [%lu, %lu]"
+4 "ÝÕÔÕÙáâÒØâÕÛìÝÞÕ ÒëàÐÖÕÝØÕ read()"
+5 "àÕÚãàáØÒÝëÙ Òë×ÞÒ read()"
+6 "ßÕàÕÜÕÝÝÐï ØÛØ íÛÕÜÕÝâ ÜÐááØÒÐ ïÒÛïÕâáï ÝÕßàÐÒØÛìÝëÜ âØßÞÜ"
+7 "áâÞßÚÐ ØÜÕÕâ áÛØèÚÞÜ ÜÐÛÞ íÛÕÜÕÝâÞÒ"
+8 "ÝÕßàÐÒØÛìÝÞÕ ÚÞÛØçÕáâÒÞ ßÐàÐÜÕâàÞÒ; ÝãÖÝÞ %zu, ÝãÖÝÞ %zu"
+9 "ÝÕÞßàÕÔÕÛÕÝÝÐï äãÝÚæØï: %s()"
+10 "ÝÕ ÜÞÖÕâ ØáßÞÛì×ÞÒÐâì ßãáâÞÕ ×ÝÐçÕÝØÕ Ò ÒëàÐÖÕÝØØ"
+
+$ ÄÐâÐÛìÝëÕ ÞèØÑÚØ.
+$set 6
+
+1 "½Õ ãÔÐÛÞáì ÒëÔÕÛØâì ßÐÜïâì"
+2 "¾èØÑÚÐ ÒÒÞÔÐ/ÒëÒÞÔÐ"
+3 "ÝÕ áÜÞÓ ÞâÚàëâì äÐÙÛ: %s"
+4 "äÐÙÛ ÝÕ ASCII: %s"
+5 "ßãâì - íâÞ ÚÐâÐÛÞÓ: %s"
+6 "ÝÕÒÕàÝÐï ÞßæØï ÚÞÜÐÝÔÝÞÙ áâàÞÚØ: '%c' (\"%s\")"
+
+$set 7
+
+1 "ÞßæØï âàÕÑãÕâ ÐàÓãÜÕÝâÐ: '%c' (\"%s\")"
+2 "ÞßæØï ÝÕ ßàØÝØÜÐÕâ ÐàÓãÜÕÝâÞÒ: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/ru_RU.KOI8-R.msg b/contrib/bc/locales/ru_RU.KOI8-R.msg
new file mode 100644
index 000000000000..991845680d49
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.KOI8-R.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ òÁÚÎÙÅ ÓÏÏÂÝÅÎÉÑ.
+$set 1
+
+1 "æÕÎËÃÉÑ:"
+
+$ ôÉÐÙ ÏÛÉÂÏË.
+$set 2
+
+1 "íÁÔÅÍÁÔÉÞÅÓËÁÑ ÏÛÉÂËÁ:"
+2 "ïÛÉÂËÁ ÐÒÉ ÒÁÚÂÏÒÅ:"
+3 "ïÛÉÂËÁ ×ÙÐÏÌÎÅÎÉÑ:"
+4 "æÁÔÁÌØÎÁÑ ÏÛÉÂËÁ:"
+5 "ðÒÅÄÕÐÒÅÖÄÅÎÉÅ:"
+
+$ íÁÔÅÍÁÔÉÞÅÓËÉÅ ÏÛÉÂËÉ.
+$set 3
+
+1 "ÏÔÒÉÃÁÔÅÌØÎÏÅ ÞÉÓÌÏ"
+2 "ÎÅÉÎÔÅÇÒÉÒÏ×ÁÎÎÏÅ ÞÉÓÌÏ"
+3 "ÐÅÒÅÐÏÌÎÅÎÉÅ: ÎÏÍÅÒ ÎÅ ÐÏÍÅÝÁÅÔÓÑ × ÁÐÐÁÒÁÔÎÙÊ ÎÏÍÅÒ"
+4 "ÄÅÌÉÔØ ÎÁ 0"
+
+$ ïÛÉÂËÉ ÐÒÉ ÒÁÚÂÏÒÅ.
+$set 4
+
+1 "ËÏÎÅÃ ÆÁÊÌÁ"
+2 "ÎÅÄÏÐÕÓÔÉÍÙÊ ÓÉÍ×ÏÌ '%c'"
+3 "ËÏÎÅÃ ÓÔÒÏËÉ ÎÅ ÎÁÊÄÅÎ"
+4 "ËÏÎÅÃ ËÏÍÍÅÎÔÁÒÉÑ ÎÅ ÎÁÊÄÅÎ"
+5 "ÎÅÄÅÊÓÔ×ÉÔÅÌØÎÙÊ ÖÅÔÏÎ"
+6 "ÎÅÐÒÁ×ÉÌØÎÏÅ ×ÙÒÁÖÅÎÉÅ"
+7 "ÐÕÓÔÏÅ ×ÙÒÁÖÅÎÉÅ"
+8 "ÚÁÑ×ÌÅÎÉÅ Ï ÎÅÄÅÊÓÔ×ÉÔÅÌØÎÏÓÔÉ ÐÅÞÁÔÉ"
+9 "ÏÐÒÅÄÅÌÅÎÉÅ ÎÅÄÅÊÓÔ×ÉÔÅÌØÎÏÊ ÆÕÎËÃÉÉ"
+10 "ÎÅ×ÅÒÎÏÅ ÐÒÉÓ×ÏÅÎÉÅ: ÌÅ×ÁÑ ÓÔÏÒÏÎÁ ÄÏÌÖÎÁ ÂÙÔØ scale, ibase, obase, last, ×ÁÒÏÍ ÉÌÉ ÜÌÅÍÅÎÔÏÍ ÍÁÓÓÉ×Á"
+11 "Á×ÔÏÍÁÔÉÞÅÓËÁÑ ÐÅÒÅÍÅÎÎÁÑ ÎÅ ÎÁÊÄÅÎÁ"
+12 "ÐÁÒÁÍÅÔÒ ÆÕÎËÃÉÉ ÉÌÉ auto \"%s%s\" ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ"
+13 "ËÏÎÅÃ ÂÌÏËÁ ÎÅ ÎÁÊÄÅÎ"
+14 "ÎÅ ÍÏÖÅÔ ×ÅÒÎÕÔØ ÚÎÁÞÅÎÉÅ ÉÚ ÆÕÎËÃÉÉ void: %s()"
+15 "var ÎÅ ÍÏÖÅÔ ÂÙÔØ ÓÓÙÌËÏÊ: %s"
+16 "POSIX ÎÅ ÄÏÐÕÓËÁÅÔ ÉÍÅÎ ÄÌÉÎÎÅÅ 1 ÓÉÍ×ÏÌÁ: %s"
+17 "POSIX ÎÅ ÄÏÐÕÓËÁÅÔ ËÏÍÍÅÎÔÁÒÉÅ× Ë ÓÃÅÎÁÒÉÀ '#'"
+18 "POSIX ÎÅ ÄÏÐÕÓËÁÅÔ ÓÌÅÄÕÀÝÅÅ ËÌÀÞÅ×ÏÅ ÓÌÏ×Ï: %s"
+19 "POSIX ÎÅ ÄÏÐÕÓËÁÅÔ ÔÏÞËÕ ('.') × ËÁÞÅÓÔ×Å ÑÒÌÙËÁ ÄÌÑ ÐÏÓÌÅÄÎÅÇÏ ÒÅÚÕÌØÔÁÔÁ"
+20 "POSIX ÔÒÅÂÕÅÔ ÓËÏÂÏË ×ÏËÒÕÇ ×ÙÒÁÖÅÎÉÊ ×ÏÚ×ÒÁÔÁ"
+21 "POSIX ÎÅ ÒÁÚÒÅÛÁÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÓÌÅÄÕÀÝÉÊ ÏÐÅÒÁÔÏÒ: %s"
+22 "POSIX ÎÅ ÒÁÚÒÅÛÁÅÔ ÏÐÅÒÁÔÏÒÁÍ ÓÒÁ×ÎÅÎÉÑ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ, ÅÓÌÉ ÕÔ×ÅÒÖÄÅÎÉÑ ÉÌÉ ÃÉËÌÙ"
+23 "POSIX ÔÒÅÂÕÅÔ 0 ÉÌÉ 1 ÏÐÅÒÁÔÏÒÁ ÓÒÁ×ÎÅÎÉÑ ÎÁ ÕÓÌÏ×ÉÅ"
+24 "POSIX ÔÒÅÂÕÅÔ, ÞÔÏÂÙ ×ÓÅ 3 ÞÁÓÔÉ ÐÅÔÌÉ ÂÙÌÉ ÎÅÐÕÓÔÙÍÉ"
+25 "POSIX ÎÅ ÄÏÐÕÓËÁÅÔ ÜËÓÐÏÎÅÎÃÉÁÌØÎÏÊ ÎÏÔÁÃÉÉ"
+26 "POSIX ÎÅ ÄÏÐÕÓËÁÅÔ ÓÓÙÌËÉ ÎÁ ÍÁÓÓÉ× × ËÁÞÅÓÔ×Å ÐÁÒÁÍÅÔÒÏ× ÆÕÎËÃÉÉ"
+27 "POSIX ÔÒÅÂÕÅÔ, ÞÔÏÂÙ ÌÅ×ÁÑ ÓËÏÂËÁ ÂÙÌÁ ÎÁ ÔÏÊ ÖÅ ÌÉÎÉÉ, ÞÔÏ É ÚÁÇÏÌÏ×ÏË ÆÕÎËÃÉÉ"
+
+$ ïÛÉÂËÉ ×ÙÐÏÌÎÅÎÉÑ.
+$set 5
+
+1 "îÅÄÅÊÓÔ×ÉÔÅÌØÎÙÊ ibase: ÄÏÌÖÅÎ ÂÙÔØ [%lu, %lu]"
+2 "îÅÄÅÊÓÔ×ÉÔÅÌØÎÙÊ obase: ÄÏÌÖÅÎ ÂÙÔØ [%lu, %lu]"
+3 "ÎÅÄÅÊÓÔ×ÉÔÅÌØÎÁÑ scale: ÄÏÌÖÎÁ ÂÙÔØ [%lu, %lu]"
+4 "ÎÅÄÅÊÓÔ×ÉÔÅÌØÎÏÅ ×ÙÒÁÖÅÎÉÅ read()"
+5 "ÒÅËÕÒÓÉ×ÎÙÊ ×ÙÚÏ× read()"
+6 "ÐÅÒÅÍÅÎÎÁÑ ÉÌÉ ÜÌÅÍÅÎÔ ÍÁÓÓÉ×Á Ñ×ÌÑÅÔÓÑ ÎÅÐÒÁ×ÉÌØÎÙÍ ÔÉÐÏÍ"
+7 "ÓÔÏÐËÁ ÉÍÅÅÔ ÓÌÉÛËÏÍ ÍÁÌÏ ÜÌÅÍÅÎÔÏ×"
+8 "ÎÅÐÒÁ×ÉÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÐÁÒÁÍÅÔÒÏ×; ÎÕÖÎÏ %zu, ÎÕÖÎÏ %zu"
+9 "ÎÅÏÐÒÅÄÅÌÅÎÎÁÑ ÆÕÎËÃÉÑ: %s()"
+10 "ÎÅ ÍÏÖÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÕÓÔÏÅ ÚÎÁÞÅÎÉÅ × ×ÙÒÁÖÅÎÉÉ"
+
+$ æÁÔÁÌØÎÙÅ ÏÛÉÂËÉ.
+$set 6
+
+1 "îÅ ÕÄÁÌÏÓØ ×ÙÄÅÌÉÔØ ÐÁÍÑÔØ"
+2 "ïÛÉÂËÁ ××ÏÄÁ/×Ù×ÏÄÁ"
+3 "ÎÅ ÓÍÏÇ ÏÔËÒÙÔØ ÆÁÊÌ: %s"
+4 "ÆÁÊÌ ÎÅ ASCII: %s"
+5 "ÐÕÔØ - ÜÔÏ ËÁÔÁÌÏÇ: %s"
+6 "ÎÅ×ÅÒÎÁÑ ÏÐÃÉÑ ËÏÍÁÎÄÎÏÊ ÓÔÒÏËÉ: '%c' (\"%s\")"
+
+$set 7
+
+1 "ÏÐÃÉÑ ÔÒÅÂÕÅÔ ÁÒÇÕÍÅÎÔÁ: '%c' (\"%s\")"
+2 "ÏÐÃÉÑ ÎÅ ÐÒÉÎÉÍÁÅÔ ÁÒÇÕÍÅÎÔÏ×: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/ru_RU.UTF-8.msg b/contrib/bc/locales/ru_RU.UTF-8.msg
new file mode 100644
index 000000000000..b0d8165554b2
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ Разные ÑообщениÑ.
+$set 1
+
+1 "ФункциÑ:"
+
+$ Типы ошибок.
+$set 2
+
+1 "МатематичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°:"
+2 "Ошибка при разборе:"
+3 "Ошибка выполнениÑ:"
+4 "Ð¤Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°:"
+5 "Предупреждение:"
+
+$ МатематичеÑкие ошибки.
+$set 3
+
+1 "отрицательное чиÑло"
+2 "неинтегрированное чиÑло"
+3 "переполнение: номер не помещаетÑÑ Ð² аппаратный номер"
+4 "делить на 0"
+
+$ Ошибки при разборе.
+$set 4
+
+1 "конец файла"
+2 "недопуÑтимый Ñимвол '%c'"
+3 "конец Ñтроки не найден"
+4 "конец ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ Ð½Ðµ найден"
+5 "недейÑтвительный жетон"
+6 "неправильное выражение"
+7 "пуÑтое выражение"
+8 "заÑвление о недейÑтвительноÑти печати"
+9 "определение недейÑтвительной функции"
+10 "неверное приÑвоение: Ð»ÐµÐ²Ð°Ñ Ñторона должна быть scale, ibase, obase, last, варом или Ñлементом маÑÑива"
+11 "автоматичеÑÐºÐ°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð½Ðµ найдена"
+12 "параметр функции или auto \"%s%s\" уже ÑущеÑтвует"
+13 "конец блока не найден"
+14 "не может вернуть значение из функции void: %s()"
+15 "var не может быть ÑÑылкой: %s"
+16 "POSIX не допуÑкает имен длиннее 1 Ñимвола: %s"
+17 "POSIX не допуÑкает комментариев к Ñценарию '#'"
+18 "POSIX не допуÑкает Ñледующее ключевое Ñлово: %s"
+19 "POSIX не допуÑкает точку ('.') в качеÑтве Ñрлыка Ð´Ð»Ñ Ð¿Ð¾Ñледнего результата"
+20 "POSIX требует Ñкобок вокруг выражений возврата"
+21 "POSIX не разрешает иÑпользовать Ñледующий оператор: %s"
+22 "POSIX не разрешает операторам ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð¸Ñ‚ÑŒ за пределы, еÑли ÑƒÑ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ циклы"
+23 "POSIX требует 0 или 1 оператора ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ð½Ð° уÑловие"
+24 "POSIX требует, чтобы вÑе 3 чаÑти петли были непуÑтыми"
+25 "POSIX не допуÑкает ÑкÑпоненциальной нотации"
+26 "POSIX не допуÑкает ÑÑылки на маÑÑив в качеÑтве параметров функции"
+27 "POSIX требует, чтобы Ð»ÐµÐ²Ð°Ñ Ñкобка была на той же линии, что и заголовок функции"
+
+$ Ошибки выполнениÑ.
+$set 5
+
+1 "ÐедейÑтвительный ibase: должен быть [%lu, %lu]"
+2 "ÐедейÑтвительный obase: должен быть [%lu, %lu]"
+3 "недейÑÑ‚Ð²Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ scale: должна быть [%lu, %lu]"
+4 "недейÑтвительное выражение read()"
+5 "рекурÑивный вызов read()"
+6 "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¸Ð»Ð¸ Ñлемент маÑÑива ÑвлÑетÑÑ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ типом"
+7 "Ñтопка имеет Ñлишком мало Ñлементов"
+8 "неправильное количеÑтво параметров; нужно %zu, нужно %zu"
+9 "Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ: %s()"
+10 "не может иÑпользовать пуÑтое значение в выражении"
+
+$ Фатальные ошибки.
+$set 6
+
+1 "Ðе удалоÑÑŒ выделить памÑÑ‚ÑŒ"
+2 "Ошибка ввода/вывода"
+3 "не Ñмог открыть файл: %s"
+4 "файл не ASCII: %s"
+5 "путь - Ñто каталог: %s"
+6 "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¾Ð¿Ñ†Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¾Ð¹ Ñтроки: '%c' (\"%s\")"
+
+$set 7
+
+1 "Ð¾Ð¿Ñ†Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ аргумента: '%c' (\"%s\")"
+2 "Ð¾Ð¿Ñ†Ð¸Ñ Ð½Ðµ принимает аргументов: '%c' (\"%s\")"
diff --git a/contrib/bc/locales/ru_RU.utf8.msg b/contrib/bc/locales/ru_RU.utf8.msg
new file mode 120000
index 000000000000..632597a5ffce
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.utf8.msg
@@ -0,0 +1 @@
+ru_RU.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/locales/zh_CN.GB18030.msg b/contrib/bc/locales/zh_CN.GB18030.msg
new file mode 100644
index 000000000000..36b150b2bcbf
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.GB18030.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ ÔÓÏîÐÅÏ¢¡£
+$set 1
+
+1 "º¯Êý£º"
+
+$ ´íÎóÀàÐÍ¡£
+$set 2
+
+1 "Êýѧ´íÎó£º"
+2 "½âÎö´íÎó£º"
+3 "ÔËÐÐʱ´íÎó£º"
+4 "ÖÂÃü´íÎó£º"
+5 "¾¯¸æ£º"
+
+$ Êýѧ´íÎó¡£
+$set 3
+
+1 "¸ºÊý"
+2 "·ÇÕûÊý"
+3 "Òç³ö£ºÊý×Ö²»·ûºÏÓ²¼þºÅÂë"
+4 "³ýÒÔ0"
+
+$ ½âÎö´íÎó¡£
+$set 4
+
+1 "Îļþ½áÊø"
+2 "ÎÞЧ×Ö·û'%c'"
+3 "ÕÒ²»µ½×Ö·û´®Î²²¿"
+4 "ÎÞ·¨ÕÒµ½ÆÀÂ۵Ľáβ"
+5 "ÎÞЧÁîÅÆ"
+6 "ÎÞЧ±í´ï"
+7 ¡°¿Õ±í´ï¡±
+8 "ÎÞЧ´òÓ¡ÉùÃ÷"
+9 "ÎÞЧµÄ¹¦Äܶ¨Òå"
+10 "ÎÞЧ·ÖÅ䣺×ó²à±ØÐëÊÇscale¡¢ibase¡¢obase¡¢last¡¢var»òÊý×éÔªËØ"
+11 "ûÓÐÕÒµ½×Ô¶¯±äÁ¿"
+12 "º¯Êý²ÎÊý»ò×Ô¶¯²ÎÊý \"%s%s\" ÒѾ­´æÔÚ"
+13 "ÕÒ²»µ½Çø¿éÄ©¶Ë"
+14 "²»ÄÜ´Óvoidº¯ÊýÖзµ»ØÒ»¸öÖµ£º%s()"
+15 "var²»ÄÜ×÷Ϊ²Î¿¼£º%s"
+16 "POSIX²»ÔÊÐíÃû×Ö³¬¹ý1¸ö×Ö·û£º%s"
+17 "POSIX²»ÔÊÐí'#'½Å±¾×¢ÊÍ"
+18 "POSIX²»ÔÊÐíʹÓÃÒÔϹؼü×Ö£º%s"
+19 "POSIX²»ÔÊÐíÓþäºÅ('.')×÷Ϊ×îºó½á¹ûµÄ¿ì½Ý·½Ê½"
+20 "POSIXÒªÇóÔÚ·µ»Ø±í´ïʽÖÜΧ¼ÓÀ¨ºÅ"
+21 "POSIX²»ÔÊÐíÒÔϲÙ×÷·û£º%s"
+22 "POSIX²»ÔÊÐíÔÚifÓï¾ä»òÑ­»·Ö®ÍâµÄ±È½ÏÔËËã·û"
+23 "POSIXÒªÇóÿ¸öÌõ¼þµÄ±È½ÏÔËËã·ûΪ0»ò1¸ö"
+24 "POSIXÒªÇóforÑ­»·µÄËùÓÐ3¸ö²¿·Ö±ØÐëÊÇ·Ç¿ÕµÄ"
+25 "POSIX²»ÔÊÐíʹÓÃÖ¸Êý·ûºÅ"
+26 "POSIX²»ÔÊÐíÊý×éÒýÓÃ×÷Ϊº¯Êý²ÎÊý"
+27 "POSIXÒªÇó×ó±ßµÄÀ¨ºÅºÍº¯ÊýÍ·ÔÚͬһÐÐÉÏ"
+
+$ ÔËÐÐʱ´íÎó¡£
+$set 5
+
+1 "ÎÞЧµÄibase: ±ØÐëÊÇ[%lu, %lu]"
+2 "ÎÞЧµÄobase£º±ØÐëÊÇ[%lu£¬%lu]"
+3 "ÎÞЧµÄscale£º±ØÐëÊÇ[%lu£¬%lu]"
+4 "ÎÞЧµÄread()±í´ïʽ"
+5 "µÝ¹é¶ÁÈ¡()µ÷ÓÃ"
+6 "±äÁ¿»òÊý×éÔªËØÊÇ´íÎóµÄÀàÐÍ"
+7 "¶ÑÕ»µÄÔªËØÌ«ÉÙ"
+8 "²ÎÊýÊýÁ¿´íÎó£»ÐèÒª%zu£¬ÓÐ%zu"
+9 "䶨ÒåµÄº¯Êý£º%s()"
+10 ¡°²»ÄÜÔÚ±í´ïʽÖÐʹÓÿÕÖµ¡±
+
+$ ÖÂÃü´íÎó¡£
+$set 6
+
+1 "ÄÚ´æ·ÖÅäʧ°Ü"
+2 "I/O´íÎó"
+3 "ÎÞ·¨´ò¿ªÎļþ¡£%s"
+4 "Îļþ²»ÊÇASCII: %s"
+5 "·¾¶ÊÇÒ»¸öĿ¼£º%s"
+6 "ÎÞЧµÄÃüÁîÐÐÑ¡Ï\"%s\""
+7 "Ñ¡ÏîÐèÒªÒ»¸ö²ÎÊý£º'%c'(\"%s\")"
+8 "Ñ¡Ïî²»ÐèÒª²ÎÊý¡£'%c'(\"%s\")"
diff --git a/contrib/bc/locales/zh_CN.GB2312.msg b/contrib/bc/locales/zh_CN.GB2312.msg
new file mode 100644
index 000000000000..36b150b2bcbf
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.GB2312.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ ÔÓÏîÐÅÏ¢¡£
+$set 1
+
+1 "º¯Êý£º"
+
+$ ´íÎóÀàÐÍ¡£
+$set 2
+
+1 "Êýѧ´íÎó£º"
+2 "½âÎö´íÎó£º"
+3 "ÔËÐÐʱ´íÎó£º"
+4 "ÖÂÃü´íÎó£º"
+5 "¾¯¸æ£º"
+
+$ Êýѧ´íÎó¡£
+$set 3
+
+1 "¸ºÊý"
+2 "·ÇÕûÊý"
+3 "Òç³ö£ºÊý×Ö²»·ûºÏÓ²¼þºÅÂë"
+4 "³ýÒÔ0"
+
+$ ½âÎö´íÎó¡£
+$set 4
+
+1 "Îļþ½áÊø"
+2 "ÎÞЧ×Ö·û'%c'"
+3 "ÕÒ²»µ½×Ö·û´®Î²²¿"
+4 "ÎÞ·¨ÕÒµ½ÆÀÂ۵Ľáβ"
+5 "ÎÞЧÁîÅÆ"
+6 "ÎÞЧ±í´ï"
+7 ¡°¿Õ±í´ï¡±
+8 "ÎÞЧ´òÓ¡ÉùÃ÷"
+9 "ÎÞЧµÄ¹¦Äܶ¨Òå"
+10 "ÎÞЧ·ÖÅ䣺×ó²à±ØÐëÊÇscale¡¢ibase¡¢obase¡¢last¡¢var»òÊý×éÔªËØ"
+11 "ûÓÐÕÒµ½×Ô¶¯±äÁ¿"
+12 "º¯Êý²ÎÊý»ò×Ô¶¯²ÎÊý \"%s%s\" ÒѾ­´æÔÚ"
+13 "ÕÒ²»µ½Çø¿éÄ©¶Ë"
+14 "²»ÄÜ´Óvoidº¯ÊýÖзµ»ØÒ»¸öÖµ£º%s()"
+15 "var²»ÄÜ×÷Ϊ²Î¿¼£º%s"
+16 "POSIX²»ÔÊÐíÃû×Ö³¬¹ý1¸ö×Ö·û£º%s"
+17 "POSIX²»ÔÊÐí'#'½Å±¾×¢ÊÍ"
+18 "POSIX²»ÔÊÐíʹÓÃÒÔϹؼü×Ö£º%s"
+19 "POSIX²»ÔÊÐíÓþäºÅ('.')×÷Ϊ×îºó½á¹ûµÄ¿ì½Ý·½Ê½"
+20 "POSIXÒªÇóÔÚ·µ»Ø±í´ïʽÖÜΧ¼ÓÀ¨ºÅ"
+21 "POSIX²»ÔÊÐíÒÔϲÙ×÷·û£º%s"
+22 "POSIX²»ÔÊÐíÔÚifÓï¾ä»òÑ­»·Ö®ÍâµÄ±È½ÏÔËËã·û"
+23 "POSIXÒªÇóÿ¸öÌõ¼þµÄ±È½ÏÔËËã·ûΪ0»ò1¸ö"
+24 "POSIXÒªÇóforÑ­»·µÄËùÓÐ3¸ö²¿·Ö±ØÐëÊÇ·Ç¿ÕµÄ"
+25 "POSIX²»ÔÊÐíʹÓÃÖ¸Êý·ûºÅ"
+26 "POSIX²»ÔÊÐíÊý×éÒýÓÃ×÷Ϊº¯Êý²ÎÊý"
+27 "POSIXÒªÇó×ó±ßµÄÀ¨ºÅºÍº¯ÊýÍ·ÔÚͬһÐÐÉÏ"
+
+$ ÔËÐÐʱ´íÎó¡£
+$set 5
+
+1 "ÎÞЧµÄibase: ±ØÐëÊÇ[%lu, %lu]"
+2 "ÎÞЧµÄobase£º±ØÐëÊÇ[%lu£¬%lu]"
+3 "ÎÞЧµÄscale£º±ØÐëÊÇ[%lu£¬%lu]"
+4 "ÎÞЧµÄread()±í´ïʽ"
+5 "µÝ¹é¶ÁÈ¡()µ÷ÓÃ"
+6 "±äÁ¿»òÊý×éÔªËØÊÇ´íÎóµÄÀàÐÍ"
+7 "¶ÑÕ»µÄÔªËØÌ«ÉÙ"
+8 "²ÎÊýÊýÁ¿´íÎó£»ÐèÒª%zu£¬ÓÐ%zu"
+9 "䶨ÒåµÄº¯Êý£º%s()"
+10 ¡°²»ÄÜÔÚ±í´ïʽÖÐʹÓÿÕÖµ¡±
+
+$ ÖÂÃü´íÎó¡£
+$set 6
+
+1 "ÄÚ´æ·ÖÅäʧ°Ü"
+2 "I/O´íÎó"
+3 "ÎÞ·¨´ò¿ªÎļþ¡£%s"
+4 "Îļþ²»ÊÇASCII: %s"
+5 "·¾¶ÊÇÒ»¸öĿ¼£º%s"
+6 "ÎÞЧµÄÃüÁîÐÐÑ¡Ï\"%s\""
+7 "Ñ¡ÏîÐèÒªÒ»¸ö²ÎÊý£º'%c'(\"%s\")"
+8 "Ñ¡Ïî²»ÐèÒª²ÎÊý¡£'%c'(\"%s\")"
diff --git a/contrib/bc/locales/zh_CN.GBK.msg b/contrib/bc/locales/zh_CN.GBK.msg
new file mode 100644
index 000000000000..36b150b2bcbf
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.GBK.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ ÔÓÏîÐÅÏ¢¡£
+$set 1
+
+1 "º¯Êý£º"
+
+$ ´íÎóÀàÐÍ¡£
+$set 2
+
+1 "Êýѧ´íÎó£º"
+2 "½âÎö´íÎó£º"
+3 "ÔËÐÐʱ´íÎó£º"
+4 "ÖÂÃü´íÎó£º"
+5 "¾¯¸æ£º"
+
+$ Êýѧ´íÎó¡£
+$set 3
+
+1 "¸ºÊý"
+2 "·ÇÕûÊý"
+3 "Òç³ö£ºÊý×Ö²»·ûºÏÓ²¼þºÅÂë"
+4 "³ýÒÔ0"
+
+$ ½âÎö´íÎó¡£
+$set 4
+
+1 "Îļþ½áÊø"
+2 "ÎÞЧ×Ö·û'%c'"
+3 "ÕÒ²»µ½×Ö·û´®Î²²¿"
+4 "ÎÞ·¨ÕÒµ½ÆÀÂ۵Ľáβ"
+5 "ÎÞЧÁîÅÆ"
+6 "ÎÞЧ±í´ï"
+7 ¡°¿Õ±í´ï¡±
+8 "ÎÞЧ´òÓ¡ÉùÃ÷"
+9 "ÎÞЧµÄ¹¦Äܶ¨Òå"
+10 "ÎÞЧ·ÖÅ䣺×ó²à±ØÐëÊÇscale¡¢ibase¡¢obase¡¢last¡¢var»òÊý×éÔªËØ"
+11 "ûÓÐÕÒµ½×Ô¶¯±äÁ¿"
+12 "º¯Êý²ÎÊý»ò×Ô¶¯²ÎÊý \"%s%s\" ÒѾ­´æÔÚ"
+13 "ÕÒ²»µ½Çø¿éÄ©¶Ë"
+14 "²»ÄÜ´Óvoidº¯ÊýÖзµ»ØÒ»¸öÖµ£º%s()"
+15 "var²»ÄÜ×÷Ϊ²Î¿¼£º%s"
+16 "POSIX²»ÔÊÐíÃû×Ö³¬¹ý1¸ö×Ö·û£º%s"
+17 "POSIX²»ÔÊÐí'#'½Å±¾×¢ÊÍ"
+18 "POSIX²»ÔÊÐíʹÓÃÒÔϹؼü×Ö£º%s"
+19 "POSIX²»ÔÊÐíÓþäºÅ('.')×÷Ϊ×îºó½á¹ûµÄ¿ì½Ý·½Ê½"
+20 "POSIXÒªÇóÔÚ·µ»Ø±í´ïʽÖÜΧ¼ÓÀ¨ºÅ"
+21 "POSIX²»ÔÊÐíÒÔϲÙ×÷·û£º%s"
+22 "POSIX²»ÔÊÐíÔÚifÓï¾ä»òÑ­»·Ö®ÍâµÄ±È½ÏÔËËã·û"
+23 "POSIXÒªÇóÿ¸öÌõ¼þµÄ±È½ÏÔËËã·ûΪ0»ò1¸ö"
+24 "POSIXÒªÇóforÑ­»·µÄËùÓÐ3¸ö²¿·Ö±ØÐëÊÇ·Ç¿ÕµÄ"
+25 "POSIX²»ÔÊÐíʹÓÃÖ¸Êý·ûºÅ"
+26 "POSIX²»ÔÊÐíÊý×éÒýÓÃ×÷Ϊº¯Êý²ÎÊý"
+27 "POSIXÒªÇó×ó±ßµÄÀ¨ºÅºÍº¯ÊýÍ·ÔÚͬһÐÐÉÏ"
+
+$ ÔËÐÐʱ´íÎó¡£
+$set 5
+
+1 "ÎÞЧµÄibase: ±ØÐëÊÇ[%lu, %lu]"
+2 "ÎÞЧµÄobase£º±ØÐëÊÇ[%lu£¬%lu]"
+3 "ÎÞЧµÄscale£º±ØÐëÊÇ[%lu£¬%lu]"
+4 "ÎÞЧµÄread()±í´ïʽ"
+5 "µÝ¹é¶ÁÈ¡()µ÷ÓÃ"
+6 "±äÁ¿»òÊý×éÔªËØÊÇ´íÎóµÄÀàÐÍ"
+7 "¶ÑÕ»µÄÔªËØÌ«ÉÙ"
+8 "²ÎÊýÊýÁ¿´íÎó£»ÐèÒª%zu£¬ÓÐ%zu"
+9 "䶨ÒåµÄº¯Êý£º%s()"
+10 ¡°²»ÄÜÔÚ±í´ïʽÖÐʹÓÿÕÖµ¡±
+
+$ ÖÂÃü´íÎó¡£
+$set 6
+
+1 "ÄÚ´æ·ÖÅäʧ°Ü"
+2 "I/O´íÎó"
+3 "ÎÞ·¨´ò¿ªÎļþ¡£%s"
+4 "Îļþ²»ÊÇASCII: %s"
+5 "·¾¶ÊÇÒ»¸öĿ¼£º%s"
+6 "ÎÞЧµÄÃüÁîÐÐÑ¡Ï\"%s\""
+7 "Ñ¡ÏîÐèÒªÒ»¸ö²ÎÊý£º'%c'(\"%s\")"
+8 "Ñ¡Ïî²»ÐèÒª²ÎÊý¡£'%c'(\"%s\")"
diff --git a/contrib/bc/locales/zh_CN.UTF-8.msg b/contrib/bc/locales/zh_CN.UTF-8.msg
new file mode 100644
index 000000000000..4ca46786fc94
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.UTF-8.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ æ‚项信æ¯ã€‚
+$set 1
+
+1 "函数:"
+
+$ 错误类型。
+$set 2
+
+1 "数学错误:"
+2 "解æžé”™è¯¯ï¼š"
+3 "è¿è¡Œæ—¶é”™è¯¯ï¼š"
+4 "致命错误:"
+5 "警告:"
+
+$ 数学错误。
+$set 3
+
+1 "è´Ÿæ•°"
+2 "éžæ•´æ•°"
+3 "溢出:数字ä¸ç¬¦åˆç¡¬ä»¶å·ç "
+4 "除以0"
+
+$ 解æžé”™è¯¯ã€‚
+$set 4
+
+1 "文件结æŸ"
+2 "无效字符'%c'"
+3 "找ä¸åˆ°å­—符串尾部"
+4 "无法找到评论的结尾"
+5 "无效令牌"
+6 "无效表达"
+7 “空表达â€
+8 "无效打å°å£°æ˜Ž"
+9 "无效的功能定义"
+10 "无效分é…:左侧必须是scaleã€ibaseã€obaseã€lastã€var或数组元素"
+11 "没有找到自动å˜é‡"
+12 "函数å‚数或自动å‚æ•° \"%s%s\" å·²ç»å­˜åœ¨"
+13 "找ä¸åˆ°åŒºå—末端"
+14 "ä¸èƒ½ä»Žvoid函数中返回一个值:%s()"
+15 "varä¸èƒ½ä½œä¸ºå‚考:%s"
+16 "POSIXä¸å…许å字超过1个字符:%s"
+17 "POSIXä¸å…许'#'脚本注释"
+18 "POSIXä¸å…许使用以下关键字:%s"
+19 "POSIXä¸å…许用å¥å·('.')作为最åŽç»“果的快æ·æ–¹å¼"
+20 "POSIXè¦æ±‚在返回表达å¼å‘¨å›´åŠ æ‹¬å·"
+21 "POSIXä¸å…许以下æ“作符:%s"
+22 "POSIXä¸å…许在if语å¥æˆ–循环之外的比较è¿ç®—符"
+23 "POSIXè¦æ±‚æ¯ä¸ªæ¡ä»¶çš„比较è¿ç®—符为0或1个"
+24 "POSIXè¦æ±‚for循环的所有3个部分必须是éžç©ºçš„"
+25 "POSIXä¸å…许使用指数符å·"
+26 "POSIXä¸å…许数组引用作为函数å‚æ•°"
+27 "POSIXè¦æ±‚左边的括å·å’Œå‡½æ•°å¤´åœ¨åŒä¸€è¡Œä¸Š"
+
+$ è¿è¡Œæ—¶é”™è¯¯ã€‚
+$set 5
+
+1 "无效的ibase: 必须是[%lu, %lu]"
+2 "无效的obase:必须是[%lu,%lu]"
+3 "无效的scale:必须是[%lu,%lu]"
+4 "无效的read()表达å¼"
+5 "递归读å–()调用"
+6 "å˜é‡æˆ–数组元素是错误的类型"
+7 "堆栈的元素太少"
+8 "å‚æ•°æ•°é‡é”™è¯¯ï¼šéœ€è¦%zu,有%zu"
+9 "未定义的函数:%s()"
+10 “ä¸èƒ½åœ¨è¡¨è¾¾å¼ä¸­ä½¿ç”¨ç©ºå€¼â€
+
+$ 致命错误。
+$set 6
+
+1 "内存分é…失败"
+2 "I/O错误"
+3 "无法打开文件:%s"
+4 "文件ä¸æ˜¯ASCII: %s"
+5 "路径是一个目录:%s"
+6 "无效的命令行选项:\"%s\""
+7 "选项需è¦ä¸€ä¸ªå‚数:'%c'(\"%s\")"
+8 "选项ä¸éœ€è¦å‚数。'%c'(\"%s\")"
diff --git a/contrib/bc/locales/zh_CN.eucCN.msg b/contrib/bc/locales/zh_CN.eucCN.msg
new file mode 100644
index 000000000000..36b150b2bcbf
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.eucCN.msg
@@ -0,0 +1,108 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2020 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.
+$ $
+
+$quote "
+
+$ ÔÓÏîÐÅÏ¢¡£
+$set 1
+
+1 "º¯Êý£º"
+
+$ ´íÎóÀàÐÍ¡£
+$set 2
+
+1 "Êýѧ´íÎó£º"
+2 "½âÎö´íÎó£º"
+3 "ÔËÐÐʱ´íÎó£º"
+4 "ÖÂÃü´íÎó£º"
+5 "¾¯¸æ£º"
+
+$ Êýѧ´íÎó¡£
+$set 3
+
+1 "¸ºÊý"
+2 "·ÇÕûÊý"
+3 "Òç³ö£ºÊý×Ö²»·ûºÏÓ²¼þºÅÂë"
+4 "³ýÒÔ0"
+
+$ ½âÎö´íÎó¡£
+$set 4
+
+1 "Îļþ½áÊø"
+2 "ÎÞЧ×Ö·û'%c'"
+3 "ÕÒ²»µ½×Ö·û´®Î²²¿"
+4 "ÎÞ·¨ÕÒµ½ÆÀÂ۵Ľáβ"
+5 "ÎÞЧÁîÅÆ"
+6 "ÎÞЧ±í´ï"
+7 ¡°¿Õ±í´ï¡±
+8 "ÎÞЧ´òÓ¡ÉùÃ÷"
+9 "ÎÞЧµÄ¹¦Äܶ¨Òå"
+10 "ÎÞЧ·ÖÅ䣺×ó²à±ØÐëÊÇscale¡¢ibase¡¢obase¡¢last¡¢var»òÊý×éÔªËØ"
+11 "ûÓÐÕÒµ½×Ô¶¯±äÁ¿"
+12 "º¯Êý²ÎÊý»ò×Ô¶¯²ÎÊý \"%s%s\" ÒѾ­´æÔÚ"
+13 "ÕÒ²»µ½Çø¿éÄ©¶Ë"
+14 "²»ÄÜ´Óvoidº¯ÊýÖзµ»ØÒ»¸öÖµ£º%s()"
+15 "var²»ÄÜ×÷Ϊ²Î¿¼£º%s"
+16 "POSIX²»ÔÊÐíÃû×Ö³¬¹ý1¸ö×Ö·û£º%s"
+17 "POSIX²»ÔÊÐí'#'½Å±¾×¢ÊÍ"
+18 "POSIX²»ÔÊÐíʹÓÃÒÔϹؼü×Ö£º%s"
+19 "POSIX²»ÔÊÐíÓþäºÅ('.')×÷Ϊ×îºó½á¹ûµÄ¿ì½Ý·½Ê½"
+20 "POSIXÒªÇóÔÚ·µ»Ø±í´ïʽÖÜΧ¼ÓÀ¨ºÅ"
+21 "POSIX²»ÔÊÐíÒÔϲÙ×÷·û£º%s"
+22 "POSIX²»ÔÊÐíÔÚifÓï¾ä»òÑ­»·Ö®ÍâµÄ±È½ÏÔËËã·û"
+23 "POSIXÒªÇóÿ¸öÌõ¼þµÄ±È½ÏÔËËã·ûΪ0»ò1¸ö"
+24 "POSIXÒªÇóforÑ­»·µÄËùÓÐ3¸ö²¿·Ö±ØÐëÊÇ·Ç¿ÕµÄ"
+25 "POSIX²»ÔÊÐíʹÓÃÖ¸Êý·ûºÅ"
+26 "POSIX²»ÔÊÐíÊý×éÒýÓÃ×÷Ϊº¯Êý²ÎÊý"
+27 "POSIXÒªÇó×ó±ßµÄÀ¨ºÅºÍº¯ÊýÍ·ÔÚͬһÐÐÉÏ"
+
+$ ÔËÐÐʱ´íÎó¡£
+$set 5
+
+1 "ÎÞЧµÄibase: ±ØÐëÊÇ[%lu, %lu]"
+2 "ÎÞЧµÄobase£º±ØÐëÊÇ[%lu£¬%lu]"
+3 "ÎÞЧµÄscale£º±ØÐëÊÇ[%lu£¬%lu]"
+4 "ÎÞЧµÄread()±í´ïʽ"
+5 "µÝ¹é¶ÁÈ¡()µ÷ÓÃ"
+6 "±äÁ¿»òÊý×éÔªËØÊÇ´íÎóµÄÀàÐÍ"
+7 "¶ÑÕ»µÄÔªËØÌ«ÉÙ"
+8 "²ÎÊýÊýÁ¿´íÎó£»ÐèÒª%zu£¬ÓÐ%zu"
+9 "䶨ÒåµÄº¯Êý£º%s()"
+10 ¡°²»ÄÜÔÚ±í´ïʽÖÐʹÓÿÕÖµ¡±
+
+$ ÖÂÃü´íÎó¡£
+$set 6
+
+1 "ÄÚ´æ·ÖÅäʧ°Ü"
+2 "I/O´íÎó"
+3 "ÎÞ·¨´ò¿ªÎļþ¡£%s"
+4 "Îļþ²»ÊÇASCII: %s"
+5 "·¾¶ÊÇÒ»¸öĿ¼£º%s"
+6 "ÎÞЧµÄÃüÁîÐÐÑ¡Ï\"%s\""
+7 "Ñ¡ÏîÐèÒªÒ»¸ö²ÎÊý£º'%c'(\"%s\")"
+8 "Ñ¡Ïî²»ÐèÒª²ÎÊý¡£'%c'(\"%s\")"
diff --git a/contrib/bc/locales/zh_CN.utf8.msg b/contrib/bc/locales/zh_CN.utf8.msg
new file mode 120000
index 000000000000..d67657f26521
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.utf8.msg
@@ -0,0 +1 @@
+zh_CN.UTF-8.msg \ No newline at end of file
diff --git a/contrib/bc/manpage.sh b/contrib/bc/manpage.sh
new file mode 100755
index 000000000000..edde671da238
--- /dev/null
+++ b/contrib/bc/manpage.sh
@@ -0,0 +1,131 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+usage() {
+ printf "usage: %s manpage\n" "$0" 1>&2
+ exit 1
+}
+
+print_manpage() {
+
+ _print_manpage_md="$1"
+ shift
+
+ _print_manpage_out="$1"
+ shift
+
+ cat "$manualsdir/header.txt" > "$_print_manpage_out"
+ cat "$manualsdir/header_${manpage}.txt" >> "$_print_manpage_out"
+
+ pandoc -f markdown -t man "$_print_manpage_md" >> "$_print_manpage_out"
+
+}
+
+gen_manpage() {
+
+ _gen_manpage_args="$1"
+ shift
+
+ _gen_manpage_status="$ALL"
+ _gen_manpage_out="$manualsdir/$manpage/$_gen_manpage_args.1"
+ _gen_manpage_md="$manualsdir/$manpage/$_gen_manpage_args.1.md"
+ _gen_manpage_temp="$manualsdir/temp.1.md"
+ _gen_manpage_ifs="$IFS"
+
+ rm -rf "$_gen_manpage_out" "$_gen_manpage_md"
+
+ while IFS= read -r line; do
+
+ if [ "$line" = "{{ end }}" ]; then
+
+ if [ "$_gen_manpage_status" -eq "$ALL" ]; then
+ err_exit "{{ end }} tag without corresponding start tag" 2
+ fi
+
+ _gen_manpage_status="$ALL"
+
+ elif [ "${line#\{\{* $_gen_manpage_args *\}\}}" != "$line" ]; then
+
+ if [ "$_gen_manpage_status" -ne "$ALL" ]; then
+ err_exit "start tag nested in start tag" 3
+ fi
+
+ _gen_manpage_status="$NOSKIP"
+
+ elif [ "${line#\{\{*\}\}}" != "$line" ]; then
+
+ if [ "$_gen_manpage_status" -ne "$ALL" ]; then
+ err_exit "start tag nested in start tag" 3
+ fi
+
+ _gen_manpage_status="$SKIP"
+
+ else
+ if [ "$_gen_manpage_status" -ne "$SKIP" ]; then
+ printf '%s\n' "$line" >> "$_gen_manpage_temp"
+ fi
+ fi
+
+ done < "$manualsdir/${manpage}.1.md.in"
+
+ uniq "$_gen_manpage_temp" "$_gen_manpage_md"
+ rm -rf "$_gen_manpage_temp"
+
+ IFS="$_gen_manpage_ifs"
+
+ print_manpage "$_gen_manpage_md" "$_gen_manpage_out"
+}
+
+set -e
+
+script="$0"
+scriptdir=$(dirname "$script")
+manualsdir="$scriptdir/manuals"
+
+. "$scriptdir/functions.sh"
+
+ARGS="A E H N P EH EN EP HN HP NP EHN EHP ENP HNP EHNP"
+ALL=0
+NOSKIP=1
+SKIP=2
+
+test "$#" -eq 1 || usage
+
+manpage="$1"
+shift
+
+if [ "$manpage" != "bcl" ]; then
+
+ for a in $ARGS; do
+ gen_manpage "$a"
+ done
+
+else
+ print_manpage "$manualsdir/${manpage}.3.md" "$manualsdir/${manpage}.3"
+fi
diff --git a/contrib/bc/manuals/algorithms.md b/contrib/bc/manuals/algorithms.md
new file mode 100644
index 000000000000..172401e1a483
--- /dev/null
+++ b/contrib/bc/manuals/algorithms.md
@@ -0,0 +1,189 @@
+# Algorithms
+
+This `bc` uses the math algorithms below:
+
+### Addition
+
+This `bc` uses brute force addition, which is linear (`O(n)`) in the number of
+digits.
+
+### Subtraction
+
+This `bc` uses brute force subtraction, which is linear (`O(n)`) in the number
+of digits.
+
+### Multiplication
+
+This `bc` uses two algorithms: [Karatsuba][1] and brute force.
+
+Karatsuba is used for "large" numbers. ("Large" numbers are defined as any
+number with `BC_NUM_KARATSUBA_LEN` digits or larger. `BC_NUM_KARATSUBA_LEN` has
+a sane default, but may be configured by the user.) Karatsuba, as implemented in
+this `bc`, is superlinear but subpolynomial (bounded by `O(n^log_2(3))`).
+
+Brute force multiplication is used below `BC_NUM_KARATSUBA_LEN` digits. It is
+polynomial (`O(n^2)`), but since Karatsuba requires both more intermediate
+values (which translate to memory allocations) and a few more additions, there
+is a "break even" point in the number of digits where brute force multiplication
+is faster than Karatsuba. There is a script (`$ROOT/karatsuba.py`) that will
+find the break even point on a particular machine.
+
+***WARNING: The Karatsuba script requires Python 3.***
+
+### Division
+
+This `bc` uses Algorithm D ([long division][2]). Long division is polynomial
+(`O(n^2)`), but unlike Karatsuba, any division "divide and conquer" algorithm
+reaches its "break even" point with significantly larger numbers. "Fast"
+algorithms become less attractive with division as this operation typically
+reduces the problem size.
+
+While the implementation of long division may appear to use the subtractive
+chunking method, it only uses subtraction to find a quotient digit. It avoids
+unnecessary work by aligning digits prior to performing subtraction and finding
+a starting guess for the quotient.
+
+Subtraction was used instead of multiplication for two reasons:
+
+1. Division and subtraction can share code (one of the less important goals of
+ this `bc` is small code).
+2. It minimizes algorithmic complexity.
+
+Using multiplication would make division have the even worse algorithmic
+complexity of `O(n^(2*log_2(3)))` (best case) and `O(n^3)` (worst case).
+
+### Power
+
+This `bc` implements [Exponentiation by Squaring][3], which (via Karatsuba) has
+a complexity of `O((n*log(n))^log_2(3))` which is favorable to the
+`O((n*log(n))^2)` without Karatsuba.
+
+### Square Root
+
+This `bc` implements the fast algorithm [Newton's Method][4] (also known as the
+Newton-Raphson Method, or the [Babylonian Method][5]) to perform the square root
+operation. Its complexity is `O(log(n)*n^2)` as it requires one division per
+iteration.
+
+### Sine and Cosine (`bc` Only)
+
+This `bc` uses the series
+
+```
+x - x^3/3! + x^5/5! - x^7/7! + ...
+```
+
+to calculate `sin(x)` and `cos(x)`. It also uses the relation
+
+```
+cos(x) = sin(x + pi/2)
+```
+
+to calculate `cos(x)`. It has a complexity of `O(n^3)`.
+
+**Note**: this series has a tendency to *occasionally* produce an error of 1
+[ULP][6]. (It is an unfortunate side effect of the algorithm, and there isn't
+any way around it; [this article][7] explains why calculating sine and cosine,
+and the other transcendental functions below, within less than 1 ULP is nearly
+impossible and unnecessary.) Therefore, I recommend that users do their
+calculations with the precision (`scale`) set to at least 1 greater than is
+needed.
+
+### Exponentiation (`bc` Only)
+
+This `bc` uses the series
+
+```
+1 + x + x^2/2! + x^3/3! + ...
+```
+
+to calculate `e^x`. Since this only works when `x` is small, it uses
+
+```
+e^x = (e^(x/2))^2
+```
+
+to reduce `x`. It has a complexity of `O(n^3)`.
+
+**Note**: this series can also produce errors of 1 ULP, so I recommend users do
+their calculations with the precision (`scale`) set to at least 1 greater than
+is needed.
+
+### Natural Logarithm (`bc` Only)
+
+This `bc` uses the series
+
+```
+a + a^3/3 + a^5/5 + ...
+```
+
+(where `a` is equal to `(x - 1)/(x + 1)`) to calculate `ln(x)` when `x` is small
+and uses the relation
+
+```
+ln(x^2) = 2 * ln(x)
+```
+
+to sufficiently reduce `x`. It has a complexity of `O(n^3)`.
+
+**Note**: this series can also produce errors of 1 ULP, so I recommend users do
+their calculations with the precision (`scale`) set to at least 1 greater than
+is needed.
+
+### Arctangent (`bc` Only)
+
+This `bc` uses the series
+
+```
+x - x^3/3 + x^5/5 - x^7/7 + ...
+```
+
+to calculate `atan(x)` for small `x` and the relation
+
+```
+atan(x) = atan(c) + atan((x - c)/(1 + x * c))
+```
+
+to reduce `x` to small enough. It has a complexity of `O(n^3)`.
+
+**Note**: this series can also produce errors of 1 ULP, so I recommend users do
+their calculations with the precision (`scale`) set to at least 1 greater than
+is needed.
+
+### Bessel (`bc` Only)
+
+This `bc` uses the series
+
+```
+x^n/(2^n * n!) * (1 - x^2 * 2 * 1! * (n + 1)) + x^4/(2^4 * 2! * (n + 1) * (n + 2)) - ...
+```
+
+to calculate the bessel function (integer order only).
+
+It also uses the relation
+
+```
+j(-n,x) = (-1)^n * j(n,x)
+```
+
+to calculate the bessel when `x < 0`, It has a complexity of `O(n^3)`.
+
+**Note**: this series can also produce errors of 1 ULP, so I recommend users do
+their calculations with the precision (`scale`) set to at least 1 greater than
+is needed.
+
+### Modular Exponentiation (`dc` Only)
+
+This `dc` uses the [Memory-efficient method][8] to compute modular
+exponentiation. The complexity is `O(e*n^2)`, which may initially seem
+inefficient, but `n` is kept small by maintaining small numbers. In practice, it
+is extremely fast.
+
+[1]: https://en.wikipedia.org/wiki/Karatsuba_algorithm
+[2]: https://en.wikipedia.org/wiki/Long_division
+[3]: https://en.wikipedia.org/wiki/Exponentiation_by_squaring
+[4]: https://en.wikipedia.org/wiki/Newton%27s_method#Square_root_of_a_number
+[5]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
+[6]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[7]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[8]: https://en.wikipedia.org/wiki/Modular_exponentiation#Memory-efficient_method
diff --git a/contrib/bc/manuals/bc.1.md.in b/contrib/bc/manuals/bc.1.md.in
new file mode 100644
index 000000000000..efc0be037526
--- /dev/null
+++ b/contrib/bc/manuals/bc.1.md.in
@@ -0,0 +1,1810 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+{{ A N P NP }}
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1). It also has many extensions and extra features beyond
+other implementations.
+{{ end }}
+{{ E EN EP ENP }}
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1).
+{{ end }}
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+{{ A H N P HN HP NP HNP }}
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ This has the effect that a copy of the current value of all four are pushed
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three are pushed
+{{ end }}
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+{{ A H N P HN HP NP HNP }}
+ (**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.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** globally, functions that are made to do so cannot
+ work anymore. There are two possible use cases for that, and each has a
+ solution.
+{{ end }}
+
+ 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+{{ A H N P HN HP NP HNP }}
+ 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
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+{{ end }}
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+{{ A H N P HN HP NP HNP }}
+ math library and the extended math library before running any code,
+ including any expressions or files specified on the command line.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+{{ end }}
+
+**-P**, **--no-prompt**
+
+{{ 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
+ 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).
+{{ end }}
+{{ P EP HP NP EHP ENP HNP EHNP }}
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+{{ A H N P HN HP NP HNP }}
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+{{ end }}
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+{{ A H N P HN HP NP HNP }}
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+{{ end }}
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+{{ A H N P HN HP NP HNP }}
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+{{ end }}
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+{{ A H N P HN HP NP HNP }}
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+{{ end }}
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+{{ A H N P HN HP NP HNP }}
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+{{ end }}
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+{{ A H N P HN HP NP HNP }}
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+{{ end }}
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+{{ A H N P HN HP NP HNP }}
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+{{ end }}
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+{{ A H N P HN HP NP HNP }}
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+{{ end }}
+
+{{ A H N P HN HP NP HNP }}
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+{{ end }}
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+{{ A H N P HN HP NP HNP }}
+ The **assignment** operators that correspond to operators that are
+ extensions are themselves **non-portable extensions**.
+{{ end }}
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+{{ A H N P HN HP NP HNP }}
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+{{ end }}
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+{{ A H N P HN HP NP HNP }}
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+{{ end }}
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+{{ A H N P HN HP NP HNP }}
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+{{ end }}
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+{{ A H N P HN HP NP HNP }}
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+{{ end }}
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+{{ A H N P HN HP NP HNP }}
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+{{ end }}
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+{{ A H N P HN HP NP HNP }}
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+{{ end }}
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+{{ A E N P EN EP NP ENP }}
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+{{ end }}
+
+{{ A E H N EH EN HN EHN }}
+The prompt is enabled in TTY mode.
+{{ end }}
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+{{ A E N P EN EP NP ENP }}
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+{{ end }}
+{{ H EH HN HP EHN EHP HNP EHNP }}
+default handler for all other signals.
+{{ end }}
+
+{{ A E N P EN EP NP ENP }}
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+{{ end }}
+
+{{ A E H P EH EP HP EHP }}
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+{{ end }}
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+{{ A E H P EH EP HP EHP }}
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+{{ end }}
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/A.1 b/contrib/bc/manuals/bc/A.1
new file mode 100644
index 000000000000..2e2816290587
--- /dev/null
+++ b/contrib/bc/manuals/bc/A.1
@@ -0,0 +1,2041 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+It also has many extensions and extra features beyond other
+implementations.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/A.1.md b/contrib/bc/manuals/bc/A.1.md
new file mode 100644
index 000000000000..5e5b75bb3821
--- /dev/null
+++ b/contrib/bc/manuals/bc/A.1.md
@@ -0,0 +1,1693 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1). It also has many extensions and extra features beyond
+other implementations.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/E.1 b/contrib/bc/manuals/bc/E.1
new file mode 100644
index 000000000000..6bacb680af67
--- /dev/null
+++ b/contrib/bc/manuals/bc/E.1
@@ -0,0 +1,1301 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/E.1.md b/contrib/bc/manuals/bc/E.1.md
new file mode 100644
index 000000000000..3bec29912b77
--- /dev/null
+++ b/contrib/bc/manuals/bc/E.1.md
@@ -0,0 +1,1085 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1).
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/EH.1 b/contrib/bc/manuals/bc/EH.1
new file mode 100644
index 000000000000..ed19e9769bd7
--- /dev/null
+++ b/contrib/bc/manuals/bc/EH.1
@@ -0,0 +1,1283 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/EH.1.md b/contrib/bc/manuals/bc/EH.1.md
new file mode 100644
index 000000000000..32d95f48fcee
--- /dev/null
+++ b/contrib/bc/manuals/bc/EH.1.md
@@ -0,0 +1,1069 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/EHN.1 b/contrib/bc/manuals/bc/EHN.1
new file mode 100644
index 000000000000..39846195d4b3
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHN.1
@@ -0,0 +1,1276 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/EHN.1.md b/contrib/bc/manuals/bc/EHN.1.md
new file mode 100644
index 000000000000..2eaf8145c90e
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHN.1.md
@@ -0,0 +1,1061 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/EHNP.1 b/contrib/bc/manuals/bc/EHNP.1
new file mode 100644
index 000000000000..231dc1d404c4
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHNP.1
@@ -0,0 +1,1269 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/EHNP.1.md b/contrib/bc/manuals/bc/EHNP.1.md
new file mode 100644
index 000000000000..4138ffb98c5e
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHNP.1.md
@@ -0,0 +1,1055 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/EHP.1 b/contrib/bc/manuals/bc/EHP.1
new file mode 100644
index 000000000000..7dcc83b7bddd
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHP.1
@@ -0,0 +1,1276 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/EHP.1.md b/contrib/bc/manuals/bc/EHP.1.md
new file mode 100644
index 000000000000..c012f68fed43
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHP.1.md
@@ -0,0 +1,1063 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/EN.1 b/contrib/bc/manuals/bc/EN.1
new file mode 100644
index 000000000000..d11c6f7742a1
--- /dev/null
+++ b/contrib/bc/manuals/bc/EN.1
@@ -0,0 +1,1294 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/EN.1.md b/contrib/bc/manuals/bc/EN.1.md
new file mode 100644
index 000000000000..e7ba17a98401
--- /dev/null
+++ b/contrib/bc/manuals/bc/EN.1.md
@@ -0,0 +1,1077 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1).
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/ENP.1 b/contrib/bc/manuals/bc/ENP.1
new file mode 100644
index 000000000000..0240b22b495a
--- /dev/null
+++ b/contrib/bc/manuals/bc/ENP.1
@@ -0,0 +1,1287 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/ENP.1.md b/contrib/bc/manuals/bc/ENP.1.md
new file mode 100644
index 000000000000..8e5b6fbdd27c
--- /dev/null
+++ b/contrib/bc/manuals/bc/ENP.1.md
@@ -0,0 +1,1071 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1).
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/EP.1 b/contrib/bc/manuals/bc/EP.1
new file mode 100644
index 000000000000..01f34378fd65
--- /dev/null
+++ b/contrib/bc/manuals/bc/EP.1
@@ -0,0 +1,1294 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.PP
+\f[B]-g\f[R], \f[B]\[en]global-stacks\f[R]
+.IP
+.nf
+\f[C]
+Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+This makes writing functions much easier.
+
+However, since using this flag means that functions cannot set **ibase**,
+**obase**, or **scale** 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:
+
+ 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**, or
+**scale** globally for any other purpose, it could be split into one to
+three functions (based on how many globals it sets) and each of those
+functions could return the desired value for a global.
+
+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
+.TP
+\f[B]-h\f[R], \f[B]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Number 6 is a \f[B]non-portable extension\f[R].
+.PP
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]\[ha]\f[R]
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below are available when the \f[B]-l\f[R] or
+\f[B]\[en]mathlib\f[R] command-line flags are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/EP.1.md b/contrib/bc/manuals/bc/EP.1.md
new file mode 100644
index 000000000000..a853961d683c
--- /dev/null
+++ b/contrib/bc/manuals/bc/EP.1.md
@@ -0,0 +1,1079 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1).
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+ Turns the globals **ibase**, **obase**, and **scale** into stacks.
+
+ This has the effect that a copy of the current value of all three 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ However, since using this flag means that functions cannot set **ibase**,
+ **obase**, or **scale** 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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ Second, if the purpose of a function is to set **ibase**, **obase**, or
+ **scale** globally for any other purpose, it could be split into one to
+ three functions (based on how many globals it sets) and each of those
+ functions could return the desired value for a global.
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** and loads the included
+ math library before running any code, including any expressions or files
+ specified on the command line.
+
+ To learn what is in the library, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **2**. Values are output in the specified
+base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **last** or a single dot (**.**)
+
+Number 6 is a **non-portable extension**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**=** **+=** **-=** **\*=** **/=** **%=** **\^=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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 **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below are available when the **-l** or **--mathlib**
+command-line flags are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator and the corresponding assignment operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/H.1 b/contrib/bc/manuals/bc/H.1
new file mode 100644
index 000000000000..d6053feab4e8
--- /dev/null
+++ b/contrib/bc/manuals/bc/H.1
@@ -0,0 +1,2021 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/H.1.md b/contrib/bc/manuals/bc/H.1.md
new file mode 100644
index 000000000000..f764e47cc0f4
--- /dev/null
+++ b/contrib/bc/manuals/bc/H.1.md
@@ -0,0 +1,1676 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/HN.1 b/contrib/bc/manuals/bc/HN.1
new file mode 100644
index 000000000000..6a8dd876db65
--- /dev/null
+++ b/contrib/bc/manuals/bc/HN.1
@@ -0,0 +1,2014 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/HN.1.md b/contrib/bc/manuals/bc/HN.1.md
new file mode 100644
index 000000000000..9cc71c3be057
--- /dev/null
+++ b/contrib/bc/manuals/bc/HN.1.md
@@ -0,0 +1,1668 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/HNP.1 b/contrib/bc/manuals/bc/HNP.1
new file mode 100644
index 000000000000..30a8b00a5009
--- /dev/null
+++ b/contrib/bc/manuals/bc/HNP.1
@@ -0,0 +1,2007 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/HNP.1.md b/contrib/bc/manuals/bc/HNP.1.md
new file mode 100644
index 000000000000..0425073d1c08
--- /dev/null
+++ b/contrib/bc/manuals/bc/HNP.1.md
@@ -0,0 +1,1662 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/HP.1 b/contrib/bc/manuals/bc/HP.1
new file mode 100644
index 000000000000..2ece4e38cbd1
--- /dev/null
+++ b/contrib/bc/manuals/bc/HP.1
@@ -0,0 +1,2014 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+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
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/HP.1.md b/contrib/bc/manuals/bc/HP.1.md
new file mode 100644
index 000000000000..482f1a482734
--- /dev/null
+++ b/contrib/bc/manuals/bc/HP.1.md
@@ -0,0 +1,1670 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/N.1 b/contrib/bc/manuals/bc/N.1
new file mode 100644
index 000000000000..9250b028635a
--- /dev/null
+++ b/contrib/bc/manuals/bc/N.1
@@ -0,0 +1,2034 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+It also has many extensions and extra features beyond other
+implementations.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/N.1.md b/contrib/bc/manuals/bc/N.1.md
new file mode 100644
index 000000000000..63a5acf8ab47
--- /dev/null
+++ b/contrib/bc/manuals/bc/N.1.md
@@ -0,0 +1,1685 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1). It also has many extensions and extra features beyond
+other implementations.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-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
+ 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**.
+
+**-q**, **--quiet**
+
+: This option is for compatibility with the [GNU bc(1)][2]; 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 **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/NP.1 b/contrib/bc/manuals/bc/NP.1
new file mode 100644
index 000000000000..89377821b179
--- /dev/null
+++ b/contrib/bc/manuals/bc/NP.1
@@ -0,0 +1,2027 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+It also has many extensions and extra features beyond other
+implementations.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/NP.1.md b/contrib/bc/manuals/bc/NP.1.md
new file mode 100644
index 000000000000..60d6a7e59b37
--- /dev/null
+++ b/contrib/bc/manuals/bc/NP.1.md
@@ -0,0 +1,1679 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1). It also has many extensions and extra features beyond
+other implementations.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bc/P.1 b/contrib/bc/manuals/bc/P.1
new file mode 100644
index 000000000000..688d6cb612b3
--- /dev/null
+++ b/contrib/bc/manuals/bc/P.1
@@ -0,0 +1,2034 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BC" "1" "October 2020" "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]\[en]global-stacks\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]mathlib\f[R]] [\f[B]\[en]no-prompt\f[R]]
+[\f[B]\[en]quiet\f[R]] [\f[B]\[en]standard\f[R]] [\f[B]\[en]warn\f[R]]
+[\f[B]\[en]version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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
+1991 by POSIX.
+(The current standard is
+here (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html).)
+The language provides unlimited precision decimal arithmetic and is
+somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+.PP
+After parsing and handling options, this bc(1) reads any files given on
+the command line and executes them before reading from \f[B]stdin\f[R].
+.PP
+This bc(1) is a drop-in replacement for \f[I]any\f[R] bc(1), including
+(and especially) the GNU bc(1).
+It also has many extensions and extra features beyond other
+implementations.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]\[en]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:
+.IP
+.nf
+\f[C]
+define void output(x, b) {
+ obase=b
+ x
+}
+\f[R]
+.fi
+.PP
+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
+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
+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]
+\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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-l\f[R], \f[B]\[en]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
+\f[B]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-q\f[R], \f[B]\[en]quiet\f[R]
+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]\[en]version\f[R] options are given.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-s\f[R], \f[B]\[en]standard\f[R]
+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
+.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]\[en]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
+\f[B]-w\f[R], \f[B]\[en]warn\f[R]
+Like \f[B]-s\f[R] and \f[B]\[en]standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]bc >&-\f[R], it will quit with an error.
+This is done so that bc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other bc(1) implementations, this bc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]bc 2>&-\f[R], it will quit with an error.
+This is done so that bc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other bc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+The syntax for bc(1) programs is mostly C-like, with some differences.
+This bc(1) follows the POSIX
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+which is a much more thorough resource for the language this bc(1)
+accepts.
+This section is meant to be a summary and a listing of all the
+extensions to the standard.
+.PP
+In the sections below, \f[B]E\f[R] means expression, \f[B]S\f[R] means
+statement, and \f[B]I\f[R] means identifier.
+.PP
+Identifiers (\f[B]I\f[R]) start with a lowercase letter and can be
+followed by any number (up to \f[B]BC_NAME_MAX-1\f[R]) of lowercase
+letters (\f[B]a-z\f[R]), digits (\f[B]0-9\f[R]), and underscores
+(\f[B]_\f[R]).
+The regex is \f[B][a-z][a-z0-9_]*\f[R].
+Identifiers with more than one character (letter) are a
+\f[B]non-portable extension\f[R].
+.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
+input numbers.
+\f[B]ibase\f[R] is initially \f[B]10\f[R].
+If the \f[B]-s\f[R] (\f[B]\[en]standard\f[R]) and \f[B]-w\f[R]
+(\f[B]\[en]warn\f[R]) flags were not given on the command line, the max
+allowable value for \f[B]ibase\f[R] is \f[B]36\f[R].
+Otherwise, it is \f[B]16\f[R].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+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
+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
+can be queried in bc(1) programs with the \f[B]maxobase()\f[R] built-in
+function.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a global variable that sets the precision of any operations, with
+exceptions.
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] is \f[B]BC_SCALE_MAX\f[R]
+and can be queried in bc(1) programs with the \f[B]maxscale()\f[R]
+built-in function.
+.PP
+bc(1) has both \f[I]global\f[R] variables and \f[I]local\f[R] variables.
+All \f[I]local\f[R] variables are local to the function; they are
+parameters or are introduced in the \f[B]auto\f[R] list of a function
+(see the \f[B]FUNCTIONS\f[R] section).
+If a variable is accessed which is not a parameter or in the
+\f[B]auto\f[R] list, it is assumed to be \f[I]global\f[R].
+If a parent function has a \f[I]local\f[R] variable version of a
+variable that a child function considers \f[I]global\f[R], the value of
+that \f[I]global\f[R] variable in the child function is the value of the
+variable in the parent function, not the value of the actual
+\f[I]global\f[R] variable.
+.PP
+All of the above applies to arrays as well.
+.PP
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence
+operator is an assignment operator \f[I]and\f[R] the expression is
+notsurrounded by parentheses.
+.PP
+The value that is printed is also assigned to the special variable
+\f[B]last\f[R].
+A single dot (\f[B].\f[R]) may also be used as a synonym for
+\f[B]last\f[R].
+These are \f[B]non-portable extensions\f[R].
+.PP
+Either semicolons or newlines may separate statements.
+.SS Comments
+.PP
+There are two kinds of comments:
+.IP "1." 3
+Block comments are enclosed in \f[B]/*\f[R] and \f[B]*/\f[R].
+.IP "2." 3
+Line comments go from \f[B]#\f[R] until, and not including, the next
+newline.
+This is a \f[B]non-portable extension\f[R].
+.SS Named Expressions
+.PP
+The following are named expressions in bc(1):
+.IP "1." 3
+Variables: \f[B]I\f[R]
+.IP "2." 3
+Array Elements: \f[B]I[E]\f[R]
+.IP "3." 3
+\f[B]ibase\f[R]
+.IP "4." 3
+\f[B]obase\f[R]
+.IP "5." 3
+\f[B]scale\f[R]
+.IP "6." 3
+\f[B]seed\f[R]
+.IP "7." 3
+\f[B]last\f[R] or a single dot (\f[B].\f[R])
+.PP
+Numbers 6 and 7 are \f[B]non-portable extensions\f[R].
+.PP
+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.
+.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 assigned to \f[B]seed\f[R]
+and 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 \f[B]seed\f[R] is queried again immediately.
+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
+\f[I]not\f[R] produce unique sequences of pseudo-random numbers.
+The value of \f[B]seed\f[R] will change after any use of the
+\f[B]rand()\f[R] and \f[B]irand(E)\f[R] operands (see the
+\f[I]Operands\f[R] subsection below), except if the parameter passed to
+\f[B]irand(E)\f[R] is \f[B]0\f[R], \f[B]1\f[R], or negative.
+.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
+Variables and arrays do not interfere; users can have arrays named the
+same as variables.
+This also applies to functions (see the \f[B]FUNCTIONS\f[R] section), so
+a user can have a variable, array, and function that all have the same
+name, and they will not shadow each other, whether inside of functions
+or not.
+.PP
+Named expressions are required as the operand of
+\f[B]increment\f[R]/\f[B]decrement\f[R] operators and as the left side
+of \f[B]assignment\f[R] operators (see the \f[I]Operators\f[R]
+subsection).
+.SS Operands
+.PP
+The following are valid operands in bc(1):
+.IP " 1." 4
+Numbers (see the \f[I]Numbers\f[R] subsection below).
+.IP " 2." 4
+Array indices (\f[B]I[E]\f[R]).
+.IP " 3." 4
+\f[B](E)\f[R]: The value of \f[B]E\f[R] (used to change precedence).
+.IP " 4." 4
+\f[B]sqrt(E)\f[R]: The square root of \f[B]E\f[R].
+\f[B]E\f[R] must be non-negative.
+.IP " 5." 4
+\f[B]length(E)\f[R]: The number of significant decimal digits in
+\f[B]E\f[R].
+.IP " 6." 4
+\f[B]length(I[])\f[R]: The number of elements in the array \f[B]I\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 7." 4
+\f[B]scale(E)\f[R]: The \f[I]scale\f[R] of \f[B]E\f[R].
+.IP " 8." 4
+\f[B]abs(E)\f[R]: The absolute value of \f[B]E\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP " 9." 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 non-\f[B]void\f[R] function (see the
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.IP "10." 4
+\f[B]read()\f[R]: Reads a line from \f[B]stdin\f[R] and uses that as an
+expression.
+The result of that expression is the result of the \f[B]read()\f[R]
+operand.
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]maxibase()\f[R]: The max allowable \f[B]ibase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 4
+\f[B]maxobase()\f[R]: The max allowable \f[B]obase\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "13." 4
+\f[B]maxscale()\f[R]: The max allowable \f[B]scale\f[R].
+This is a \f[B]non-portable extension\f[R].
+.IP "14." 4
+\f[B]rand()\f[R]: A pseudo-random integer between \f[B]0\f[R]
+(inclusive) and \f[B]BC_RAND_MAX\f[R] (inclusive).
+Using this operand will change the value of \f[B]seed\f[R].
+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
+\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.
+If \f[B]E\f[R] is larger than \f[B]BC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]BC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this operand is
+unbounded.
+Using this operand will change the value of \f[B]seed\f[R], unless the
+value of \f[B]E\f[R] is \f[B]0\f[R] or \f[B]1\f[R].
+In that case, \f[B]0\f[R] is returned, and \f[B]seed\f[R] is
+\f[I]not\f[R] changed.
+This is a \f[B]non-portable extension\f[R].
+.IP "16." 4
+\f[B]maxrand()\f[R]: The max integer returned by \f[B]rand()\f[R].
+This is a \f[B]non-portable extension\f[R].
+.PP
+The integers generated by \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are
+guaranteed to be as unbiased as possible, subject to the limitations of
+the pseudo-random number generator.
+.PP
+\f[B]Note\f[R]: The values returned by the pseudo-random number
+generator with \f[B]rand()\f[R] and \f[B]irand(E)\f[R] are guaranteed to
+\f[I]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
+\f[B]seed\f[R] values.
+.SS Numbers
+.PP
+Numbers are strings made up of digits, uppercase letters, and at most
+\f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]BC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]Z\f[R] alone always equals decimal \f[B]35\f[R].
+.PP
+In addition, bc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e-3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.PP
+Using scientific notation is an error or warning if the \f[B]-s\f[R] or
+\f[B]-w\f[R], respectively, command-line options (or equivalents) are
+given.
+.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 bc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if bc(1) is given the number string
+\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SS Operators
+.PP
+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
+\f[B]++\f[R] \f[B]\[en]\f[R]
+Type: Prefix and Postfix
+.RS
+.PP
+Associativity: None
+.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
+Associativity: None
+.PP
+Description: \f[B]negation\f[R], \f[B]boolean not\f[R]
+.RE
+.TP
+\f[B]$\f[R]
+Type: Postfix
+.RS
+.PP
+Associativity: None
+.PP
+Description: \f[B]truncation\f[R]
+.RE
+.TP
+\f[B]\[at]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.PP
+Description: \f[B]set precision\f[R]
+.RE
+.TP
+\f[B]\[ha]\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Right
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+Associativity: Left
+.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
+.PP
+Associativity: Right
+.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
+.PP
+Associativity: Left
+.PP
+Description: \f[B]relational\f[R]
+.RE
+.TP
+\f[B]&&\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean and\f[R]
+.RE
+.TP
+\f[B]||\f[R]
+Type: Binary
+.RS
+.PP
+Associativity: Left
+.PP
+Description: \f[B]boolean or\f[R]
+.RE
+.PP
+The operators will be described in more detail below.
+.TP
+\f[B]++\f[R] \f[B]\[en]\f[R]
+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
+.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
+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]
+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
+\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
+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
+.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,
+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
+.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.
+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
+\f[B]/\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]%\f[R]
+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
+The second expression must be non-zero.
+.RE
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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]
+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
+.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]
+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
+.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] \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
+.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].
+.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].
+Otherwise, it is \f[B]0\f[R].
+.RS
+.PP
+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].
+.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
+\f[B]1\f[R] if both expressions are 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
+.TP
+\f[B]||\f[R]
+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
+.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]
+.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
+\f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+\f[B]else\f[R] \f[B]S\f[R]
+.IP " 5." 4
+\f[B]while\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 6." 4
+\f[B]for\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B];\f[R] \f[B]E\f[R]
+\f[B];\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R]
+.IP " 7." 4
+An empty statement
+.IP " 8." 4
+\f[B]break\f[R]
+.IP " 9." 4
+\f[B]continue\f[R]
+.IP "10." 4
+\f[B]quit\f[R]
+.IP "11." 4
+\f[B]halt\f[R]
+.IP "12." 4
+\f[B]limits\f[R]
+.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]
+.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
+\f[I]Void Functions\f[R] subsection of the \f[B]FUNCTIONS\f[R] section).
+The \f[B]E\f[R] argument(s) may also be arrays of the form
+\f[B]I[]\f[R], which will automatically be turned into array references
+(see the \f[I]Array References\f[R] subsection of the
+\f[B]FUNCTIONS\f[R] section) if the corresponding parameter in the
+function definition is an array reference.
+.PP
+Numbers 4, 9, 11, 12, 14, and 15 are \f[B]non-portable extensions\f[R].
+.PP
+Also, as a \f[B]non-portable extension\f[R], any or all of the
+expressions in the header of a for loop may be omitted.
+If the condition (second expression) is omitted, it is assumed to be a
+constant \f[B]1\f[R].
+.PP
+The \f[B]break\f[R] statement causes a loop to stop iterating and resume
+execution immediately following a loop.
+This is only allowed in loops.
+.PP
+The \f[B]continue\f[R] statement causes a loop iteration to stop early
+and returns to the start of the loop, including testing the loop
+condition.
+This is only allowed in loops.
+.PP
+The \f[B]if\f[R] \f[B]else\f[R] statement does the same thing as in C.
+.PP
+The \f[B]quit\f[R] statement causes bc(1) to quit, even if it is on a
+branch that will not be executed (it is a compile-time command).
+.PP
+The \f[B]halt\f[R] statement causes bc(1) to quit, if it is executed.
+(Unlike \f[B]quit\f[R] if it is on a branch of an \f[B]if\f[R] statement
+that is not executed, bc(1) does not quit.)
+.PP
+The \f[B]limits\f[R] statement prints the limits that this bc(1) is
+subject to.
+This is like the \f[B]quit\f[R] statement in that it is a compile-time
+command.
+.PP
+An expression by itself is evaluated and printed, followed by a newline.
+.PP
+Both scientific notation and engineering notation are available for
+printing the results of expressions.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R], and engineering notation is activated by assigning
+\f[B]1\f[R] to \f[B]obase\f[R].
+To deactivate them, just assign a different value to \f[B]obase\f[R].
+.PP
+Scientific notation and engineering notation are disabled if bc(1) is
+run with either the \f[B]-s\f[R] or \f[B]-w\f[R] command-line options
+(or equivalents).
+.PP
+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
+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
+Any other character following a backslash causes the backslash and
+character to be printed as-is.
+.PP
+Any non-string expression in a print statement shall be assigned to
+\f[B]last\f[R], like any other expression that is printed.
+.SS Order of Evaluation
+.PP
+All expressions in a statment are evaluated left to right, except as
+necessary to maintain order of operations.
+This means, for example, assuming that \f[B]i\f[R] is equal to
+\f[B]0\f[R], in the expression
+.IP
+.nf
+\f[C]
+a[i++] = i++
+\f[R]
+.fi
+.PP
+the first (or 0th) element of \f[B]a\f[R] is set to \f[B]1\f[R], and
+\f[B]i\f[R] is equal to \f[B]2\f[R] at the end of the expression.
+.PP
+This includes function arguments.
+Thus, assuming \f[B]i\f[R] is equal to \f[B]0\f[R], this means that in
+the expression
+.IP
+.nf
+\f[C]
+x(i++, i++)
+\f[R]
+.fi
+.PP
+the first argument passed to \f[B]x()\f[R] is \f[B]0\f[R], and the
+second argument is \f[B]1\f[R], while \f[B]i\f[R] is equal to
+\f[B]2\f[R] before the function starts executing.
+.SH FUNCTIONS
+.PP
+Function definitions are as follows:
+.IP
+.nf
+\f[C]
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+\f[R]
+.fi
+.PP
+Any \f[B]I\f[R] in the parameter list or \f[B]auto\f[R] list may be
+replaced with \f[B]I[]\f[R] to make a parameter or \f[B]auto\f[R] var an
+array, and any \f[B]I\f[R] in the parameter list may be replaced with
+\f[B]*I[]\f[R] to make a parameter an array reference.
+Callers of functions that take array references should not put an
+asterisk in the call; they must be called with just \f[B]I[]\f[R] like
+normal array parameters and will be automatically converted into
+references.
+.PP
+As a \f[B]non-portable extension\f[R], the opening brace of a
+\f[B]define\f[R] statement may appear on the next line.
+.PP
+As a \f[B]non-portable extension\f[R], the return statement may also be
+in one of the following forms:
+.IP "1." 3
+\f[B]return\f[R]
+.IP "2." 3
+\f[B]return\f[R] \f[B](\f[R] \f[B])\f[R]
+.IP "3." 3
+\f[B]return\f[R] \f[B]E\f[R]
+.PP
+The first two, or not specifying a \f[B]return\f[R] statement, is
+equivalent to \f[B]return (0)\f[R], unless the function is a
+\f[B]void\f[R] function (see the \f[I]Void Functions\f[R] subsection
+below).
+.SS Void Functions
+.PP
+Functions can also be \f[B]void\f[R] functions, defined as follows:
+.IP
+.nf
+\f[C]
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+\f[R]
+.fi
+.PP
+They can only be used as standalone expressions, where such an
+expression would be printed alone, except in a print statement.
+.PP
+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
+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
+\f[B]define\f[R] keyword.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SS Array References
+.PP
+For any array in the parameter list, if the array is declared in the
+form
+.IP
+.nf
+\f[C]
+*I[]
+\f[R]
+.fi
+.PP
+it is a \f[B]reference\f[R].
+Any changes to the array in the function are reflected, when the
+function returns, to the array that was passed in.
+.PP
+Other than this, all function arguments are passed by value.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.SH LIBRARY
+.PP
+All of the functions below, including the functions in the extended math
+library (see the \f[I]Extended Library\f[R] subsection below), are
+available when the \f[B]-l\f[R] or \f[B]\[en]mathlib\f[R] command-line
+flags are given, except that the extended math library is not available
+when the \f[B]-s\f[R] option, the \f[B]-w\f[R] option, or equivalents
+are given.
+.SS Standard Library
+.PP
+The
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+defines the following functions for the math library:
+.TP
+\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
+\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
+\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
+\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
+\f[B]e(x)\f[R]
+Returns the mathematical constant \f[B]e\f[R] raised to the power 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
+\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
+.SS Extended Library
+.PP
+The extended library is \f[I]not\f[R] loaded when the
+\f[B]-s\f[R]/\f[B]\[en]standard\f[R] or \f[B]-w\f[R]/\f[B]\[en]warn\f[R]
+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
+\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
+\f[B]scale\f[R].
+.RS
+.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
+the rounding mode round half away from
+\f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).
+.TP
+\f[B]ceil(x, p)\f[R]
+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
+\f[B]f(x)\f[R]
+Returns the factorial of the truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]perm(n, k)\f[R]
+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
+\f[B]comb(n, k)\f[R]
+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
+\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
+\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
+\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
+\f[B]cbrt(x)\f[R]
+Returns the cube root of \f[B]x\f[R].
+.TP
+\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
+\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
+\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
+\f[B]a2(y, x)\f[R]
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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].
+.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].
+.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).
+.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].
+.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.
+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
+\f[B]a(y/x)\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is greater than
+or equal to \f[B]0\f[R], it returns \f[B]a(y/x)+pi\f[R].
+If \f[B]x\f[R] is less than \f[B]0\f[R], and \f[B]y\f[R] is less than
+\f[B]0\f[R], it returns \f[B]a(y/x)-pi\f[R].
+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
+.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
+\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
+\f[B]frand(p)\f[R]
+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
+\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].
+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
+\f[B]srand(x)\f[R]
+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
+\f[B]brand()\f[R]
+Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]).
+.TP
+\f[B]ubytes(x)\f[R]
+Returns the numbers of unsigned integer bytes required to hold the
+truncated absolute value of \f[B]x\f[R].
+.TP
+\f[B]sbytes(x)\f[R]
+Returns the numbers of signed, two\[cq]s-complement integer bytes
+required to hold the truncated value of \f[B]x\f[R].
+.TP
+\f[B]hex(x)\f[R]
+Outputs the hexadecimal (base \f[B]16\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
+\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
+\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
+\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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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.
+Both outputs are split into bytes separated by spaces.
+.RS
+.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
+\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
+.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
+\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
+.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
+\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
+.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
+.SS Transcendental Functions
+.PP
+All transcendental functions can return slightly inaccurate results (up
+to 1 ULP (https://en.wikipedia.org/wiki/Unit_in_the_last_place)).
+This is unavoidable, and this
+article (https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT) explains
+why it is impossible and unnecessary to calculate exact results for the
+transcendental functions.
+.PP
+Because of the possible inaccuracy, I recommend that users call those
+functions with the precision (\f[B]scale\f[R]) set to at least 1 higher
+than is necessary.
+If exact results are \f[I]absolutely\f[R] required, users can double the
+precision (\f[B]scale\f[R]) and then truncate.
+.PP
+The transcendental functions in the standard math library are:
+.IP \[bu] 2
+\f[B]s(x)\f[R]
+.IP \[bu] 2
+\f[B]c(x)\f[R]
+.IP \[bu] 2
+\f[B]a(x)\f[R]
+.IP \[bu] 2
+\f[B]l(x)\f[R]
+.IP \[bu] 2
+\f[B]e(x)\f[R]
+.IP \[bu] 2
+\f[B]j(x, n)\f[R]
+.PP
+The transcendental functions in the extended math library are:
+.IP \[bu] 2
+\f[B]l2(x)\f[R]
+.IP \[bu] 2
+\f[B]l10(x)\f[R]
+.IP \[bu] 2
+\f[B]log(x, b)\f[R]
+.IP \[bu] 2
+\f[B]pi(p)\f[R]
+.IP \[bu] 2
+\f[B]t(x)\f[R]
+.IP \[bu] 2
+\f[B]a2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]sin(x)\f[R]
+.IP \[bu] 2
+\f[B]cos(x)\f[R]
+.IP \[bu] 2
+\f[B]tan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan(x)\f[R]
+.IP \[bu] 2
+\f[B]atan2(y, x)\f[R]
+.IP \[bu] 2
+\f[B]r2d(x)\f[R]
+.IP \[bu] 2
+\f[B]d2r(x)\f[R]
+.SH RESET
+.PP
+When bc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any functions that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all functions returned) is skipped.
+.PP
+Thus, when bc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.PP
+Note that this reset behavior is different from the GNU bc(1), which
+attempts to start executing the statement right after the one that
+caused an error.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This bc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+The actual values of \f[B]BC_LONG_BIT\f[R] and \f[B]BC_BASE_DIGS\f[R]
+can be queried with the \f[B]limits\f[R] statement.
+.PP
+In addition, this bc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]BC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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.
+.PP
+These limits are meant to be effectively non-existent; the limits are so
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+bc(1) recognizes the following environment variables:
+.TP
+\f[B]POSIXLY_CORRECT\f[R]
+If this variable exists (no matter the contents), bc(1) behaves as if
+the \f[B]-s\f[R] option was given.
+.TP
+\f[B]BC_ENV_ARGS\f[R]
+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
+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
+.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
+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]).
+The default line length is \f[B]70\f[R].
+.SH EXIT STATUS
+.PP
+bc(1) returns the following exit statuses:
+.TP
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+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
+.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
+.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.
+.PP
+The other statuses will only be returned when bc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+bc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Per the
+standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, bc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to bc(1) as it is
+executing a file, it can seem as though bc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause bc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when bc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause bc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+bc(1) supports interactive command-line editing.
+If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This bc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGES\f[R].
+.SH SEE ALSO
+.PP
+dc(1)
+.SH STANDARDS
+.PP
+bc(1) is compliant with the IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+The flags \f[B]-efghiqsvVw\f[R], all long options, and the extensions
+noted above are extensions to that specification.
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+.PP
+This bc(1) supports error messages for different locales, and thus, it
+supports \f[B]LC_MESSAGES\f[R].
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bc/P.1.md b/contrib/bc/manuals/bc/P.1.md
new file mode 100644
index 000000000000..af712806cfc7
--- /dev/null
+++ b/contrib/bc/manuals/bc/P.1.md
@@ -0,0 +1,1687 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+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*...]
+
+# DESCRIPTION
+
+bc(1) is an interactive processor for a language first standardized in 1991 by
+POSIX. (The current standard is [here][1].) The language provides unlimited
+precision decimal arithmetic and is somewhat C-like, but there are differences.
+Such differences will be noted in this document.
+
+After parsing and handling options, this bc(1) reads any files given on the
+command line and executes them before reading from **stdin**.
+
+This bc(1) is a drop-in replacement for *any* bc(1), including (and
+especially) the GNU bc(1). It also has many extensions and extra features beyond
+other implementations.
+
+# OPTIONS
+
+The following are the options that bc(1) accepts.
+
+**-g**, **--global-stacks**
+
+: Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks.
+
+ 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:
+
+ define void output(x, b) {
+ auto c
+ c=obase
+ obase=b
+ x
+ obase=c
+ }
+
+ This makes writing functions much easier.
+
+ (**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:
+
+ alias d2o="bc -e ibase=A -e obase=8"
+ alias h2b="bc -e ibase=G -e obase=2"
+
+ 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**.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-l**, **--mathlib**
+
+: Sets **scale** (see the **SYNTAX** section) to **20** 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.
+
+ To learn what is in the libraries, see the **LIBRARY** section.
+
+**-P**, **--no-prompt**
+
+: 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.
+ Without this option, GNU bc(1) prints a copyright header. This bc(1) only
+ prints the copyright header if one or more of the **-v**, **-V**, or
+ **--version** options are given.
+
+ This is a **non-portable extension**.
+
+**-s**, **--standard**
+
+: Process exactly the language defined by the [standard][1] and error if any
+ extensions are used.
+
+ This is a **non-portable extension**.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+ This is a **non-portable extension**.
+
+**-w**, **--warn**
+
+: Like **-s** and **--standard**, except that warnings (and not errors) are
+ printed for non-standard extensions and execution continues normally.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, bc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **bc <file> >&-**, it will quit with an error. This
+is done so that bc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other bc(1) implementations, this bc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **bc <file> 2>&-**, it will quit with an error. This
+is done so that bc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other bc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+The syntax for bc(1) programs is mostly C-like, with some differences. This
+bc(1) follows the [POSIX standard][1], which is a much more thorough resource
+for the language this bc(1) accepts. This section is meant to be a summary and a
+listing of all the extensions to the standard.
+
+In the sections below, **E** means expression, **S** means statement, and **I**
+means identifier.
+
+Identifiers (**I**) start with a lowercase letter and can be followed by any
+number (up to **BC_NAME_MAX-1**) of lowercase letters (**a-z**), digits
+(**0-9**), and underscores (**\_**). The regex is **\[a-z\]\[a-z0-9\_\]\***.
+Identifiers with more than one character (letter) are a
+**non-portable extension**.
+
+**ibase** is a global variable determining how to interpret constant numbers. It
+is the "input" base, or the number base used for interpreting input numbers.
+**ibase** is initially **10**. If the **-s** (**--standard**) and **-w**
+(**--warn**) flags were not given on the command line, the max allowable value
+for **ibase** is **36**. Otherwise, it is **16**. The min allowable value for
+**ibase** is **2**. The max allowable value for **ibase** can be queried in
+bc(1) programs with the **maxibase()** built-in function.
+
+**obase** is a global variable determining how to output results. It is the
+"output" base, or the number base used for outputting numbers. **obase** is
+initially **10**. The max allowable value for **obase** is **BC_BASE_MAX** and
+can be queried in bc(1) programs with the **maxobase()** built-in function. The
+min allowable value for **obase** is **0**. If **obase** is **0**, values are
+output in scientific notation, and if **obase** is **1**, values are output in
+engineering notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a global variable that
+sets the precision of any operations, with exceptions. **scale** is initially
+**0**. **scale** cannot be negative. The max allowable value for **scale** is
+**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()**
+built-in function.
+
+bc(1) has both *global* variables and *local* variables. All *local*
+variables are local to the function; they are parameters or are introduced in
+the **auto** list of a function (see the **FUNCTIONS** section). If a variable
+is accessed which is not a parameter or in the **auto** list, it is assumed to
+be *global*. If a parent function has a *local* variable version of a variable
+that a child function considers *global*, the value of that *global* variable in
+the child function is the value of the variable in the parent function, not the
+value of the actual *global* variable.
+
+All of the above applies to arrays as well.
+
+The value of a statement that is an expression (i.e., any of the named
+expressions or operands) is printed unless the lowest precedence operator is an
+assignment operator *and* the expression is notsurrounded by parentheses.
+
+The value that is printed is also assigned to the special variable **last**. A
+single dot (**.**) may also be used as a synonym for **last**. These are
+**non-portable extensions**.
+
+Either semicolons or newlines may separate statements.
+
+## Comments
+
+There are two kinds of comments:
+
+1. Block comments are enclosed in **/\*** and **\*/**.
+2. Line comments go from **#** until, and not including, the next newline. This
+ is a **non-portable extension**.
+
+## Named Expressions
+
+The following are named expressions in bc(1):
+
+1. Variables: **I**
+2. Array Elements: **I[E]**
+3. **ibase**
+4. **obase**
+5. **scale**
+6. **seed**
+7. **last** or a single dot (**.**)
+
+Numbers 6 and 7 are **non-portable extensions**.
+
+The meaning of **seed** is dependent on the current pseudo-random number
+generator but is guaranteed to not change except for new major versions.
+
+The *scale* and sign of the value may be significant.
+
+If a previously used **seed** value is assigned to **seed** and 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
+**seed** is queried again immediately. 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. The value of **seed** will change after any use of the **rand()** and
+**irand(E)** operands (see the *Operands* subsection below), except if the
+parameter passed to **irand(E)** is **0**, **1**, or negative.
+
+There is no limit to the length (number of significant decimal digits) or
+*scale* of the value that can be assigned to **seed**.
+
+Variables and arrays do not interfere; users can have arrays named the same as
+variables. This also applies to functions (see the **FUNCTIONS** section), so a
+user can have a variable, array, and function that all have the same name, and
+they will not shadow each other, whether inside of functions or not.
+
+Named expressions are required as the operand of **increment**/**decrement**
+operators and as the left side of **assignment** operators (see the *Operators*
+subsection).
+
+## Operands
+
+The following are valid operands in bc(1):
+
+1. Numbers (see the *Numbers* subsection below).
+2. Array indices (**I[E]**).
+3. **(E)**: The value of **E** (used to change precedence).
+4. **sqrt(E)**: The square root of **E**. **E** must be non-negative.
+5. **length(E)**: The number of significant decimal digits in **E**.
+6. **length(I[])**: The number of elements in the array **I**. This is a
+ **non-portable extension**.
+7. **scale(E)**: The *scale* of **E**.
+8. **abs(E)**: The absolute value of **E**. This is a **non-portable
+ extension**.
+9. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a non-**void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+10. **read()**: Reads a line from **stdin** and uses that as an expression. The
+ result of that expression is the result of the **read()** operand. This is a
+ **non-portable extension**.
+11. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+12. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+13. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+14. **rand()**: A pseudo-random integer between **0** (inclusive) and
+ **BC_RAND_MAX** (inclusive). Using this operand will change the value of
+ **seed**. This is a **non-portable extension**.
+15. **irand(E)**: A pseudo-random integer between **0** (inclusive) and the
+ value of **E** (exclusive). If **E** is negative or is a non-integer
+ (**E**'s *scale* is not **0**), an error is raised, and bc(1) resets (see
+ the **RESET** section) while **seed** remains unchanged. If **E** is larger
+ than **BC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **BC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this operand is unbounded. Using this operand will
+ change the value of **seed**, unless the value of **E** is **0** or **1**.
+ In that case, **0** is returned, and **seed** is *not* changed. This is a
+ **non-portable extension**.
+16. **maxrand()**: The max integer returned by **rand()**. This is a
+ **non-portable extension**.
+
+The integers generated by **rand()** and **irand(E)** are guaranteed to be as
+unbiased as possible, subject to the limitations of the pseudo-random number
+generator.
+
+**Note**: The values returned by the pseudo-random number generator with
+**rand()** and **irand(E)** are guaranteed to *NOT* be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they *are* guaranteed to be reproducible with identical **seed** values.
+
+## Numbers
+
+Numbers are strings made up of digits, uppercase letters, and at most **1**
+period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase
+letters are equal to **9** + their position in the alphabet (i.e., **A** equals
+**10**, or **9+1**). If a digit or letter makes no sense with the current value
+of **ibase**, they are set to the value of the highest valid digit in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **Z** alone always equals decimal
+**35**.
+
+In addition, bc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
+
+Using scientific notation is an error or warning if the **-s** or **-w**,
+respectively, command-line options (or equivalents) are given.
+
+**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\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and bc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if bc(1) is given the
+number string **10e-4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+## Operators
+
+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.
+
+**++** **--**
+
+: Type: Prefix and Postfix
+
+ Associativity: None
+
+ Description: **increment**, **decrement**
+
+**-** **!**
+
+: Type: Prefix
+
+ Associativity: None
+
+ Description: **negation**, **boolean not**
+
+**\$**
+
+: Type: Postfix
+
+ Associativity: None
+
+ Description: **truncation**
+
+**\@**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **set precision**
+
+**\^**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **power**
+
+**\*** **/** **%**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **multiply**, **divide**, **modulus**
+
+**+** **-**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **add**, **subtract**
+
+**\<\<** **\>\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **shift left**, **shift right**
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: Type: Binary
+
+ Associativity: Right
+
+ Description: **assignment**
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **relational**
+
+**&&**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean and**
+
+**||**
+
+: Type: Binary
+
+ Associativity: Left
+
+ Description: **boolean or**
+
+The operators will be described in more detail below.
+
+**++** **--**
+
+: The prefix and postfix **increment** and **decrement** operators behave
+ exactly like they would in C. They require a named expression (see the
+ *Named Expressions* subsection) as an operand.
+
+ The prefix versions of these operators are more efficient; use them where
+ possible.
+
+**-**
+
+: The **negation** operator returns **0** if a user attempts to negate any
+ expression with the value **0**. Otherwise, a copy of the expression with
+ its sign flipped is returned.
+
+**!**
+
+: The **boolean not** operator returns **1** if the expression is **0**, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The **truncation** operator returns a copy of the given expression with all
+ of its *scale* removed.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: The **set precision** operator takes two expressions and returns a copy of
+ the first with its *scale* equal to the value of the second expression. That
+ could either mean that the number is returned without change (if the
+ *scale* of the first expression matches the value of the second
+ expression), extended (if it is less), or truncated (if it is more).
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: The **power** operator (not the **exclusive or** operator, as it would be in
+ C) takes two expressions and raises the first to the power of the value of
+ the second. The *scale* of the result is equal to **scale**.
+
+ The second expression must be an integer (no *scale*), and if it is
+ negative, the first value must be non-zero.
+
+**\***
+
+: The **multiply** operator takes two expressions, multiplies them, and
+ returns the product. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result is
+ equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The **divide** operator takes two expressions, divides them, and returns the
+ quotient. The *scale* of the result shall be the value of **scale**.
+
+ The second expression must be non-zero.
+
+**%**
+
+: The **modulus** operator takes two expressions, **a** and **b**, and
+ evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the
+ result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The second expression must be non-zero.
+
+**+**
+
+: The **add** operator takes two expressions, **a** and **b**, and returns the
+ sum, with a *scale* equal to the max of the *scale*s of **a** and **b**.
+
+**-**
+
+: The **subtract** operator takes two expressions, **a** and **b**, and
+ returns the difference, with a *scale* equal to the max of the *scale*s of
+ **a** and **b**.
+
+**\<\<**
+
+: The **left shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the right.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**\>\>**
+
+: The **right shift** operator takes two expressions, **a** and **b**, and
+ returns a copy of the value of **a** with its decimal point moved **b**
+ places to the left.
+
+ The second expression must be an integer (no *scale*) and non-negative.
+
+ This is a **non-portable extension**.
+
+**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=**
+
+: The **assignment** operators take two expressions, **a** and **b** where
+ **a** is a named expression (see the *Named Expressions* subsection).
+
+ 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**.
+
+**==** **\<=** **\>=** **!=** **\<** **\>**
+
+: The **relational** operators compare two expressions, **a** and **b**, and
+ if the relation holds, according to C language semantics, the result is
+ **1**. Otherwise, it is **0**.
+
+ Note that unlike in C, these operators have a lower precedence than the
+ **assignment** operators, which means that **a=b\>c** is interpreted as
+ **(a=b)\>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**.
+
+**&&**
+
+: The **boolean and** operator takes two expressions and returns **1** if both
+ expressions are non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+**||**
+
+: The **boolean or** operator takes two expressions and returns **1** if one
+ of the expressions is non-zero, **0** otherwise.
+
+ This is *not* a short-circuit operator.
+
+ This is a **non-portable extension**.
+
+## Statements
+
+The following items are statements:
+
+1. **E**
+2. **{** **S** **;** ... **;** **S** **}**
+3. **if** **(** **E** **)** **S**
+4. **if** **(** **E** **)** **S** **else** **S**
+5. **while** **(** **E** **)** **S**
+6. **for** **(** **E** **;** **E** **;** **E** **)** **S**
+7. An empty statement
+8. **break**
+9. **continue**
+10. **quit**
+11. **halt**
+12. **limits**
+13. A string of characters, enclosed in double quotes
+14. **print** **E** **,** ... **,** **E**
+15. **I()**, **I(E)**, **I(E, E)**, and so on, where **I** is an identifier for
+ a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section). The **E** argument(s) may also be arrays of the form
+ **I[]**, which will automatically be turned into array references (see the
+ *Array References* subsection of the **FUNCTIONS** section) if the
+ corresponding parameter in the function definition is an array reference.
+
+Numbers 4, 9, 11, 12, 14, and 15 are **non-portable extensions**.
+
+Also, as a **non-portable extension**, any or all of the expressions in the
+header of a for loop may be omitted. If the condition (second expression) is
+omitted, it is assumed to be a constant **1**.
+
+The **break** statement causes a loop to stop iterating and resume execution
+immediately following a loop. This is only allowed in loops.
+
+The **continue** statement causes a loop iteration to stop early and returns to
+the start of the loop, including testing the loop condition. This is only
+allowed in loops.
+
+The **if** **else** statement does the same thing as in C.
+
+The **quit** statement causes bc(1) to quit, even if it is on a branch that will
+not be executed (it is a compile-time command).
+
+The **halt** statement causes bc(1) to quit, if it is executed. (Unlike **quit**
+if it is on a branch of an **if** statement that is not executed, bc(1) does not
+quit.)
+
+The **limits** statement prints the limits that this bc(1) is subject to. This
+is like the **quit** statement in that it is a compile-time command.
+
+An expression by itself is evaluated and printed, followed by a newline.
+
+Both scientific notation and engineering notation are available for printing the
+results of expressions. Scientific notation is activated by assigning **0** to
+**obase**, and engineering notation is activated by assigning **1** to
+**obase**. To deactivate them, just assign a different value to **obase**.
+
+Scientific notation and engineering notation are disabled if bc(1) is run with
+either the **-s** or **-w** command-line options (or equivalents).
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+## Print Statement
+
+The "expressions" in a **print** 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:
+
+-------- -------
+**\\a** **\\a**
+**\\b** **\\b**
+**\\\\** **\\**
+**\\e** **\\**
+**\\f** **\\f**
+**\\n** **\\n**
+**\\q** **"**
+**\\r** **\\r**
+**\\t** **\\t**
+-------- -------
+
+Any other character following a backslash causes the backslash and character to
+be printed as-is.
+
+Any non-string expression in a print statement shall be assigned to **last**,
+like any other expression that is printed.
+
+## Order of Evaluation
+
+All expressions in a statment are evaluated left to right, except as necessary
+to maintain order of operations. This means, for example, assuming that **i** is
+equal to **0**, in the expression
+
+ a[i++] = i++
+
+the first (or 0th) element of **a** is set to **1**, and **i** is equal to **2**
+at the end of the expression.
+
+This includes function arguments. Thus, assuming **i** is equal to **0**, this
+means that in the expression
+
+ x(i++, i++)
+
+the first argument passed to **x()** is **0**, and the second argument is **1**,
+while **i** is equal to **2** before the function starts executing.
+
+# FUNCTIONS
+
+Function definitions are as follows:
+
+```
+define I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return(E)
+}
+```
+
+Any **I** in the parameter list or **auto** list may be replaced with **I[]** to
+make a parameter or **auto** var an array, and any **I** in the parameter list
+may be replaced with **\*I[]** to make a parameter an array reference. Callers
+of functions that take array references should not put an asterisk in the call;
+they must be called with just **I[]** like normal array parameters and will be
+automatically converted into references.
+
+As a **non-portable extension**, the opening brace of a **define** statement may
+appear on the next line.
+
+As a **non-portable extension**, the return statement may also be in one of the
+following forms:
+
+1. **return**
+2. **return** **(** **)**
+3. **return** **E**
+
+The first two, or not specifying a **return** statement, is equivalent to
+**return (0)**, unless the function is a **void** function (see the *Void
+Functions* subsection below).
+
+## Void Functions
+
+Functions can also be **void** functions, defined as follows:
+
+```
+define void I(I,...,I){
+ auto I,...,I
+ S;...;S
+ return
+}
+```
+
+They can only be used as standalone expressions, where such an expression would
+be printed alone, except in a print statement.
+
+Void functions can only use the first two **return** statements listed above.
+They can also omit the return statement entirely.
+
+The word "void" is not treated as a keyword; it is still possible to have
+variables, arrays, and functions named **void**. The word "void" is only
+treated specially right after the **define** keyword.
+
+This is a **non-portable extension**.
+
+## Array References
+
+For any array in the parameter list, if the array is declared in the form
+
+```
+*I[]
+```
+
+it is a **reference**. Any changes to the array in the function are reflected,
+when the function returns, to the array that was passed in.
+
+Other than this, all function arguments are passed by value.
+
+This is a **non-portable extension**.
+
+# LIBRARY
+
+All of the functions below, including the functions in the extended math
+library (see the *Extended Library* subsection below), are available when the
+**-l** or **--mathlib** command-line flags are given, except that the extended
+math library is not available when the **-s** option, the **-w** option, or
+equivalents are given.
+
+## Standard Library
+
+The [standard][1] defines the following functions for the math library:
+
+**s(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**c(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l(x)**
+
+: Returns the natural logarithm of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**e(x)**
+
+: Returns the mathematical constant **e** raised to the power of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**j(x, n)**
+
+: Returns the bessel integer order **n** (truncated) of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+## Extended Library
+
+The extended library is *not* loaded when the **-s**/**--standard** or
+**-w**/**--warn** options are given since they are not part of the library
+defined by the [standard][1].
+
+The extended library is a **non-portable extension**.
+
+**p(x, y)**
+
+: Calculates **x** to the power of **y**, even if **y** is not an integer, and
+ returns the result to the current **scale**.
+
+ It is an error if **y** is negative and **x** is **0**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**r(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round half away from **0**][3].
+
+**ceil(x, p)**
+
+: Returns **x** rounded to **p** decimal places according to the rounding mode
+ [round away from **0**][6].
+
+**f(x)**
+
+: Returns the factorial of the truncated absolute value of **x**.
+
+**perm(n, k)**
+
+: Returns the permutation of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**comb(n, k)**
+
+: Returns the combination of the truncated absolute value of **n** of the
+ truncated absolute value of **k**, if **k \<= n**. If not, it returns **0**.
+
+**l2(x)**
+
+: Returns the logarithm base **2** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**l10(x)**
+
+: Returns the logarithm base **10** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**log(x, b)**
+
+: Returns the logarithm base **b** of **x**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cbrt(x)**
+
+: Returns the cube root of **x**.
+
+**root(x, n)**
+
+: Calculates the truncated value of **n**, **r**, and returns the **r**th root
+ of **x** to the current **scale**.
+
+ 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.
+
+**pi(p)**
+
+: Returns **pi** to **p** decimal places.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**t(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**a2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ This function is the same as the **atan2()** function in many programming
+ languages.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**sin(x)**
+
+: Returns the sine of **x**, which is assumed to be in radians.
+
+ This is an alias of **s(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**cos(x)**
+
+: Returns the cosine of **x**, which is assumed to be in radians.
+
+ This is an alias of **c(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**tan(x)**
+
+: Returns the tangent of **x**, which is assumed to be in radians.
+
+ 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).
+
+**atan(x)**
+
+: Returns the arctangent of **x**, in radians.
+
+ This is an alias of **a(x)**.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**atan2(y, x)**
+
+: Returns the arctangent of **y/x**, in radians. If both **y** and **x** are
+ equal to **0**, it raises an error and causes bc(1) to reset (see the
+ **RESET** section). Otherwise, if **x** is greater than **0**, it returns
+ **a(y/x)**. If **x** is less than **0**, and **y** is greater than or equal
+ to **0**, it returns **a(y/x)+pi**. If **x** is less than **0**, and **y**
+ is less than **0**, it returns **a(y/x)-pi**. If **x** is equal to **0**,
+ and **y** is greater than **0**, it returns **pi/2**. If **x** is equal to
+ **0**, and **y** is less than **0**, it returns **-pi/2**.
+
+ 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).
+
+**r2d(x)**
+
+: Converts **x** from radians to degrees and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**d2r(x)**
+
+: Converts **x** from degrees to radians and returns the result.
+
+ This is a transcendental function (see the *Transcendental Functions*
+ subsection below).
+
+**frand(p)**
+
+: Generates a pseudo-random number between **0** (inclusive) and **1**
+ (exclusive) with the number of decimal digits after the decimal point equal
+ to the truncated absolute value of **p**. If **p** is not **0**, then
+ calling this function will change the value of **seed**. If **p** is **0**,
+ then **0** is returned, and **seed** is *not* changed.
+
+**ifrand(i, p)**
+
+: Generates a pseudo-random number that is between **0** (inclusive) and the
+ truncated absolute value of **i** (exclusive) with the number of decimal
+ digits after the decimal point equal to the truncated absolute value of
+ **p**. If the absolute value of **i** is greater than or equal to **2**, and
+ **p** is not **0**, then calling this function will change the value of
+ **seed**; otherwise, **0** is returned and **seed** is not changed.
+
+**srand(x)**
+
+: Returns **x** with its sign flipped with probability **0.5**. In other
+ words, it randomizes the sign of **x**.
+
+**brand()**
+
+: Returns a random boolean value (either **0** or **1**).
+
+**ubytes(x)**
+
+: Returns the numbers of unsigned integer bytes required to hold the truncated
+ absolute value of **x**.
+
+**sbytes(x)**
+
+: Returns the numbers of signed, two's-complement integer bytes required to
+ hold the truncated value of **x**.
+
+**hex(x)**
+
+: Outputs the hexadecimal (base **16**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary(x)**
+
+: Outputs the binary (base **2**) representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output(x, b)**
+
+: Outputs the base **b** representation of **x**.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**uint(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in as few power of two bytes as possible. Both outputs are
+ split into bytes separated by spaces.
+
+ 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).
+
+**int(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in as few power of two bytes as possible. Both
+ outputs are split into bytes separated by spaces.
+
+ 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).
+
+**uintn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **n** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**intn(x, n)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **n** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **1** byte. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int8(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **1** byte. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **2** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int16(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **2** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **4** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int32(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **4** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**uint64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as an
+ unsigned integer in **8** bytes. Both outputs are split into bytes separated
+ by spaces.
+
+ 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).
+
+**int64(x)**
+
+: Outputs the representation, in binary and hexadecimal, of **x** as a signed,
+ two's-complement integer in **8** bytes. Both outputs are split into bytes
+ separated by spaces.
+
+ 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).
+
+**hex_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in hexadecimal using **n** bytes. Not all of the value will
+ be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**binary_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in binary using **n** bytes. Not all of the value will be
+ output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_uint(x, n)**
+
+: Outputs the representation of the truncated absolute value of **x** as an
+ unsigned integer in the current **obase** (see the **SYNTAX** section) using
+ **n** bytes. Not all of the value will be output if **n** is too small.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+**output_byte(x, i)**
+
+: Outputs byte **i** of the truncated absolute value of **x**, where **0** is
+ the least significant byte and **number_of_bytes - 1** is the most
+ significant byte.
+
+ This is a **void** function (see the *Void Functions* subsection of the
+ **FUNCTIONS** section).
+
+## Transcendental Functions
+
+All transcendental functions can return slightly inaccurate results (up to 1
+[ULP][4]). This is unavoidable, and [this article][5] explains why it is
+impossible and unnecessary to calculate exact results for the transcendental
+functions.
+
+Because of the possible inaccuracy, I recommend that users call those functions
+with the precision (**scale**) set to at least 1 higher than is necessary. If
+exact results are *absolutely* required, users can double the precision
+(**scale**) and then truncate.
+
+The transcendental functions in the standard math library are:
+
+* **s(x)**
+* **c(x)**
+* **a(x)**
+* **l(x)**
+* **e(x)**
+* **j(x, n)**
+
+The transcendental functions in the extended math library are:
+
+* **l2(x)**
+* **l10(x)**
+* **log(x, b)**
+* **pi(p)**
+* **t(x)**
+* **a2(y, x)**
+* **sin(x)**
+* **cos(x)**
+* **tan(x)**
+* **atan(x)**
+* **atan2(y, x)**
+* **r2d(x)**
+* **d2r(x)**
+
+# RESET
+
+When bc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any functions that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+functions returned) is skipped.
+
+Thus, when bc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+Note that this reset behavior is different from the GNU bc(1), which attempts to
+start executing the statement right after the one that caused an error.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This bc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with
+the **limits** statement.
+
+In addition, this bc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bc(1):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_STRING_MAX**
+
+: The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **rand()** operand. Set at
+ **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+The actual values can be queried with the **limits** statement.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+bc(1) recognizes the following environment variables:
+
+**POSIXLY_CORRECT**
+
+: If this variable exists (no matter the contents), bc(1) behaves as if
+ the **-s** option was given.
+
+**BC_ENV_ARGS**
+
+: 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 **BC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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.
+
+ The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"bc\" file.bc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**BC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output
+ lines to that length, including the backslash (**\\**). The default line
+ length is **70**.
+
+# EXIT STATUS
+
+bc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**\<\<**), and right shift (**\>\>**)
+ operators and their corresponding assignment operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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 **void** function call as a value in an expression.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, bc(1) always exits
+and returns **4**, no matter what mode bc(1) is in.
+
+The other statuses will only be returned when bc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since bc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow bc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Per the [standard][1], bc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, bc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, bc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to stop execution of the current input. If
+bc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If bc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to bc(1) as it is executing a file, it
+can seem as though bc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with bc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause bc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when bc(1) is in TTY mode, a **SIGHUP** will cause bc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing. If bc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This bc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGES**.
+
+# SEE ALSO
+
+dc(1)
+
+# STANDARDS
+
+bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1]
+specification. The flags **-efghiqsvVw**, all long options, and the extensions
+noted above are extensions to that specification.
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**.
+
+This bc(1) supports error messages for different locales, and thus, it supports
+**LC_MESSAGES**.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero
+[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place
+[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT
+[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero
diff --git a/contrib/bc/manuals/bcl.3 b/contrib/bc/manuals/bcl.3
new file mode 100644
index 000000000000..cb56f9dd8491
--- /dev/null
+++ b/contrib/bc/manuals/bcl.3
@@ -0,0 +1,1365 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "BCL" "3" "October 2020" "Gavin D. Howard" "Libraries Manual"
+.SH NAME
+.PP
+bcl - library of arbitrary precision decimal arithmetic
+.SH SYNOPSIS
+.SS Use
+.PP
+\f[I]#include <bcl.h>\f[R]
+.PP
+Link with \f[I]-lbcl\f[R].
+.SS Signals
+.PP
+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]
+.PP
+\f[B]bool bcl_running(\f[R]\f[I]void\f[R]\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]
+.PP
+\f[B]void bcl_free(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]bool bcl_abortOnFatalError(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_setAbortOnFatalError(bool\f[R] \f[I]abrt\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_gc(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.SS Contexts
+.PP
+These items will allow clients to handle contexts, which are isolated
+from each other.
+This allows more than one client to use bcl(3) in the same program.
+.PP
+\f[B]struct BclCtxt;\f[R]
+.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]
+.PP
+\f[B]void bcl_ctxt_free(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R]
+.PP
+\f[B]BclError bcl_pushContext(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_popContext(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]BclContext bcl_context(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_ctxt_freeNums(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R]
+.PP
+\f[B]size_t bcl_ctxt_scale(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\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]
+.PP
+\f[B]size_t bcl_ctxt_ibase(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\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]
+.PP
+\f[B]size_t bcl_ctxt_obase(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\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]
+.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]
+.SS Numbers
+.PP
+These items allow clients to manipulate and query the
+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]
+.PP
+\f[B]void bcl_num_free(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R]
+.PP
+\f[B]bool bcl_num_neg(BclNumber\f[R] \f[I]n\f[R]\f[B]);\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]
+.PP
+\f[B]size_t bcl_num_scale(BclNumber\f[R] \f[I]n\f[R]\f[B]);\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]
+.PP
+\f[B]size_t bcl_num_len(BclNumber\f[R] \f[I]n\f[R]\f[B]);\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]
+.PP
+\f[B]char* bcl_string(BclNumber\f[R] \f[I]n\f[R]\f[B]);\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]
+.PP
+\f[B]BclNumber bcl_bigdig2num(BclBigDig\f[R] \f[I]val\f[R]\f[B]);\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]
+.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]
+.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]
+.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]
+.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]
+.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]
+.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]
+.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]
+.PP
+\f[B]BclNumber bcl_sqrt(BclNumber\f[R] \f[I]a\f[R]\f[B]);\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]
+.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]
+.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]
+.PP
+\f[B]void bcl_one(BclNumber\f[R] \f[I]n\f[R]\f[B]);\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]
+.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]
+.PP
+\f[B]BclNumber bcl_dup(BclNumber\f[R] \f[I]s\f[R]\f[B]);\f[R]
+.SS Pseudo-Random Number Generator
+.PP
+These items allow clients to manipulate the seeded pseudo-random number
+generator in bcl(3).
+.PP
+\f[B]#define BCL_SEED_ULONGS\f[R]
+.PP
+\f[B]#define BCL_SEED_SIZE\f[R]
+.PP
+\f[B]typedef unsigned long BclBigDig;\f[R]
+.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]
+.PP
+\f[B]BclNumber bcl_frand(size_t\f[R] \f[I]places\f[R]\f[B]);\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]
+.PP
+\f[B]BclError bcl_rand_seedWithNum(BclNumber\f[R]
+\f[I]n\f[R]\f[B]);\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]
+.PP
+\f[B]void bcl_rand_reseed(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]BclNumber bcl_rand_seed2num(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]BclRandInt bcl_rand_int(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]BclRandInt bcl_rand_bounded(BclRandInt\f[R]
+\f[I]bound\f[R]\f[B]);\f[R]
+.SH DESCRIPTION
+.PP
+bcl(3) is a library that implements arbitrary-precision decimal math, as
+standardized by
+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.
+(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.
+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]
+return to its caller.
+.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.
+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].
+Otherwise, it returns \f[B]false\f[R].
+.RS
+.PP
+See the \f[B]SIGNAL HANDLING\f[R] section.
+.RE
+.SS Setup
+.TP
+\f[B]BclError bcl_init(\f[R]\f[I]void\f[R]\f[B])\f[R]
+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].
+This is to make it possible for multiple libraries and applications to
+initialize bcl(3) without problem.
+.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_FATAL_ALLOC_ERR\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
+with it if the reference count is \f[B]0\f[R].
+.RS
+.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
+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
+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.
+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
+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.
+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
+\f[B]struct BclCtxt\f[R]
+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
+\f[B]BclContext\f[R]
+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
+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].
+.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].
+.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.
+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.
+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.
+\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
+.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]
+.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].
+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]
+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
+\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
+\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
+\f[I]obase\f[R].
+.SS Errors
+.TP
+\f[B]BclError\f[R]
+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].
+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
+There must be a valid current context.
+.RE
+.SS Numbers
+.PP
+All procedures in this section require a valid current context.
+.TP
+\f[B]BclNumber\f[R]
+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].
+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].
+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
+.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[I]n\f[R].
+.SS Conversion
+.PP
+All procedures in this section require a valid current context.
+.PP
+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
+\f[B]ibase\f[R] and returns the resulting number.
+.RS
+.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.
+.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].
+The string is dynamically allocated and must be freed by the caller.
+.RS
+.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
+in the space pointed to by \f[I]result\f[R].
+.RS
+.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
+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
+.SS Math
+.PP
+All procedures in this section require a valid current context.
+.PP
+All procedures in this section can return the following errors:
+.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]
+.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.
+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
+.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_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.
+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
+.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_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.
+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
+.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_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.
+The \f[I]scale\f[R] of the result is the \f[I]scale\f[R] of the current
+context.
+.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_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
+\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
+.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].
+.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
+and returns the result.
+This is done in decimal.
+\f[I]b\f[R] must be an integer.
+.RS
+.PP
+\f[I]b\f[R] must be an integer.
+.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
+and returns the result.
+This is done in decimal.
+\f[I]b\f[R] must be an integer.
+.RS
+.PP
+\f[I]b\f[R] must be an integer.
+.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.
+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] cannot be 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
+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
+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
+.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]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,
+\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
+.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
+\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[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
+.SS Pseudo-Random Number Generator
+.PP
+The pseudo-random number generator in bcl(3) is a \f[I]seeded\f[R] PRNG.
+Given the same seed twice, it will produce the same sequence of
+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
+\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.
+.PP
+This should provide fairly good seeding in the standard case while also
+remaining fairly portable.
+.PP
+If necessary, the PRNG can be reseeded with one of the following
+functions:
+.IP \[bu] 2
+\f[B]bcl_rand_seedWithNum(BclNumber)\f[R]
+.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]
+.PP
+The following items allow clients to use the pseudo-random number
+generator.
+All procedures require a valid current context.
+.TP
+\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
+random number generator.
+.TP
+\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
+number generator.
+.TP
+\f[B]BclBigDig\f[R]
+bcl(3)\[cq]s overflow type (see the \f[B]PERFORMANCE\f[R] section).
+.TP
+\f[B]BclRandInt\f[R]
+An unsigned integer type returned by bcl(3)\[cq]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
+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].
+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
+This procedure requires a valid current context.
+.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).
+There are no limits on \f[I]places\f[R].
+.RS
+.PP
+This procedure requires a valid current context.
+.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]
+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
+This procedure requires a valid current context.
+.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.
+.PP
+This procedure requires a valid current context.
+.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]
+.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
+.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.
+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
+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
+.PP
+This procedure requires a valid current context.
+.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]
+(inclusive).
+.RS
+.PP
+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]
+(exclusive).
+Bias is removed before returning the integer.
+.RS
+.PP
+This procedure cannot fail.
+.RE
+.SS Consumption and Propagation
+.PP
+Some functions are listed as consuming some or all of their arguments.
+This means that the arguments are freed, regardless of if there were
+errors or not.
+.PP
+This is to enable compact code like the following:
+.IP
+.nf
+\f[C]
+BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
+\f[R]
+.fi
+.PP
+If arguments to those functions were not consumed, memory would be
+leaked until reclaimed with \f[B]bcl_ctxt_freeNums(BclContext)\f[R].
+.PP
+When errors occur, they are propagated through.
+The result should always be checked with \f[B]bcl_err(BclNumber)\f[R],
+so the example above should properly be:
+.IP
+.nf
+\f[C]
+BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
+if (bc_num_err(n) != BCL_ERROR_NONE) {
+ // Handle the error.
+}
+\f[R]
+.fi
+.SH ERRORS
+.PP
+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
+\f[B]BCL_ERROR_NONE\f[R]
+Success; no error occurred.
+.TP
+\f[B]BCL_ERROR_INVALID_NUM\f[R]
+An invalid \f[B]BclNumber\f[R] was given as a parameter.
+.TP
+\f[B]BCL_ERROR_INVALID_CONTEXT\f[R]
+An invalid \f[B]BclContext\f[R] is being used.
+.TP
+\f[B]BCL_ERROR_SIGNAL\f[R]
+A signal interrupted execution.
+.TP
+\f[B]BCL_ERROR_MATH_NEGATIVE\f[R]
+A negative number was given as an argument to a parameter that cannot
+accept negative numbers, such as for square roots.
+.TP
+\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
+\f[B]bcl_num_pow()\f[R].
+.TP
+\f[B]BCL_ERROR_MATH_OVERFLOW\f[R]
+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
+\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R]
+A divide by zero occurred.
+.TP
+\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
+exponent.
+.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.
+By default, this behavior is off.
+.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.
+By default, this behavior is off.
+.PP
+It is highly recommended that client libraries do \f[I]not\f[R] activate
+this behavior.
+.RE
+.SH ATTRIBUTES
+.PP
+When \f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\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
+more than one thread.
+.SH PERFORMANCE
+.PP
+Most bc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+bcl(3) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]BC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]BC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]BC_BASE_DIGS\f[R].
+.PP
+In addition, this bcl(3) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]BC_LONG_BIT\f[R], but is
+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
+\f[B]BC_LONG_BIT\f[R]
+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
+\f[B]BC_BASE_DIGS\f[R]
+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
+\f[B]BC_BASE_POW\f[R]
+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
+\f[B]BC_OVERFLOW_MAX\f[R]
+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
+\f[B]BC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]BC_BASE_POW\f[R].
+.TP
+\f[B]BC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]BC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]BC_NUM_MAX\f[R]
+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
+\f[B]BC_RAND_MAX\f[R]
+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
+Exponent
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+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
+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
+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.
+.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
+thread that is not executing bcl(3) functions, if bcl(3) functions are
+executing.
+.SH SEE ALSO
+.PP
+bc(1) and dc(1)
+.SH STANDARDS
+.PP
+bcl(3) is compliant with the arithmetic defined in the IEEE Std
+1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification for bc(1).
+.PP
+Note that the specification explicitly says that bc(1) only accepts
+numbers that use a period (\f[B].\f[R]) as a radix point, regardless of
+the value of \f[B]LC_NUMERIC\f[R].
+This is also true of bcl(3).
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHORS
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/bcl.3.md b/contrib/bc/manuals/bcl.3.md
new file mode 100644
index 000000000000..93c98923f083
--- /dev/null
+++ b/contrib/bc/manuals/bcl.3.md
@@ -0,0 +1,1177 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# NAME
+
+bcl - library of arbitrary precision decimal arithmetic
+
+# SYNOPSIS
+
+## Use
+
+*#include <bcl.h>*
+
+Link with *-lbcl*.
+
+## Signals
+
+This procedure will allow clients to use signals to interrupt computations
+running in bcl(3).
+
+**void bcl_handleSignal(***void***);**
+
+**bool bcl_running(***void***);**
+
+## Setup
+
+These items allow clients to set up bcl(3).
+
+**BclError bcl_init(***void***);**
+
+**void bcl_free(***void***);**
+
+**bool bcl_abortOnFatalError(***void***);**
+
+**void bcl_setAbortOnFatalError(bool** *abrt***);**
+
+**void bcl_gc(***void***);**
+
+## Contexts
+
+These items will allow clients to handle contexts, which are isolated from each
+other. This allows more than one client to use bcl(3) in the same program.
+
+**struct BclCtxt;**
+
+**typedef struct BclCtxt\* BclContext;**
+
+**BclContext bcl_ctxt_create(***void***);**
+
+**void bcl_ctxt_free(BclContext** *ctxt***);**
+
+**BclError bcl_pushContext(BclContext** *ctxt***);**
+
+**void bcl_popContext(***void***);**
+
+**BclContext bcl_context(***void***);**
+
+**void bcl_ctxt_freeNums(BclContext** *ctxt***);**
+
+**size_t bcl_ctxt_scale(BclContext** *ctxt***);**
+
+**void bcl_ctxt_setScale(BclContext** *ctxt***, size_t** *scale***);**
+
+**size_t bcl_ctxt_ibase(BclContext** *ctxt***);**
+
+**void bcl_ctxt_setIbase(BclContext** *ctxt***, size_t** *ibase***);**
+
+**size_t bcl_ctxt_obase(BclContext** *ctxt***);**
+
+**void bcl_ctxt_setObase(BclContext** *ctxt***, size_t** *obase***);**
+
+## Errors
+
+These items allow clients to handle errors.
+
+**typedef enum BclError BclError;**
+
+**BclError bcl_err(BclNumber** *n***);**
+
+## Numbers
+
+These items allow clients to manipulate and query the arbitrary-precision
+numbers managed by bcl(3).
+
+**typedef struct { size_t i; } BclNumber;**
+
+**BclNumber bcl_num_create(***void***);**
+
+**void bcl_num_free(BclNumber** *n***);**
+
+**bool bcl_num_neg(BclNumber** *n***);**
+
+**void bcl_num_setNeg(BclNumber** *n***, bool** *neg***);**
+
+**size_t bcl_num_scale(BclNumber** *n***);**
+
+**BclError bcl_num_setScale(BclNumber** *n***, size_t** *scale***);**
+
+**size_t bcl_num_len(BclNumber** *n***);**
+
+## Conversion
+
+These items allow clients to convert numbers into and from strings and integers.
+
+**BclNumber bcl_parse(const char \*restrict** *val***);**
+
+**char\* bcl_string(BclNumber** *n***);**
+
+**BclError bcl_bigdig(BclNumber** *n***, BclBigDig \****result***);**
+
+**BclNumber bcl_bigdig2num(BclBigDig** *val***);**
+
+## Math
+
+These items allow clients to run math on numbers.
+
+**BclNumber bcl_add(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_sub(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_mul(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_div(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_mod(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_pow(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_lshift(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_rshift(BclNumber** *a***, BclNumber** *b***);**
+
+**BclNumber bcl_sqrt(BclNumber** *a***);**
+
+**BclError bcl_divmod(BclNumber** *a***, BclNumber** *b***, BclNumber \****c***, BclNumber \****d***);**
+
+**BclNumber bcl_modexp(BclNumber** *a***, BclNumber** *b***, BclNumber** *c***);**
+
+## Miscellaneous
+
+These items are miscellaneous.
+
+**void bcl_zero(BclNumber** *n***);**
+
+**void bcl_one(BclNumber** *n***);**
+
+**ssize_t bcl_cmp(BclNumber** *a***, BclNumber** *b***);**
+
+**BclError bcl_copy(BclNumber** *d***, BclNumber** *s***);**
+
+**BclNumber bcl_dup(BclNumber** *s***);**
+
+## Pseudo-Random Number Generator
+
+These items allow clients to manipulate the seeded pseudo-random number
+generator in bcl(3).
+
+**#define BCL_SEED_ULONGS**
+
+**#define BCL_SEED_SIZE**
+
+**typedef unsigned long BclBigDig;**
+
+**typedef unsigned long BclRandInt;**
+
+**BclNumber bcl_irand(BclNumber** *a***);**
+
+**BclNumber bcl_frand(size_t** *places***);**
+
+**BclNumber bcl_ifrand(BclNumber** *a***, size_t** *places***);**
+
+**BclError bcl_rand_seedWithNum(BclNumber** *n***);**
+
+**BclError bcl_rand_seed(unsigned char** *seed***[***BC_SEED_SIZE***]);**
+
+**void bcl_rand_reseed(***void***);**
+
+**BclNumber bcl_rand_seed2num(***void***);**
+
+**BclRandInt bcl_rand_int(***void***);**
+
+**BclRandInt bcl_rand_bounded(BclRandInt** *bound***);**
+
+# DESCRIPTION
+
+bcl(3) is a library that implements arbitrary-precision decimal math, as
+[standardized by POSIX][1] in bc(1).
+
+bcl(3) is async-signal-safe if **bcl_handleSignal(***void***)** is used
+properly. (See the **SIGNAL HANDLING** section.)
+
+All of the items in its interface are described below. See the documentation for
+each function for what each function can return.
+
+## Signals
+
+**void bcl_handleSignal(***void***)**
+
+: 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
+ *not* executing any bcl(3) functions while any bcl(3) functions are
+ executing.
+
+ If execution *is* interrupted, **bcl_handleSignal(***void***)** does *not*
+ return to its caller.
+
+ See the **SIGNAL HANDLING** section.
+
+**bool bcl_running(***void***)**
+
+: An async-signal-safe function that can be called from a signal handler. It
+ will return **true** if any bcl(3) procedures are running, which means it is
+ safe to call **bcl_handleSignal(***void***)**. Otherwise, it returns
+ **false**.
+
+ See the **SIGNAL HANDLING** section.
+
+## Setup
+
+**BclError bcl_init(***void***)**
+
+: Initializes this library. This function can be called multiple times, but
+ each call must be matched by a call to **bcl_free(***void***)**. This is to
+ make it possible for multiple libraries and applications to initialize
+ bcl(3) without problem.
+
+ 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.
+
+**void bcl_free(***void***)**
+
+: Decrements bcl(3)'s reference count and frees the data associated with it if
+ the reference count is **0**.
+
+ This function must be the last one clients call. Calling this function
+ before calling any other function is undefined behavior.
+
+**bool bcl_abortOnFatalError(***void***)**
+
+: Queries and returns the current state of calling **abort()** on fatal
+ errors. If **true** is returned, bcl(3) will cause a **SIGABRT** if a fatal
+ error occurs.
+
+ If activated, clients do not need to check for fatal errors.
+
+**void bcl_setAbortOnFatalError(bool** *abrt***)**
+
+: Sets the state of calling **abort()** on fatal errors. If *abrt* is
+ **false**, bcl(3) will not cause a **SIGABRT** on fatal errors after the
+ call. If *abrt* is **true**, bcl(3) will cause a **SIGABRT** on fatal errors
+ after the call.
+
+ If activated, clients do not need to check for fatal errors.
+
+**void bcl_gc(***void***)**
+
+: Garbage collects cached instances of arbitrary-precision numbers. This only
+ frees the memory of numbers that are *not* in use, so it is safe to call at
+ any time.
+
+## Contexts
+
+All procedures that take a **BclContext** parameter a require a valid context as
+an argument.
+
+**struct BclCtxt**
+
+: A forward declaration for a hidden **struct** type. Clients cannot access
+ the internals of the **struct** type directly. All interactions with the
+ type are done through pointers. See **BclContext** below.
+
+**BclContext**
+
+: A typedef to a pointer of **struct BclCtxt**. This is the only handle
+ clients can get to **struct BclCtxt**.
+
+ 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 **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.
+
+**BclContext bcl_ctxt_create(***void***)**
+
+: Creates a context and returns it. Returns **NULL** if there was an error.
+
+**void bcl_ctxt_free(BclContext** *ctxt***)**
+
+: Frees *ctxt*, after which it is no longer valid. It is undefined behavior to
+ attempt to use an invalid context.
+
+**BclError bcl_pushContext(BclContext** *ctxt***)**
+
+: Pushes *ctxt* onto bcl(3)'s stack of contexts. *ctxt* must have been created
+ with **bcl_ctxt_create(***void***)**.
+
+ 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.
+
+**void bcl_popContext(***void***)**
+
+: Pops the current context off of the stack, if one exists.
+
+**BclContext bcl_context(***void***)**
+
+: Returns the current context, or **NULL** if no context exists.
+
+**void bcl_ctxt_freeNums(BclContext** *ctxt***)**
+
+: Frees all numbers in use that are associated with *ctxt*. It is undefined
+ behavior to attempt to use a number associated with *ctxt* after calling
+ this procedure unless such numbers have been created with
+ **bcl_num_create(***void***)** after calling this procedure.
+
+**size_t bcl_ctxt_scale(BclContext** *ctxt***)**
+
+: Returns the **scale** for given context.
+
+**void bcl_ctxt_setScale(BclContext** *ctxt***, size_t** *scale***)**
+
+: Sets the **scale** for the given context to the argument *scale*.
+
+**size_t bcl_ctxt_ibase(BclContext** *ctxt***)**
+
+: Returns the **ibase** for the given context.
+
+**void bcl_ctxt_setIbase(BclContext** *ctxt***, size_t** *ibase***)**
+
+: Sets the **ibase** for the given context to the argument *ibase*. If the
+ argument *ibase* is invalid, it clamped, so an *ibase* of **0** or **1** is
+ clamped to **2**, and any values above **36** are clamped to **36**.
+
+**size_t bcl_ctxt_obase(BclContext** *ctxt***)**
+
+: Returns the **obase** for the given context.
+
+**void bcl_ctxt_setObase(BclContext** *ctxt***, size_t** *obase***)**
+
+: Sets the **obase** for the given context to the argument *obase*.
+
+## Errors
+
+**BclError**
+
+: An **enum** of possible error codes. See the **ERRORS** section for a
+ complete listing the codes.
+
+**BclError bcl_err(BclNumber** *n***)**
+
+: Checks for errors in a **BclNumber**. All functions that can return a
+ **BclNumber** can encode an error in the number, and this function will
+ return the error, if any. If there was no error, it will return
+ **BCL_ERROR_NONE**.
+
+ There must be a valid current context.
+
+## Numbers
+
+All procedures in this section require a valid current context.
+
+**BclNumber**
+
+: A handle to an arbitrary-precision number. The actual number type is not
+ exposed; the **BclNumber** handle is the only way clients can refer to
+ instances of arbitrary-precision numbers.
+
+**BclNumber bcl_num_create(***void***)**
+
+: Creates and returns a **BclNumber**.
+
+ 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**
+
+**void bcl_num_free(BclNumber** *n***)**
+
+: Frees *n*. It is undefined behavior to use *n* after calling this function.
+
+**bool bcl_num_neg(BclNumber** *n***)**
+
+: Returns **true** if *n* is negative, **false** otherwise.
+
+**void bcl_num_setNeg(BclNumber** *n***, bool** *neg***)**
+
+: Sets *n*'s sign to *neg*, where **true** is negative, and **false** is
+ positive.
+
+**size_t bcl_num_scale(BclNumber** *n***)**
+
+: Returns the *scale* of *n*.
+
+ The *scale* of a number is the number of decimal places it has after the
+ radix (decimal point).
+
+**BclError bcl_num_setScale(BclNumber** *n***, size_t** *scale***)**
+
+: Sets the *scale* of *n* to the argument *scale*. If the argument *scale* is
+ greater than the *scale* of *n*, *n* is extended. If the argument *scale* is
+ less than the *scale* of *n*, *n* is truncated.
+
+ 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**
+
+**size_t bcl_num_len(BclNumber** *n***)**
+
+: Returns the number of *significant decimal digits* in *n*.
+
+## Conversion
+
+All procedures in this section require a valid current context.
+
+All procedures in this section consume the given **BclNumber** arguments that
+are not given to pointer arguments. See the **Consumption and Propagation**
+subsection below.
+
+**BclNumber bcl_parse(const char \*restrict** *val***)**
+
+: Parses a number string according to the current context's **ibase** and
+ returns the resulting number.
+
+ *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**
+
+**char\* bcl_string(BclNumber** *n***)**
+
+: Returns a string representation of *n* according the the current context's
+ **ibase**. The string is dynamically allocated and must be freed by the
+ caller.
+
+ *n* is consumed; it cannot be used after the call. See the
+ **Consumption and Propagation** subsection below.
+
+**BclError bcl_bigdig(BclNumber** *n***, BclBigDig \****result***)**
+
+: Converts *n* into a **BclBigDig** and returns the result in the space
+ pointed to by *result*.
+
+ *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.
+
+**BclNumber bcl_bigdig2num(BclBigDig** *val***)**
+
+: Creates a **BclNumber** from *val*.
+
+ 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**
+
+## Math
+
+All procedures in this section require a valid current context.
+
+All procedures in this section can return the following errors:
+
+* **BCL_ERROR_INVALID_NUM**
+* **BCL_ERROR_INVALID_CONTEXT**
+* **BCL_ERROR_FATAL_ALLOC_ERR**
+
+**BclNumber bcl_add(BclNumber** *a***, BclNumber** *b***)**
+
+: Adds *a* and *b* and returns the result. The *scale* of the result is the
+ max of the *scale*s of *a* and *b*.
+
+ *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**
+
+**BclNumber bcl_sub(BclNumber** *a***, BclNumber** *b***)**
+
+: Subtracts *b* from *a* and returns the result. The *scale* of the result is
+ the max of the *scale*s of *a* and *b*.
+
+ *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**
+
+**BclNumber bcl_mul(BclNumber** *a***, BclNumber** *b***)**
+
+: Multiplies *a* and *b* and returns the result. If *ascale* is the *scale* of
+ *a* and *bscale* is the *scale* of *b*, the *scale* of the result is equal
+ to **min(ascale+bscale,max(scale,ascale,bscale))**, where **min()** and
+ **max()** return the obvious values.
+
+ *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**
+
+**BclNumber bcl_div(BclNumber** *a***, BclNumber** *b***)**
+
+: Divides *a* by *b* and returns the result. The *scale* of the result is the
+ *scale* of the current context.
+
+ *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**
+
+**BclNumber bcl_mod(BclNumber** *a***, BclNumber** *b***)**
+
+: Divides *a* by *b* to the *scale* of the current context, computes the
+ modulus **a-(a/b)\*b**, and returns the modulus.
+
+ *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**
+
+**BclNumber bcl_pow(BclNumber** *a***, BclNumber** *b***)**
+
+: Calculates *a* to the power of *b* to the *scale* of the current context.
+ *b* must be an integer, but can be negative. If it is negative, *a* must
+ be non-zero.
+
+ *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**
+
+**BclNumber bcl_lshift(BclNumber** *a***, BclNumber** *b***)**
+
+: Shifts *a* left (moves the radix right) by *b* places and returns the
+ result. This is done in decimal. *b* must be an integer.
+
+ *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**
+
+**BclNumber bcl_rshift(BclNumber** *a***, BclNumber** *b***)**
+
+: Shifts *a* right (moves the radix left) by *b* places and returns the
+ result. This is done in decimal. *b* must be an integer.
+
+ *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**
+
+**BclNumber bcl_sqrt(BclNumber** *a***)**
+
+: Calculates the square root of *a* and returns the result. The *scale* of the
+ result is equal to the **scale** of the current context.
+
+ *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**
+
+**BclError bcl_divmod(BclNumber** *a***, BclNumber** *b***, BclNumber \****c***, BclNumber \****d***)**
+
+: Divides *a* by *b* and returns the quotient in a new number which is put
+ into the space pointed to by *c*, and puts the modulus in a new number which
+ is put into the space pointed to by *d*.
+
+ *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**
+
+**BclNumber bcl_modexp(BclNumber** *a***, BclNumber** *b***, BclNumber** *c***)**
+
+: Computes a modular exponentiation where *a* is the base, *b* is the
+ exponent, and *c* is the modulus, and returns the result. The *scale* of the
+ result is equal to the **scale** of the current context.
+
+ *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**
+
+## Miscellaneous
+
+**void bcl_zero(BclNumber** *n***)**
+
+: Sets *n* to **0**.
+
+**void bcl_one(BclNumber** *n***)**
+
+: Sets *n* to **1**.
+
+**ssize_t bcl_cmp(BclNumber** *a***, BclNumber** *b***)**
+
+: Compares *a* and *b* and returns **0** if *a* and *b* are equal, **<0** if
+ *a* is less than *b*, and **>0** if *a* is greater than *b*.
+
+**BclError bcl_copy(BclNumber** *d***, BclNumber** *s***)**
+
+: Copies *s* into *d*.
+
+ 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**
+
+**BclNumber bcl_dup(BclNumber** *s***)**
+
+: Creates and returns a new **BclNumber** that is a copy of *s*.
+
+ 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**
+
+## Pseudo-Random Number Generator
+
+The pseudo-random number generator in bcl(3) is a *seeded* PRNG. Given the same
+seed twice, it will produce the same sequence of pseudo-random numbers twice.
+
+By default, bcl(3) attempts to seed the PRNG with data from **/dev/urandom**. If
+that fails, it seeds itself with by calling **libc**'s **srand(time(NULL))** and
+then calling **rand()** for each byte, since **rand()** is only guaranteed to
+return **15** bits.
+
+This should provide fairly good seeding in the standard case while also
+remaining fairly portable.
+
+If necessary, the PRNG can be reseeded with one of the following functions:
+
+* **bcl_rand_seedWithNum(BclNumber)**
+* **bcl_rand_seed(unsigned char[BC_SEED_SIZE])**
+* **bcl_rand_reseed(***void***)**
+
+The following items allow clients to use the pseudo-random number generator. All
+procedures require a valid current context.
+
+**BCL_SEED_ULONGS**
+
+: The number of **unsigned long**'s in a seed for bcl(3)'s random number
+ generator.
+
+**BCL_SEED_SIZE**
+
+: The size, in **char**'s, of a seed for bcl(3)'s random number generator.
+
+**BclBigDig**
+
+: bcl(3)'s overflow type (see the **PERFORMANCE** section).
+
+**BclRandInt**
+
+: An unsigned integer type returned by bcl(3)'s random number generator.
+
+**BclNumber bcl_irand(BclNumber** *a***)**
+
+: Returns a random number that is not larger than *a* in a new number. If *a*
+ is **0** or **1**, the new number is equal to **0**. The bound is unlimited,
+ so it is not bound to the size of **BclRandInt**. This is done by generating
+ as many random numbers as necessary, multiplying them by certain exponents,
+ and adding them all together.
+
+ *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**
+
+**BclNumber bcl_frand(size_t** *places***)**
+
+: Returns a random number between **0** (inclusive) and **1** (exclusive) that
+ has *places* decimal digits after the radix (decimal point). There are no
+ limits on *places*.
+
+ 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**
+
+**BclNumber bcl_ifrand(BclNumber** *a***, size_t** *places***)**
+
+: Returns a random number less than *a* with *places* decimal digits after the
+ radix (decimal point). There are no limits on *a* or *places*.
+
+ *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**
+
+**BclError bcl_rand_seedWithNum(BclNumber** *n***)**
+
+: Seeds the PRNG with *n*.
+
+ *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*.
+
+**BclError bcl_rand_seed(unsigned char** *seed***[***BC_SEED_SIZE***])**
+
+: Seeds the PRNG with the bytes in *seed*.
+
+ If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this
+ function can return:
+
+ * **BCL_ERROR_INVALID_CONTEXT**
+
+**void bcl_rand_reseed(***void***)**
+
+: Reseeds the PRNG with the default reseeding behavior. First, it attempts to
+ read data from **/dev/urandom** and falls back to **libc**'s **rand()**.
+
+ This procedure cannot fail.
+
+**BclNumber bcl_rand_seed2num(***void***)**
+
+: Returns the current seed of the PRNG as a **BclNumber**.
+
+ 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**
+
+**BclRandInt bcl_rand_int(***void***)**
+
+: Returns a random integer between **0** and **BC_RAND_MAX** (inclusive).
+
+ This procedure cannot fail.
+
+**BclRandInt bcl_rand_bounded(BclRandInt** *bound***)**
+
+: Returns a random integer between **0** and *bound* (exclusive). Bias is
+ removed before returning the integer.
+
+ This procedure cannot fail.
+
+## Consumption and Propagation
+
+Some functions are listed as consuming some or all of their arguments. This
+means that the arguments are freed, regardless of if there were errors or not.
+
+This is to enable compact code like the following:
+
+ BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
+
+If arguments to those functions were not consumed, memory would be leaked until
+reclaimed with **bcl_ctxt_freeNums(BclContext)**.
+
+When errors occur, they are propagated through. The result should always be
+checked with **bcl_err(BclNumber)**, so the example above should properly
+be:
+
+ BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
+ if (bc_num_err(n) != BCL_ERROR_NONE) {
+ // Handle the error.
+ }
+
+# ERRORS
+
+Most functions in bcl(3) return, directly or indirectly, any one of the error
+codes defined in **BclError**. The complete list of codes is the following:
+
+**BCL_ERROR_NONE**
+
+: Success; no error occurred.
+
+**BCL_ERROR_INVALID_NUM**
+
+: An invalid **BclNumber** was given as a parameter.
+
+**BCL_ERROR_INVALID_CONTEXT**
+
+: An invalid **BclContext** is being used.
+
+**BCL_ERROR_SIGNAL**
+
+: A signal interrupted execution.
+
+**BCL_ERROR_MATH_NEGATIVE**
+
+: A negative number was given as an argument to a parameter that cannot accept
+ negative numbers, such as for square roots.
+
+**BCL_ERROR_MATH_NON_INTEGER**
+
+: A non-integer was given as an argument to a parameter that cannot accept
+ non-integer numbers, such as for the second parameter of **bcl_num_pow()**.
+
+**BCL_ERROR_MATH_OVERFLOW**
+
+: A number that would overflow its result was given as an argument, such as
+ for converting a **BclNumber** to a **BclBigDig**.
+
+**BCL_ERROR_MATH_DIVIDE_BY_ZERO**
+
+: A divide by zero occurred.
+
+**BCL_ERROR_PARSE_INVALID_STR**
+
+: An invalid number string was passed to a parsing function.
+
+ 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\^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**.
+
+**BCL_ERROR_FATAL_ALLOC_ERR**
+
+: bcl(3) failed to allocate memory.
+
+ 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.
+
+**BCL_ERROR_FATAL_UNKNOWN_ERR**
+
+: An unknown error occurred.
+
+ 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.
+
+# ATTRIBUTES
+
+When **bcl_handleSignal(***void***)** is used properly, bcl(3) is
+async-signal-safe.
+
+bcl(3) is *MT-Unsafe*: it is unsafe to call any functions from more than one
+thread.
+
+# PERFORMANCE
+
+Most bc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. bcl(3) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**BC_BASE_DIGS**.
+
+In addition, this bcl(3) uses an even larger integer for overflow checking. This
+integer type depends on the value of **BC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on bcl(3):
+
+**BC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**BC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **BC_LONG_BIT**.
+
+**BC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**.
+
+**BC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **BC_LONG_BIT**.
+
+**BC_BASE_MAX**
+
+: The maximum output base. Set at **BC_BASE_POW**.
+
+**BC_SCALE_MAX**
+
+: The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **BC_OVERFLOW_MAX-1**.
+
+**BC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **bcl_rand_int()** function.
+ Set at **2\^BC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **BC_OVERFLOW_MAX**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# SIGNAL HANDLING
+
+If a signal handler calls **bcl_handleSignal(***void***)** 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 return. If possible, the error code
+**BC_ERROR_SIGNAL** is returned.
+
+If execution *is* interrupted, **bcl_handleSignal(***void***)** does *not*
+return to its caller.
+
+It is undefined behavior if **bcl_handleSignal(***void***)** is called from
+a thread that is not executing bcl(3) functions, if bcl(3) functions are
+executing.
+
+# SEE ALSO
+
+bc(1) and dc(1)
+
+# STANDARDS
+
+bcl(3) is compliant with the arithmetic defined in the
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification for bc(1).
+
+Note that the specification explicitly says that bc(1) only accepts numbers that
+use a period (**.**) as a radix point, regardless of the value of
+**LC_NUMERIC**. This is also true of bcl(3).
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHORS
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/benchmarks.md b/contrib/bc/manuals/benchmarks.md
new file mode 100644
index 000000000000..af0593f4e876
--- /dev/null
+++ b/contrib/bc/manuals/benchmarks.md
@@ -0,0 +1,673 @@
+# Benchmarks
+
+The results of these benchmarks suggest that building this `bc` with
+optimization at `-O3` with link-time optimization (`-flto`) will result in the
+best performance. However, using `-march=native` can result in **WORSE**
+performance.
+
+*Note*: all benchmarks were run four times, and the fastest run is the one
+shown. Also, `[bc]` means whichever `bc` was being run, and the assumed working
+directory is the root directory of this repository. Also, this `bc` was at
+version `3.0.0` while GNU `bc` was at version `1.07.1`, and all tests were
+conducted on an `x86_64` machine running Gentoo Linux with `clang` `9.0.1` as
+the compiler.
+
+## Typical Optimization Level
+
+These benchmarks were run with both `bc`'s compiled with the typical `-O2`
+optimizations and no link-time optimization.
+
+### Addition
+
+The command used was:
+
+```
+tests/script.sh bc add.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 2.54
+user 1.21
+sys 1.32
+```
+
+For this `bc`:
+
+```
+real 0.88
+user 0.85
+sys 0.02
+```
+
+### Subtraction
+
+The command used was:
+
+```
+tests/script.sh bc subtract.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 2.51
+user 1.05
+sys 1.45
+```
+
+For this `bc`:
+
+```
+real 0.91
+user 0.85
+sys 0.05
+```
+
+### Multiplication
+
+The command used was:
+
+```
+tests/script.sh bc multiply.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 7.15
+user 4.69
+sys 2.46
+```
+
+For this `bc`:
+
+```
+real 2.20
+user 2.10
+sys 0.09
+```
+
+### Division
+
+The command used was:
+
+```
+tests/script.sh bc divide.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 3.36
+user 1.87
+sys 1.48
+```
+
+For this `bc`:
+
+```
+real 1.61
+user 1.57
+sys 0.03
+```
+
+### Power
+
+The command used was:
+
+```
+printf '1234567890^100000; halt\n' | time -p [bc] -q > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 11.30
+user 11.30
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 0.73
+user 0.72
+sys 0.00
+```
+
+### Scripts
+
+[This file][1] was downloaded, saved at `../timeconst.bc` and the following
+patch was applied:
+
+```
+--- ../timeconst.bc 2018-09-28 11:32:22.808669000 -0600
++++ ../timeconst.bc 2019-06-07 07:26:36.359913078 -0600
+@@ -110,8 +110,10 @@
+
+ print "#endif /* KERNEL_TIMECONST_H */\n"
+ }
+- halt
+ }
+
+-hz = read();
+-timeconst(hz)
++for (i = 0; i <= 50000; ++i) {
++ timeconst(i)
++}
++
++halt
+```
+
+The command used was:
+
+```
+time -p [bc] ../timeconst.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 16.71
+user 16.06
+sys 0.65
+```
+
+For this `bc`:
+
+```
+real 13.16
+user 13.15
+sys 0.00
+```
+
+Because this `bc` is faster when doing math, it might be a better comparison to
+run a script that is not running any math. As such, I put the following into
+`../test.bc`:
+
+```
+for (i = 0; i < 100000000; ++i) {
+ y = i
+}
+
+i
+y
+
+halt
+```
+
+The command used was:
+
+```
+time -p [bc] ../test.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 16.60
+user 16.59
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 22.76
+user 22.75
+sys 0.00
+```
+
+I also put the following into `../test2.bc`:
+
+```
+i = 0
+
+while (i < 100000000) {
+ i += 1
+}
+
+i
+
+halt
+```
+
+The command used was:
+
+```
+time -p [bc] ../test2.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 17.32
+user 17.30
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 16.98
+user 16.96
+sys 0.01
+```
+
+It seems that the improvements to the interpreter helped a lot in certain cases.
+
+Also, I have no idea why GNU `bc` did worse when it is technically doing less
+work.
+
+## Recommended Optimizations from `2.7.0`
+
+Note that, when running the benchmarks, the optimizations used are not the ones
+I recommended for version `2.7.0`, which are `-O3 -flto -march=native`.
+
+This `bc` separates its code into modules that, when optimized at link time,
+removes a lot of the inefficiency that comes from function overhead. This is
+most keenly felt with one function: `bc_vec_item()`, which should turn into just
+one instruction (on `x86_64`) when optimized at link time and inlined. There are
+other functions that matter as well.
+
+I also recommended `-march=native` on the grounds that newer instructions would
+increase performance on math-heavy code. We will see if that assumption was
+correct. (Spoiler: **NO**.)
+
+When compiling both `bc`'s with the optimizations I recommended for this `bc`
+for version `2.7.0`, the results are as follows.
+
+### Addition
+
+The command used was:
+
+```
+tests/script.sh bc add.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 2.44
+user 1.11
+sys 1.32
+```
+
+For this `bc`:
+
+```
+real 0.59
+user 0.54
+sys 0.05
+```
+
+### Subtraction
+
+The command used was:
+
+```
+tests/script.sh bc subtract.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 2.42
+user 1.02
+sys 1.40
+```
+
+For this `bc`:
+
+```
+real 0.64
+user 0.57
+sys 0.06
+```
+
+### Multiplication
+
+The command used was:
+
+```
+tests/script.sh bc multiply.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 7.01
+user 4.50
+sys 2.50
+```
+
+For this `bc`:
+
+```
+real 1.59
+user 1.53
+sys 0.05
+```
+
+### Division
+
+The command used was:
+
+```
+tests/script.sh bc divide.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 3.26
+user 1.82
+sys 1.44
+```
+
+For this `bc`:
+
+```
+real 1.24
+user 1.20
+sys 0.03
+```
+
+### Power
+
+The command used was:
+
+```
+printf '1234567890^100000; halt\n' | time -p [bc] -q > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 11.08
+user 11.07
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 0.71
+user 0.70
+sys 0.00
+```
+
+### Scripts
+
+The command for the `../timeconst.bc` script was:
+
+```
+time -p [bc] ../timeconst.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 15.62
+user 15.08
+sys 0.53
+```
+
+For this `bc`:
+
+```
+real 10.09
+user 10.08
+sys 0.01
+```
+
+The command for the next script, the `for` loop script, was:
+
+```
+time -p [bc] ../test.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 14.76
+user 14.75
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 17.95
+user 17.94
+sys 0.00
+```
+
+The command for the next script, the `while` loop script, was:
+
+```
+time -p [bc] ../test2.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 14.84
+user 14.83
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 13.53
+user 13.52
+sys 0.00
+```
+
+## Link-Time Optimization Only
+
+Just for kicks, let's see if `-march=native` is even useful.
+
+The optimizations I used for both `bc`'s were `-O3 -flto`.
+
+### Addition
+
+The command used was:
+
+```
+tests/script.sh bc add.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 2.41
+user 1.05
+sys 1.35
+```
+
+For this `bc`:
+
+```
+real 0.58
+user 0.52
+sys 0.05
+```
+
+### Subtraction
+
+The command used was:
+
+```
+tests/script.sh bc subtract.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 2.39
+user 1.10
+sys 1.28
+```
+
+For this `bc`:
+
+```
+real 0.65
+user 0.57
+sys 0.07
+```
+
+### Multiplication
+
+The command used was:
+
+```
+tests/script.sh bc multiply.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 6.82
+user 4.30
+sys 2.51
+```
+
+For this `bc`:
+
+```
+real 1.57
+user 1.49
+sys 0.08
+```
+
+### Division
+
+The command used was:
+
+```
+tests/script.sh bc divide.bc 1 0 1 1 [bc]
+```
+
+For GNU `bc`:
+
+```
+real 3.25
+user 1.81
+sys 1.43
+```
+
+For this `bc`:
+
+```
+real 1.27
+user 1.23
+sys 0.04
+```
+
+### Power
+
+The command used was:
+
+```
+printf '1234567890^100000; halt\n' | time -p [bc] -q > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 10.50
+user 10.49
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 0.72
+user 0.71
+sys 0.00
+```
+
+### Scripts
+
+The command for the `../timeconst.bc` script was:
+
+```
+time -p [bc] ../timeconst.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 15.50
+user 14.81
+sys 0.68
+```
+
+For this `bc`:
+
+```
+real 10.17
+user 10.15
+sys 0.01
+```
+
+The command for the next script, the `for` loop script, was:
+
+```
+time -p [bc] ../test.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 14.99
+user 14.99
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 16.85
+user 16.84
+sys 0.00
+```
+
+The command for the next script, the `while` loop script, was:
+
+```
+time -p [bc] ../test2.bc > /dev/null
+```
+
+For GNU `bc`:
+
+```
+real 14.92
+user 14.91
+sys 0.00
+```
+
+For this `bc`:
+
+```
+real 12.75
+user 12.75
+sys 0.00
+```
+
+It turns out that `-march=native` can be a problem. As such, I have removed the
+recommendation to build with `-march=native`.
+
+## Recommended Compiler
+
+When I ran these benchmarks with my `bc` compiled under `clang` vs. `gcc`, it
+performed much better under `clang`. I recommend compiling this `bc` with
+`clang`.
+
+[1]: https://github.com/torvalds/linux/blob/master/kernel/time/timeconst.bc
diff --git a/contrib/bc/manuals/build.md b/contrib/bc/manuals/build.md
new file mode 100644
index 000000000000..47fbabdfad7f
--- /dev/null
+++ b/contrib/bc/manuals/build.md
@@ -0,0 +1,694 @@
+# Build
+
+This `bc` attempts to be as portable as possible. It can be built on any
+POSIX-compliant system.
+
+To accomplish that, a POSIX-compatible, custom `configure.sh` script is used to
+select build options, compiler, and compiler flags and generate a `Makefile`.
+
+The general form of configuring, building, and installing this `bc` is as
+follows:
+
+```
+[ENVIRONMENT_VARIABLE=<value>...] ./configure.sh [build_options...]
+make
+make install
+```
+
+To get all of the options, including any useful environment variables, use
+either one of the following commands:
+
+```
+./configure.sh -h
+./configure.sh --help
+```
+
+***WARNING***: even though `configure.sh` supports both option types, short and
+long, it does not support handling both at the same time. Use only one type.
+
+To learn the available `make` targets run the following command after running
+the `configure.sh` script:
+
+```
+make help
+```
+
+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.
+
+<a name="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,
+though `HOSTCC` is prioritized). This is in order to bootstrap core file(s), if
+the architectures are not compatible (i.e., unlike i686 on x86_64). Thus, the
+approach is:
+
+```
+HOSTCC="/path/to/native/compiler" ./configure.sh
+make
+make install
+```
+
+`HOST_CC` will work in exactly the same way.
+
+`HOSTCFLAGS` and `HOST_CFLAGS` can be used to set compiler flags for `HOSTCC`.
+(The two are equivalent, as `HOSTCC` and `HOST_CC` are.) `HOSTCFLAGS` is
+prioritized over `HOST_CFLAGS`. If neither are present, `HOSTCC` (or `HOST_CC`)
+uses `CFLAGS` (see [Build Environment Variables][4] for more details).
+
+It is expected that `CC` produces code for the target system and `HOSTCC`
+produces code for the host system. See [Build Environment Variables][4] for more
+details.
+
+If an emulator is necessary to run the bootstrap binaries, it can be set with
+the environment variable `GEN_EMU`.
+
+<a name="build-environment-variables"/>
+
+## Build Environment Variables
+
+This `bc` supports `CC`, `HOSTCC`, `HOST_CC`, `CFLAGS`, `HOSTCFLAGS`,
+`HOST_CFLAGS`, `CPPFLAGS`, `LDFLAGS`, `LDLIBS`, `PREFIX`, `DESTDIR`, `BINDIR`,
+`DATAROOTDIR`, `DATADIR`, `MANDIR`, `MAN1DIR`, `LOCALEDIR` `EXECSUFFIX`,
+`EXECPREFIX`, `LONG_BIT`, `GEN_HOST`, and `GEN_EMU` environment variables in
+`configure.sh`. Any values of those variables given to `configure.sh` will be
+put into the generated Makefile.
+
+More detail on what those environment variables do can be found in the following
+sections.
+
+### `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
+compatible compiler they wish.**
+
+If there is a space in the basename of the compiler, the items after the first
+space are assumed to be compiler flags, and in that case, the flags are
+automatically moved into CFLAGS.
+
+Defaults to `c99`.
+
+### `HOSTCC` or `HOST_CC`
+
+C compiler for the host system, used only in [cross compiling][6]. Must be
+compatible with POSIX `c99` behavior and options.
+
+If there is a space in the basename of the compiler, the items after the first
+space are assumed to be compiler flags, and in that case, the flags are
+automatically moved into HOSTCFLAGS.
+
+Defaults to `$CC`.
+
+### `CFLAGS`
+
+Command-line flags that will be passed verbatim to `CC`.
+
+Defaults to empty.
+
+### `HOSTCFLAGS` or `HOST_CFLAGS`
+
+Command-line flags that will be passed verbatim to `HOSTCC` or `HOST_CC`.
+
+Defaults to `$CFLAGS`.
+
+### `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`
+
+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`
+
+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
+with different C standard libraries (like [musl][3]).
+
+Defaults to empty.
+
+### `PREFIX`
+
+The prefix to install to.
+
+Can be overridden by passing the `--prefix` option to `configure.sh`.
+
+Defaults to `/usr/local`.
+
+### `DESTDIR`
+
+Path to prepend onto `PREFIX`. This is mostly for distro and package
+maintainers.
+
+This can be passed either to `configure.sh` or `make install`. If it is passed
+to both, the one given to `configure.sh` takes precedence.
+
+Defaults to empty.
+
+### `BINDIR`
+
+The directory to install binaries in.
+
+Can be overridden by passing the `--bindir` option to `configure.sh`.
+
+Defaults to `$PREFIX/bin`.
+
+### `DATAROOTDIR`
+
+The root directory to install data files in.
+
+Can be overridden by passing the `--datarootdir` option to `configure.sh`.
+
+Defaults to `$PREFIX/share`.
+
+### `DATADIR`
+
+The directory to install data files in.
+
+Can be overridden by passing the `--datadir` option to `configure.sh`.
+
+Defaults to `$DATAROOTDIR`.
+
+### `MANDIR`
+
+The directory to install manpages in.
+
+Can be overridden by passing the `--mandir` option to `configure.sh`.
+
+Defaults to `$DATADIR/man`
+
+### `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.
+
+Can be overridden by passing the `--man1dir` option to `configure.sh`.
+
+Defaults to `$MANDIR/man1`.
+
+### `LOCALEDIR`
+
+The directory to install locales in.
+
+Can be overridden by passing the `--localedir` option to `configure.sh`.
+
+Defaults to `$DATAROOTDIR/locale`.
+
+### `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
+want to replace the default `bc`.
+
+Defaults to empty.
+
+### `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,
+but do not want to replace the default `bc`.
+
+Defaults to empty.
+
+### `LONG_BIT`
+
+The number of bits in a C `long` type. This is mostly for the embedded space.
+
+This `bc` uses `long`s internally for overflow checking. In C99, a `long` is
+required to be 32 bits. For this reason, on 8-bit and 16-bit microcontrollers,
+the generated code to do math with `long` types may be inefficient.
+
+For most normal desktop systems, setting this is unnecessary, except that 32-bit
+platforms with 64-bit longs may want to set it to `32`.
+
+Defaults to the default value of `LONG_BIT` for the target platform. For
+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`
+
+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,
+`gen/strgen.c` is used, compiled by `$HOSTCC` and run on the host machine. Using
+`gen/strgen.sh` removes the need to compile and run an executable on the host
+machine since `gen/strgen.sh` is a POSIX shell script. However, `gen/lib2.bc` is
+perilously close to 4095 characters, the max supported length of a string
+literal in C99 (and it could be added to in the future), and `gen/strgen.sh`
+generates a string literal instead of an array, as `gen/strgen.c` does. For most
+production-ready compilers, this limit probably is not enforced, but it could
+be. Both options are still available for this reason.
+
+If you are sure your compiler does not have the limit and do not want to compile
+and run a binary on the host machine, set this variable to "0". Any other value,
+or a non-existent value, will cause the build system to compile and run
+`gen/strgen.c`.
+
+Default is "".
+
+### `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.
+
+Defaults to empty.
+
+<a name="build-options"/>
+
+## Build Options
+
+This `bc` comes with several build options, all of which are enabled by default.
+
+All options can be used with each other, with a few exceptions that will be
+noted below.
+
+**NOTE**: All long options with mandatory argumenst accept either one of the
+following forms:
+
+```
+--option arg
+--option=arg
+```
+
+### Library
+
+To build the math library, use the following commands for the configure step:
+
+```
+./configure.sh -a
+./configure.sh --library
+```
+
+Both commands are equivalent.
+
+When the library is built, history, prompt, and locales are disabled, and the
+functionality for `bc` and `dc` are both enabled, though the executables are
+*not* built. This is because the library's options clash with the executables.
+
+To build an optimized version of the library, users can pass optimization
+options to `configure.sh` or include them in `CFLAGS`.
+
+The library API can be found in `manuals/bcl.3.md` or `man bcl` once the library
+is installed.
+
+The library is built as `bin/libbcl.a`.
+
+### `bc` Only
+
+To build `bc` only (no `dc`), use any one of the following commands for the
+configure step:
+
+```
+./configure.sh -b
+./configure.sh --bc-only
+./configure.sh -D
+./configure.sh --disable-dc
+```
+
+Those commands are all equivalent.
+
+***Warning***: It is an error to use those options if `bc` has also been
+disabled (see below).
+
+### `dc` Only
+
+To build `dc` only (no `bc`), use either one of the following commands for the
+configure step:
+
+```
+./configure.sh -d
+./configure.sh --dc-only
+./configure.sh -B
+./configure.sh --disable-bc
+```
+
+Those commands are all equivalent.
+
+***Warning***: It is an error to use those options if `dc` has also been
+disabled (see above).
+
+<a name="build-history"/>
+
+### History
+
+To disable signal handling, pass either the `-H` flag or the `--disable-history`
+option to `configure.sh`, as follows:
+
+```
+./configure.sh -H
+./configure.sh --disable-history
+```
+
+Both commands are equivalent.
+
+History is automatically disabled when building for Windows or on another
+platform that does not support the terminal handling that is required.
+
+***WARNING***: Of all of the code in the `bc`, this is the only code that is not
+completely portable. If the `bc` does not work on your platform, your first step
+should be to retry with history disabled.
+
+### 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:
+
+```
+./configure.sh -N
+./configure.sh --disable-nls
+```
+
+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
+
+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
+can be disabled permanently in the build by passing the `-P` flag or the
+`--disable-prompt` option to `configure.sh`, as follows:
+
+```
+./configure.sh -P
+./configure.sh --disable-prompt
+```
+
+Both commands are equivalent.
+
+### 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
+the locales that exist on the system. The `-l` flag or `--install-all-locales`
+option skips all of that and just installs all of the locales that `bc` and `dc`
+have, regardless. To enable that behavior, you can pass the `-l` flag or the
+`--install-all-locales` option to `configure.sh`, as follows:
+
+```
+./configure.sh -l
+./configure.sh --install-all-locales
+```
+
+Both commands are equivalent.
+
+### Extra Math
+
+This `bc` has 7 extra operators:
+
+* `$` (truncation to integer)
+* `@` (set precision)
+* `@=` (set precision and assign)
+* `<<` (shift number left, shifts radix right)
+* `<<=` (shift number left and assign)
+* `>>` (shift number right, shifts radix left)
+* `>>=` (shift number right and assign)
+
+There is no assignment version of `$` because it is a unary operator.
+
+The assignment versions of the above operators are not available in `dc`, but
+the others are, as the operators `$`, `@`, `H`, and `h`, respectively.
+
+In addition, this `bc` has the option of outputting in scientific notation or
+engineering notation. It can also take input in scientific or engineering
+notation. On top of that, it has a pseudo-random number generator. (See the
+full manual for more details.)
+
+Extra operators, scientific notation, engineering notation, and the
+pseudo-random number generator can be disabled by passing either the `-E` flag
+or the `--disable-extra-math` option to `configure.sh`, as follows:
+
+```
+./configure.sh -E
+./configure.sh --disable-extra-math
+```
+
+Both commands are equivalent.
+
+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
+
+To disable installing manpages, pass either the `-M` flag or the
+`--disable-man-pages` option to `configure.sh` as follows:
+
+```
+./configure.sh -M
+./configure.sh --disable-man-pages
+```
+
+Both commands are equivalent.
+
+### 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
+the `-k` flag or the `--karatsuba-len` option to `configure.sh` as follows:
+
+```
+./configure.sh -k64
+./configure.sh --karatsuba-len 64
+```
+
+Both commands are equivalent.
+
+Default is `64`.
+
+***WARNING***: The Karatsuba Length must be a **integer** greater than or equal
+to `16` (to prevent stack overflow). If it is not, `configure.sh` will give an
+error.
+
+### Install Options
+
+The relevant `autotools`-style install options are supported in `configure.sh`:
+
+* `--prefix`
+* `--bindir`
+* `--datarootdir`
+* `--datadir`
+* `--mandir`
+* `--man1dir`
+* `--localedir`
+
+An example is:
+
+```
+./configure.sh --prefix=/usr --localedir /usr/share/nls
+make
+make install
+```
+
+They correspond to the environment variables `$PREFIX`, `$BINDIR`,
+`$DATAROOTDIR`, `$DATADIR`, `$MANDIR`, `$MAN1DIR`, and `$LOCALEDIR`,
+respectively.
+
+***WARNING***: If the option is given, the value of the corresponding
+environment variable is overridden.
+
+***WARNING***: If any long command-line options are used, the long form of all
+other command-line options must be used. Mixing long and short options is not
+supported.
+
+## 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
+***highly*** recommend package and distro maintainers pass the highest
+optimization level available in `CC` to `configure.sh` with the `-O` flag or
+`--opt` option, as follows:
+
+```
+./configure.sh -O3
+./configure.sh --opt 3
+```
+
+Both commands are equivalent.
+
+The build and install can then be run as normal:
+
+```
+make
+make install
+```
+
+As usual, `configure.sh` will also accept additional `CFLAGS` on the command
+line, so for SSE4 architectures, the following can add a bit more speed:
+
+```
+CFLAGS="-march=native -msse4" ./configure.sh -O3
+make
+make install
+```
+
+Building with link-time optimization (`-flto` in clang) can further increase the
+performance. I ***highly*** recommend doing so.
+
+I do **NOT*** recommend building with `-march=native`; doing so reduces this
+`bc`'s performance.
+
+Manual stripping is not necessary; non-debug builds are automatically stripped
+in the link stage.
+
+## 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
+the `--debug` option, as follows:
+
+```
+./configure.sh -g
+./configure.sh --debug
+```
+
+Both commands are equivalent.
+
+The build and install can then be run as normal:
+
+```
+make
+make install
+```
+
+## 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
+`--disable-strip` option, as follows:
+
+```
+./configure.sh -T
+./configure.sh --disable-strip
+```
+
+Both commands are equivalent.
+
+The build and install can then be run as normal:
+
+```
+make
+make install
+```
+
+## 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
+isn't much for what is contained in the binary, but if necessary, it can be
+reduced.
+
+The single largest user of space is the `bc` calculator. If just `dc` is needed,
+the size can be reduced to 107.6 kb (107,584 bytes).
+
+The next largest user of space is history support. If that is not needed, size
+can be reduced (for a build with both calculators) to 119.9 kb (119,866 bytes).
+
+There are several reasons that history is a bigger user of space than `dc`
+itself:
+
+* `dc`'s lexer and parser are *tiny* compared to `bc`'s because `dc` code is
+ almost already in the form that it is executed in, while `bc` has to not only
+ adjust the form to be executable, it has to parse functions, loops, `if`
+ statements, and other extra features.
+* `dc` does not have much extra code in the interpreter.
+* History has a lot of const data for supporting `UTF-8` terminals.
+* History pulls in a bunch of more code from the `libc`.
+
+The next biggest user is extra math support. Without it, the size is reduced to
+124.0 kb (123,986 bytes) with history and 107.6 kb (107,560 bytes) without
+history.
+
+The reasons why extra math support is bigger than `dc`, besides the fact that
+`dc` is small already, are:
+
+* Extra math supports adds an extra math library that takes several kilobytes of
+ constant data space.
+* Extra math support includes support for a pseudo-random number generator,
+ including the code to convert a series of pseudo-random numbers into a number
+ of arbitrary size.
+* Extra math support adds several operators.
+
+The next biggest user is `dc`, so if just `bc` is needed, the size can be
+reduced to 128.1 kb (128,096 bytes) with history and extra math support, 107.6
+kb (107,576 bytes) without history and with extra math support, and 95.3 kb
+(95,272 bytes) without history and without extra math support.
+
+*Note*: all of these binary sizes were compiled using `musl` `1.2.0` as the
+`libc`, making a fully static executable, with `clang` `9.0.1` (well,
+`musl-clang` using `clang` `9.0.1`) as the compiler and using `-Os`
+optimizations. These builds were done on an `x86_64` machine running Gentoo
+Linux.
+
+## Testing
+
+The default test suite can be run with the following command:
+
+```
+make test
+```
+
+To test `bc` only, run the following command:
+
+```
+make test_bc
+```
+
+To test `dc` only, run the following command:
+
+```
+make test_dc
+```
+
+This `bc`, if built, assumes a working, GNU-compatible `bc`, installed on the
+system and in the `PATH`, to generate some tests, unless the `-G` flag or
+`--disable-generated-tests` option is given to `configure.sh`, as follows:
+
+```
+./configure.sh -G
+./configure.sh --disable-generated-tests
+```
+
+After running `configure.sh`, build and run tests as follows:
+
+```
+make
+make test
+```
+
+This `dc` also assumes a working, GNU-compatible `dc`, installed on the system
+and in the `PATH`, to generate some tests, unless one of the above options is
+given to `configure.sh`.
+
+To generate test coverage, pass the `-c` flag or the `--coverage` option to
+`configure.sh` as follows:
+
+```
+./configure.sh -c
+./configure.sh --coverage
+```
+
+Both commands are equivalent.
+
+***WARNING***: Both `bc` and `dc` must be built for test coverage. Otherwise,
+`configure.sh` will give an error.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
+[2]: https://www.gnu.org/software/bc/
+[3]: https://www.musl-libc.org/
+[4]: #build-environment-variables
+[5]: #build-options
+[6]: #cross-compiling
diff --git a/contrib/bc/manuals/dc.1.md.in b/contrib/bc/manuals/dc.1.md.in
new file mode 100644
index 000000000000..5308b1c604a5
--- /dev/null
+++ b/contrib/bc/manuals/dc.1.md.in
@@ -0,0 +1,1258 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+{{ 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
+ 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 }}
+{{ 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
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+{{ A H N P HN HP NP HNP }}
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+value for **obase** is **2**. Values are output in the specified base.
+{{ end }}
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+{{ A H N P HN HP NP HNP }}
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+{{ end }}
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+{{ A H N P HN HP NP HNP }}
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+{{ end }}
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+{{ A H N P HN HP NP HNP }}
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+{{ end }}
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+{{ A H N P HN HP NP HNP }}
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+{{ end }}
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+{{ A H N P HN HP NP HNP }}
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+{{ end }}
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+{{ A H N P HN HP NP HNP }}
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+{{ end }}
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+{{ A H N P HN HP NP HNP }}
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+{{ end }}
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+{{ A H N P HN HP NP HNP }}
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+{{ end }}
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+{{ A H N P HN HP NP HNP }}
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+{{ end }}
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+{{ A H N P HN HP NP HNP }}
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+{{ end }}
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+{{ A H N P HN HP NP HNP }}
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+{{ end }}
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ Math errors include divide by **0**, taking the square root of a negative
+{{ A H N P HN HP NP HNP }}
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+{{ end }}
+{{ E EH EN EP EHN EHP ENP EHNP }}
+ 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
+ (**\^**) operator.
+{{ end }}
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+{{ A E N P EN EP NP ENP }}
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+{{ end }}
+
+{{ A E H N EH EN HN EHN }}
+The prompt is enabled in TTY mode.
+{{ end }}
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+{{ A E N P EN EP NP ENP }}
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+{{ end }}
+{{ H EH HN HP EHN EHP HNP EHNP }}
+default handler for all other signals.
+{{ end }}
+
+{{ A E N P EN EP NP ENP }}
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+{{ end }}
+
+{{ A E H P EH EP HP EHP }}
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+{{ end }}
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/A.1 b/contrib/bc/manuals/dc/A.1
new file mode 100644
index 000000000000..c993afb1fd4e
--- /dev/null
+++ b/contrib/bc/manuals/dc/A.1
@@ -0,0 +1,1334 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/A.1.md b/contrib/bc/manuals/dc/A.1.md
new file mode 100644
index 000000000000..d48b2429aaa2
--- /dev/null
+++ b/contrib/bc/manuals/dc/A.1.md
@@ -0,0 +1,1195 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/E.1 b/contrib/bc/manuals/dc/E.1
new file mode 100644
index 000000000000..1e04920d51fd
--- /dev/null
+++ b/contrib/bc/manuals/dc/E.1
@@ -0,0 +1,1130 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/E.1.md b/contrib/bc/manuals/dc/E.1.md
new file mode 100644
index 000000000000..3ccf45a98ae3
--- /dev/null
+++ b/contrib/bc/manuals/dc/E.1.md
@@ -0,0 +1,1031 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/EH.1 b/contrib/bc/manuals/dc/EH.1
new file mode 100644
index 000000000000..5ccc64ea725e
--- /dev/null
+++ b/contrib/bc/manuals/dc/EH.1
@@ -0,0 +1,1115 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/EH.1.md b/contrib/bc/manuals/dc/EH.1.md
new file mode 100644
index 000000000000..b59a5ef71a0c
--- /dev/null
+++ b/contrib/bc/manuals/dc/EH.1.md
@@ -0,0 +1,1018 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/EHN.1 b/contrib/bc/manuals/dc/EHN.1
new file mode 100644
index 000000000000..bce6e577df6c
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHN.1
@@ -0,0 +1,1111 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/EHN.1.md b/contrib/bc/manuals/dc/EHN.1.md
new file mode 100644
index 000000000000..fd1a0251fd04
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHN.1.md
@@ -0,0 +1,1013 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/EHNP.1 b/contrib/bc/manuals/dc/EHNP.1
new file mode 100644
index 000000000000..98cdfd150436
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHNP.1
@@ -0,0 +1,1104 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/EHNP.1.md b/contrib/bc/manuals/dc/EHNP.1.md
new file mode 100644
index 000000000000..c1d7457770e8
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHNP.1.md
@@ -0,0 +1,1008 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/EHP.1 b/contrib/bc/manuals/dc/EHP.1
new file mode 100644
index 000000000000..5f930f841aa4
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHP.1
@@ -0,0 +1,1108 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/EHP.1.md b/contrib/bc/manuals/dc/EHP.1.md
new file mode 100644
index 000000000000..2df787cef087
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHP.1.md
@@ -0,0 +1,1013 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/EN.1 b/contrib/bc/manuals/dc/EN.1
new file mode 100644
index 000000000000..561a0f665cfc
--- /dev/null
+++ b/contrib/bc/manuals/dc/EN.1
@@ -0,0 +1,1126 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/EN.1.md b/contrib/bc/manuals/dc/EN.1.md
new file mode 100644
index 000000000000..01c40a8e34dc
--- /dev/null
+++ b/contrib/bc/manuals/dc/EN.1.md
@@ -0,0 +1,1026 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/ENP.1 b/contrib/bc/manuals/dc/ENP.1
new file mode 100644
index 000000000000..77a94af08310
--- /dev/null
+++ b/contrib/bc/manuals/dc/ENP.1
@@ -0,0 +1,1119 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/ENP.1.md b/contrib/bc/manuals/dc/ENP.1.md
new file mode 100644
index 000000000000..9eb8696d1755
--- /dev/null
+++ b/contrib/bc/manuals/dc/ENP.1.md
@@ -0,0 +1,1021 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/EP.1 b/contrib/bc/manuals/dc/EP.1
new file mode 100644
index 000000000000..9a41956d67a5
--- /dev/null
+++ b/contrib/bc/manuals/dc/EP.1
@@ -0,0 +1,1123 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]2\f[R].
+Values are output in the specified base.
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.TP
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]I\f[R]
+Pushes the current value of \f[B]ibase\f[R] onto the main stack.
+.TP
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/EP.1.md b/contrib/bc/manuals/dc/EP.1.md
new file mode 100644
index 000000000000..f9333fd29e19
--- /dev/null
+++ b/contrib/bc/manuals/dc/EP.1.md
@@ -0,0 +1,1026 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **2**. Values are output in the specified base.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, and **scale**. Also
+see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **2** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**) operator.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/H.1 b/contrib/bc/manuals/dc/H.1
new file mode 100644
index 000000000000..78f0f55603aa
--- /dev/null
+++ b/contrib/bc/manuals/dc/H.1
@@ -0,0 +1,1319 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/H.1.md b/contrib/bc/manuals/dc/H.1.md
new file mode 100644
index 000000000000..6542f63d4fdc
--- /dev/null
+++ b/contrib/bc/manuals/dc/H.1.md
@@ -0,0 +1,1182 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/HN.1 b/contrib/bc/manuals/dc/HN.1
new file mode 100644
index 000000000000..2c8bde98b88a
--- /dev/null
+++ b/contrib/bc/manuals/dc/HN.1
@@ -0,0 +1,1315 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/HN.1.md b/contrib/bc/manuals/dc/HN.1.md
new file mode 100644
index 000000000000..b81a98ffbf4f
--- /dev/null
+++ b/contrib/bc/manuals/dc/HN.1.md
@@ -0,0 +1,1177 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/HNP.1 b/contrib/bc/manuals/dc/HNP.1
new file mode 100644
index 000000000000..a777eaa81074
--- /dev/null
+++ b/contrib/bc/manuals/dc/HNP.1
@@ -0,0 +1,1308 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/HNP.1.md b/contrib/bc/manuals/dc/HNP.1.md
new file mode 100644
index 000000000000..c4431fd7a4b2
--- /dev/null
+++ b/contrib/bc/manuals/dc/HNP.1.md
@@ -0,0 +1,1172 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/HP.1 b/contrib/bc/manuals/dc/HP.1
new file mode 100644
index 000000000000..872e6ef3e40b
--- /dev/null
+++ b/contrib/bc/manuals/dc/HP.1
@@ -0,0 +1,1312 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/HP.1.md b/contrib/bc/manuals/dc/HP.1.md
new file mode 100644
index 000000000000..ffc61e93247b
--- /dev/null
+++ b/contrib/bc/manuals/dc/HP.1.md
@@ -0,0 +1,1177 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/N.1 b/contrib/bc/manuals/dc/N.1
new file mode 100644
index 000000000000..590d563faa50
--- /dev/null
+++ b/contrib/bc/manuals/dc/N.1
@@ -0,0 +1,1330 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+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
+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
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+The prompt is enabled in TTY mode.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/N.1.md b/contrib/bc/manuals/dc/N.1.md
new file mode 100644
index 000000000000..ef94824c7a00
--- /dev/null
+++ b/contrib/bc/manuals/dc/N.1.md
@@ -0,0 +1,1190 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-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
+ 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**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+The prompt is enabled in TTY mode.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/NP.1 b/contrib/bc/manuals/dc/NP.1
new file mode 100644
index 000000000000..01c5f1e854f2
--- /dev/null
+++ b/contrib/bc/manuals/dc/NP.1
@@ -0,0 +1,1323 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/NP.1.md b/contrib/bc/manuals/dc/NP.1.md
new file mode 100644
index 000000000000..e744a40c2474
--- /dev/null
+++ b/contrib/bc/manuals/dc/NP.1.md
@@ -0,0 +1,1185 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/dc/P.1 b/contrib/bc/manuals/dc/P.1
new file mode 100644
index 000000000000..a39132aea914
--- /dev/null
+++ b/contrib/bc/manuals/dc/P.1
@@ -0,0 +1,1327 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
+.TH "DC" "1" "October 2020" "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]\[en]version\f[R]]
+[\f[B]\[en]help\f[R]] [\f[B]\[en]interactive\f[R]]
+[\f[B]\[en]no-prompt\f[R]] [\f[B]\[en]extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]\[en]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.
+It uses a stack (reverse Polish notation) to store numbers and results
+of computations.
+Arithmetic operations pop arguments off of the stack and push the
+results.
+.PP
+If no files are given on the command-line as extra arguments (i.e., not
+as \f[B]-f\f[R] or \f[B]\[en]file\f[R] arguments), then dc(1) reads from
+\f[B]stdin\f[R].
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where \f[B]-e\f[R] (\f[B]\[en]expression\f[R]) and
+\f[B]-f\f[R] (\f[B]\[en]file\f[R]) arguments cause dc(1) to execute them
+and exit.
+The reason for this is that this dc(1) allows users to set arguments in
+the environment variable \f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section).
+Any expressions given on the command-line should be used to set up a
+standard environment.
+For example, if a user wants the \f[B]scale\f[R] always set to
+\f[B]10\f[R], they can set \f[B]DC_ENV_ARGS\f[R] to \f[B]-e 10k\f[R],
+and this dc(1) will always start with a \f[B]scale\f[R] of \f[B]10\f[R].
+.PP
+If users want to have dc(1) exit after processing all input from
+\f[B]-e\f[R] and \f[B]-f\f[R] arguments (and their equivalents), then
+they can just simply add \f[B]-e q\f[R] as the last command-line
+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]\[en]help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]\[en]version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]\[en]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]-P\f[R], \f[B]\[en]no-prompt\f[R]
+This option is a no-op.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]\[en]extended-register\f[R]
+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
+.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]\[en]expression\f[R]=\f[I]expr\f[R]
+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
+.PP
+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]\[en]file\f[R].
+.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]\[en]file\f[R]=\f[I]file\f[R]
+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
+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]\[en]file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]\[en]expression\f[R],
+\f[B]-f\f[R], or \f[B]\[en]file\f[R] arguments are given after that,
+bc(1) will give a fatal error and exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stdout\f[R], so if \f[B]stdout\f[R] is closed, as in
+\f[B]dc >&-\f[R], it will quit with an error.
+This is done so that dc(1) can report problems when \f[B]stdout\f[R] is
+redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stdout\f[R] to \f[B]/dev/null\f[R].
+.SH STDERR
+.PP
+Any error output is written to \f[B]stderr\f[R].
+.PP
+\f[B]Note\f[R]: Unlike other dc(1) implementations, this dc(1) will
+issue a fatal error (see the \f[B]EXIT STATUS\f[R] section) if it cannot
+write to \f[B]stderr\f[R], so if \f[B]stderr\f[R] is closed, as in
+\f[B]dc 2>&-\f[R], it will quit with an error.
+This is done so that dc(1) can exit with an error code when
+\f[B]stderr\f[R] is redirected to a file.
+.PP
+If there are scripts that depend on the behavior of other dc(1)
+implementations, it is recommended that those scripts be changed to
+redirect \f[B]stderr\f[R] to \f[B]/dev/null\f[R].
+.SH SYNTAX
+.PP
+Each item in the input source code, either a number (see the
+\f[B]NUMBERS\f[R] section) or a command (see the \f[B]COMMANDS\f[R]
+section), is processed and executed, in order.
+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
+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].
+The min allowable value for \f[B]ibase\f[R] is \f[B]2\f[R].
+The max allowable value for \f[B]ibase\f[R] can be queried in dc(1)
+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
+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
+can be queried with the \f[B]U\f[R] command.
+The min allowable value for \f[B]obase\f[R] is \f[B]0\f[R].
+If \f[B]obase\f[R] is \f[B]0\f[R], values are output in scientific
+notation, and if \f[B]obase\f[R] is \f[B]1\f[R], values are output in
+engineering notation.
+Otherwise, values are output in the specified base.
+.PP
+Outputting in scientific and engineering notations are \f[B]non-portable
+extensions\f[R].
+.PP
+The \f[I]scale\f[R] of an expression is the number of digits in the
+result of the expression right of the decimal point, and \f[B]scale\f[R]
+is a register (see the \f[B]REGISTERS\f[R] section) that sets the
+precision of any operations (with exceptions).
+\f[B]scale\f[R] is initially \f[B]0\f[R].
+\f[B]scale\f[R] cannot be negative.
+The max allowable value for \f[B]scale\f[R] can be queried in dc(1)
+programs with the \f[B]V\f[R] command.
+.PP
+\f[B]seed\f[R] is a register containing the current seed for the
+pseudo-random number generator.
+If the current value of \f[B]seed\f[R] is queried and stored, then if it
+is assigned to \f[B]seed\f[R] later, the pseudo-random number generator
+is guaranteed to produce the same sequence of pseudo-random numbers that
+were generated after the value of \f[B]seed\f[R] was first queried.
+.PP
+Multiple values assigned to \f[B]seed\f[R] can produce the same sequence
+of pseudo-random numbers.
+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
+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
+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
+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[B]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+.PP
+The pseudo-random number generator, \f[B]seed\f[R], and all associated
+operations are \f[B]non-portable extensions\f[R].
+.SS Comments
+.PP
+Comments go from \f[B]#\f[R] until, and not including, the next newline.
+This is a \f[B]non-portable extension\f[R].
+.SH NUMBERS
+.PP
+Numbers are strings made up of digits, uppercase letters up to
+\f[B]F\f[R], and at most \f[B]1\f[R] period for a radix.
+Numbers can have up to \f[B]DC_NUM_MAX\f[R] digits.
+Uppercase letters are equal to \f[B]9\f[R] + their position in the
+alphabet (i.e., \f[B]A\f[R] equals \f[B]10\f[R], or \f[B]9+1\f[R]).
+If a digit or letter makes no sense with the current value of
+\f[B]ibase\f[R], they are set to the value of the highest valid digit in
+\f[B]ibase\f[R].
+.PP
+Single-character numbers (i.e., \f[B]A\f[R] alone) take the value that
+they would have if they were valid digits, regardless of the value of
+\f[B]ibase\f[R].
+This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and
+\f[B]F\f[R] alone always equals decimal \f[B]15\f[R].
+.PP
+In addition, dc(1) accepts numbers in scientific notation.
+These have the form \f[B]<number>e<integer>\f[R].
+The exponent (the portion after the \f[B]e\f[R]) must be an integer.
+An example is \f[B]1.89237e9\f[R], which is equal to
+\f[B]1892370000\f[R].
+Negative exponents are also allowed, so \f[B]4.2890e_3\f[R] is equal to
+\f[B]0.0042890\f[R].
+.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 dc(1) is given the
+number string \f[B]FFeA\f[R], the resulting decimal number will be
+\f[B]2550000000000\f[R], and if dc(1) is given the number string
+\f[B]10e_4\f[R], the resulting decimal number will be \f[B]0.0016\f[R].
+.PP
+Accepting input as scientific notation is a \f[B]non-portable
+extension\f[R].
+.SH COMMANDS
+.PP
+The valid commands are listed below.
+.SS Printing
+.PP
+These commands are used for printing.
+.PP
+Note that both scientific notation and engineering notation are
+available for printing numbers.
+Scientific notation is activated by assigning \f[B]0\f[R] to
+\f[B]obase\f[R] using \f[B]0o\f[R], and engineering notation is
+activated by assigning \f[B]1\f[R] to \f[B]obase\f[R] using
+\f[B]1o\f[R].
+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
+\f[B]p\f[R]
+Prints the value on top of the stack, whether number or string, and
+prints a newline after.
+.RS
+.PP
+This does not alter the stack.
+.RE
+.TP
+\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
+\f[B]P\f[R]
+Pops a value off the stack.
+.RS
+.PP
+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
+If the value is a string, it is printed without a trailing newline.
+.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
+Users should use this command when they get lost.
+.RE
+.SS Arithmetic
+.PP
+These are the commands used for arithmetic.
+.TP
+\f[B]+\f[R]
+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
+\f[B]-\f[R]
+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
+\f[B]*\f[R]
+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
+\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
+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 first value popped off of the stack must be non-zero.
+.RE
+.TP
+\f[B]\[ti]\f[R]
+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
+The first value popped off of the stack must be non-zero.
+.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 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[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.
+The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R].
+.RS
+.PP
+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
+.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
+back onto the stack.
+Otherwise, its absolute value is pushed onto the stack.
+.RS
+.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 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.
+.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
+\f[B]\[at]\f[R]
+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
+.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
+left (radix shifted right) to the value of the first.
+.RS
+.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
+right (radix shifted left) to the value of the first.
+.RS
+.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
+\f[B]N\f[R]
+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
+.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
+\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
+second, or \f[B]0\f[R] otherwise.
+.RS
+.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.
+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
+.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.
+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
+.SS Pseudo-Random Number Generator
+.PP
+dc(1) has a built-in pseudo-random number generator.
+These commands query the pseudo-random number generator.
+(See Parameters for more information about the \f[B]seed\f[R] value that
+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
+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
+.TP
+\f[B]\[dq]\f[R]
+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]
+remains unchanged.
+If the bound is larger than \f[B]DC_RAND_MAX\f[R], the higher bound is
+honored by generating several pseudo-random integers, multiplying them
+by appropriate powers of \f[B]DC_RAND_MAX+1\f[R], and adding them
+together.
+Thus, the size of integer that can be generated with this command is
+unbounded.
+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
+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
+.SS Stack Control
+.PP
+These commands control the stack.
+.TP
+\f[B]c\f[R]
+Removes all items from (\[lq]clears\[rq]) the stack.
+.TP
+\f[B]d\f[R]
+Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes
+the copy onto the stack.
+.TP
+\f[B]r\f[R]
+Swaps (\[lq]reverses\[rq]) the two top items on the stack.
+.TP
+\f[B]R\f[R]
+Pops (\[lq]removes\[rq]) the top value from the stack.
+.SS Register Control
+.PP
+These commands control registers (see the \f[B]REGISTERS\f[R] section).
+.TP
+\f[B]s\f[R]\f[I]r\f[R]
+Pops the value off the top of the stack and stores it into register
+\f[I]r\f[R].
+.TP
+\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.
+This does not alter the contents of \f[I]r\f[R].
+.TP
+\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
+stack of register \f[I]r\f[R].
+The previous value of the register becomes inaccessible.
+.TP
+\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
+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.
+.SS Parameters
+.PP
+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
+\f[B]i\f[R]
+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
+.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
+\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
+.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
+\f[B]j\f[R]
+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
+.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
+\f[B]O\f[R]
+Pushes the current value of \f[B]obase\f[R] onto the main stack.
+.TP
+\f[B]K\f[R]
+Pushes the current value of \f[B]scale\f[R] onto the main stack.
+.TP
+\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
+\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
+\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
+\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
+.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
+.SS Strings
+.PP
+The following commands control strings.
+.PP
+dc(1) can work with both numbers and strings, and registers (see the
+\f[B]REGISTERS\f[R] section) can hold both strings and numbers.
+dc(1) always knows whether the contents of a register are a string or a
+number.
+.PP
+While arithmetic operations have to have numbers, and will print an
+error if given a string, other commands accept strings.
+.PP
+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
+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])
+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
+\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.
+.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
+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[B]>\f[R]\f[I]r\f[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 \f[I]r\f[R] are executed.
+.RS
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is less than the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+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
+.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).
+.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.
+If the first value is equal to the second, then the contents of register
+\f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+If the first value is not equal to the second, then the contents of
+register \f[I]r\f[R] are executed.
+.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).
+.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).
+.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.
+This is to allow macros to request input from users.
+.TP
+\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.
+If there are no macros, or only one macro executing, dc(1) exits.
+.TP
+\f[B]Q\f[R]
+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
+\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
+If it is a string, pushes the number of characters the string has.
+.RE
+.TP
+\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.
+.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).
+.SS Arrays
+.PP
+These commands manipulate arrays.
+.TP
+\f[B]:\f[R]\f[I]r\f[R]
+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
+\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
+array \f[I]r\f[R].
+The selected value is then pushed onto the stack.
+.SH REGISTERS
+.PP
+Registers are names that can store strings, numbers, and arrays.
+(Number/string registers do not interfere with array registers.)
+.PP
+Each register is also its own stack, so the current register value is
+the top of the stack for the register.
+All registers, when first referenced, have one value (\f[B]0\f[R]) in
+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.
+.SS Extended Register Mode
+.PP
+Unlike most other dc(1) implentations, this dc(1) provides nearly
+unlimited amounts of registers, if extended register mode is enabled.
+.PP
+If extended register mode is enabled (\f[B]-x\f[R] or
+\f[B]\[en]extended-register\f[R] command-line arguments are given), then
+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]).
+.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
+error if the next non-space characters do not match that regex.
+.SH RESET
+.PP
+When dc(1) encounters an error or a signal that it has a non-default
+handler for, it resets.
+This means that several things happen.
+.PP
+First, any macros that are executing are stopped and popped off the
+stack.
+The behavior is not unlike that of exceptions in programming languages.
+Then the execution point is set so that any code waiting to execute
+(after all macros returned) is skipped.
+.PP
+Thus, when dc(1) resets, it skips any remaining code waiting to be
+executed.
+Then, if it is interactive mode, and the error was not a fatal error
+(see the \f[B]EXIT STATUS\f[R] section), it asks for more input;
+otherwise, it exits with the appropriate return code.
+.SH PERFORMANCE
+.PP
+Most dc(1) implementations use \f[B]char\f[R] types to calculate the
+value of \f[B]1\f[R] decimal digit at a time, but that can be slow.
+This dc(1) does something different.
+.PP
+It uses large integers to calculate more than \f[B]1\f[R] decimal digit
+at a time.
+If built in a environment where \f[B]DC_LONG_BIT\f[R] (see the
+\f[B]LIMITS\f[R] section) is \f[B]64\f[R], then each integer has
+\f[B]9\f[R] decimal digits.
+If built in an environment where \f[B]DC_LONG_BIT\f[R] is \f[B]32\f[R]
+then each integer has \f[B]4\f[R] decimal digits.
+This value (the number of decimal digits per large integer) is called
+\f[B]DC_BASE_DIGS\f[R].
+.PP
+In addition, this dc(1) uses an even larger integer for overflow
+checking.
+This integer type depends on the value of \f[B]DC_LONG_BIT\f[R], but is
+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
+\f[B]DC_LONG_BIT\f[R]
+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
+\f[B]DC_BASE_DIGS\f[R]
+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
+\f[B]DC_BASE_POW\f[R]
+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
+\f[B]DC_OVERFLOW_MAX\f[R]
+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
+\f[B]DC_BASE_MAX\f[R]
+The maximum output base.
+Set at \f[B]DC_BASE_POW\f[R].
+.TP
+\f[B]DC_DIM_MAX\f[R]
+The maximum size of arrays.
+Set at \f[B]SIZE_MAX-1\f[R].
+.TP
+\f[B]DC_SCALE_MAX\f[R]
+The maximum \f[B]scale\f[R].
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_STRING_MAX\f[R]
+The maximum length of strings.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NAME_MAX\f[R]
+The maximum length of identifiers.
+Set at \f[B]DC_OVERFLOW_MAX-1\f[R].
+.TP
+\f[B]DC_NUM_MAX\f[R]
+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
+\f[B]DC_RAND_MAX\f[R]
+The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command,
+if dc(1).
+Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R].
+.TP
+Exponent
+The maximum allowable exponent (positive or negative).
+Set at \f[B]DC_OVERFLOW_MAX\f[R].
+.TP
+Number of vars
+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
+large (at least on 64-bit machines) that there should not be any point
+at which they become a problem.
+In fact, memory should be exhausted before these limits should be hit.
+.SH ENVIRONMENT VARIABLES
+.PP
+dc(1) recognizes the following environment variables:
+.TP
+\f[B]DC_ENV_ARGS\f[R]
+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
+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
+.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 `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]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
+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
+\f[B]DC_EXPR_EXIT\f[R]
+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
+\f[B]0\f[R]
+No error.
+.TP
+\f[B]1\f[R]
+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
+.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
+\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
+\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
+.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.
+.PP
+The other statuses will only be returned when dc(1) is not in
+interactive mode (see the \f[B]INTERACTIVE MODE\f[R] section), since
+dc(1) resets its state (see the \f[B]RESET\f[R] section) and accepts
+more input when one of those errors occurs in interactive mode.
+This is also the case when interactive mode is forced by the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.PP
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the
+\f[B]-i\f[R] flag or \f[B]\[en]interactive\f[R] option.
+.SH INTERACTIVE MODE
+.PP
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both \f[B]stdin\f[R]
+and \f[B]stdout\f[R] are hooked to a terminal, but the \f[B]-i\f[R] flag
+and \f[B]\[en]interactive\f[R] option can turn it on in other cases.
+.PP
+In interactive mode, dc(1) attempts to recover from errors (see the
+\f[B]RESET\f[R] section), and in normal execution, flushes
+\f[B]stdout\f[R] as soon as execution is done for the current input.
+.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]
+.PP
+TTY mode is required for history to be enabled (see the \f[B]COMMAND
+LINE HISTORY\f[R] section).
+It is also required to enable special handling for \f[B]SIGINT\f[R]
+signals.
+.PP
+TTY mode is different from interactive mode because interactive mode is
+required in the bc(1)
+specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html),
+and interactive mode requires only \f[B]stdin\f[R] and \f[B]stdout\f[R]
+to be connected to a terminal.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to stop execution of the
+current input.
+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.
+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
+processing the file and start processing the next file, if one exists,
+or ask for input from \f[B]stdin\f[R] if no other file exists.
+.PP
+This means that if a \f[B]SIGINT\f[R] is sent to dc(1) as it is
+executing a file, it can seem as though dc(1) did not respond to the
+signal since it will immediately start executing the next file.
+This is by design; most files that users execute when interacting with
+dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file.
+The rest of the files could still be executed without problem, allowing
+the user to continue.
+.PP
+\f[B]SIGTERM\f[R] and \f[B]SIGQUIT\f[R] cause dc(1) to clean up and
+exit, and it uses the default handler for all other signals.
+The one exception is \f[B]SIGHUP\f[R]; in that case, when dc(1) is in
+TTY mode, a \f[B]SIGHUP\f[R] will cause dc(1) to clean up and exit.
+.SH COMMAND LINE HISTORY
+.PP
+dc(1) supports interactive command-line editing.
+If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), history is
+enabled.
+Previous lines can be recalled and edited with the arrow keys.
+.PP
+\f[B]Note\f[R]: tabs are converted to 8 spaces.
+.SH LOCALES
+.PP
+This dc(1) ships with support for adding error messages for different
+locales and thus, supports \f[B]LC_MESSAGS\f[R].
+.SH SEE ALSO
+.PP
+bc(1)
+.SH STANDARDS
+.PP
+The dc(1) utility operators are compliant with the operators in the
+bc(1) IEEE Std 1003.1-2017
+(\[lq]POSIX.1-2017\[rq]) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
+specification.
+.SH BUGS
+.PP
+None are known.
+Report bugs at https://git.yzena.com/gavin/bc.
+.SH AUTHOR
+.PP
+Gavin D.
+Howard <gavin@yzena.com> and contributors.
diff --git a/contrib/bc/manuals/dc/P.1.md b/contrib/bc/manuals/dc/P.1.md
new file mode 100644
index 000000000000..65771f6c73e1
--- /dev/null
+++ b/contrib/bc/manuals/dc/P.1.md
@@ -0,0 +1,1190 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2020 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.
+
+-->
+
+# Name
+
+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*...]
+
+# DESCRIPTION
+
+dc(1) is an arbitrary-precision calculator. It uses a stack (reverse Polish
+notation) to store numbers and results of computations. Arithmetic operations
+pop arguments off of the stack and push the results.
+
+If no files are given on the command-line as extra arguments (i.e., not as
+**-f** or **--file** arguments), then dc(1) reads from **stdin**. Otherwise,
+those files are processed, and dc(1) will then exit.
+
+This is different from the dc(1) on OpenBSD and possibly other dc(1)
+implementations, where **-e** (**--expression**) and **-f** (**--file**)
+arguments cause dc(1) to execute them and exit. The reason for this is that this
+dc(1) allows users to set arguments in the environment variable **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). Any expressions given on the
+command-line should be used to set up a standard environment. For example, if a
+user wants the **scale** always set to **10**, they can set **DC_ENV_ARGS** to
+**-e 10k**, and this dc(1) will always start with a **scale** of **10**.
+
+If users want to have dc(1) exit after processing all input from **-e** and
+**-f** arguments (and their equivalents), then they can just simply add **-e q**
+as the last command-line argument or define the environment variable
+**DC_EXPR_EXIT**.
+
+# OPTIONS
+
+The following are the options that dc(1) accepts.
+
+**-h**, **--help**
+
+: Prints a usage message and quits.
+
+**-v**, **-V**, **--version**
+
+: Print the version information (copyright header) and exit.
+
+**-i**, **--interactive**
+
+: Forces interactive mode. (See the **INTERACTIVE MODE** section.)
+
+ This is a **non-portable extension**.
+
+**-P**, **--no-prompt**
+
+: This option is a no-op.
+
+ This is a **non-portable extension**.
+
+**-x** **--extended-register**
+
+: Enables extended register mode. See the *Extended Register Mode* subsection
+ of the **REGISTERS** section for more information.
+
+ This is a **non-portable extension**.
+
+**-e** *expr*, **--expression**=*expr*
+
+: Evaluates *expr*. 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.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+
+ This is a **non-portable extension**.
+
+**-f** *file*, **--file**=*file*
+
+: Reads in *file* and evaluates it, line by line, as though it were read
+ through **stdin**. If expressions are also given (see above), the
+ expressions are evaluated in the order given.
+
+ After processing all expressions and files, dc(1) will exit, unless **-**
+ (**stdin**) was given as an argument at least once to **-f** or **--file**.
+ However, if any other **-e**, **--expression**, **-f**, or **--file**
+ arguments are given after that, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDOUT
+
+Any non-error output is written to **stdout**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stdout**, so if
+**stdout** is closed, as in **dc <file> >&-**, it will quit with an error. This
+is done so that dc(1) can report problems when **stdout** is redirected to a
+file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stdout** to
+**/dev/null**.
+
+# STDERR
+
+Any error output is written to **stderr**.
+
+**Note**: Unlike other dc(1) implementations, this dc(1) will issue a fatal
+error (see the **EXIT STATUS** section) if it cannot write to **stderr**, so if
+**stderr** is closed, as in **dc <file> 2>&-**, it will quit with an error. This
+is done so that dc(1) can exit with an error code when **stderr** is redirected
+to a file.
+
+If there are scripts that depend on the behavior of other dc(1) implementations,
+it is recommended that those scripts be changed to redirect **stderr** to
+**/dev/null**.
+
+# SYNTAX
+
+Each item in the input source code, either a number (see the **NUMBERS**
+section) or a command (see the **COMMANDS** section), is processed and executed,
+in order. Input is processed immediately when entered.
+
+**ibase** is a register (see the **REGISTERS** section) that determines how to
+interpret constant numbers. It is the "input" base, or the number base used for
+interpreting input numbers. **ibase** is initially **10**. The max allowable
+value for **ibase** is **16**. The min allowable value for **ibase** is **2**.
+The max allowable value for **ibase** can be queried in dc(1) programs with the
+**T** command.
+
+**obase** is a register (see the **REGISTERS** section) that determines how to
+output results. It is the "output" base, or the number base used for outputting
+numbers. **obase** is initially **10**. The max allowable value for **obase** is
+**DC_BASE_MAX** and can be queried with the **U** command. The min allowable
+value for **obase** is **0**. If **obase** is **0**, values are output in
+scientific notation, and if **obase** is **1**, values are output in engineering
+notation. Otherwise, values are output in the specified base.
+
+Outputting in scientific and engineering notations are **non-portable
+extensions**.
+
+The *scale* of an expression is the number of digits in the result of the
+expression right of the decimal point, and **scale** is a register (see the
+**REGISTERS** section) that sets the precision of any operations (with
+exceptions). **scale** is initially **0**. **scale** cannot be negative. The max
+allowable value for **scale** can be queried in dc(1) programs with the **V**
+command.
+
+**seed** is a register containing the current seed for the pseudo-random number
+generator. If the current value of **seed** is queried and stored, then if it is
+assigned to **seed** later, the pseudo-random number generator is guaranteed to
+produce the same sequence of pseudo-random numbers that were generated after the
+value of **seed** was first queried.
+
+Multiple values assigned to **seed** can produce the same sequence of
+pseudo-random numbers. Likewise, when a value is assigned to **seed**, it is not
+guaranteed that querying **seed** immediately after will return the same value.
+In addition, the value of **seed** will change after any call to the **'**
+command or the **"** command that does not get receive a value of **0** or
+**1**. The maximum integer returned by the **'** command can be queried with the
+**W** command.
+
+**Note**: The values returned by the pseudo-random number generator with the
+**'** and **"** commands are guaranteed to **NOT** be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator. However,
+they **are** guaranteed to be reproducible with identical **seed** values.
+
+The pseudo-random number generator, **seed**, and all associated operations are
+**non-portable extensions**.
+
+## Comments
+
+Comments go from **#** until, and not including, the next newline. This is a
+**non-portable extension**.
+
+# NUMBERS
+
+Numbers are strings made up of digits, uppercase letters up to **F**, and at
+most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits.
+Uppercase letters are equal to **9** + their position in the alphabet (i.e.,
+**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the
+current value of **ibase**, they are set to the value of the highest valid digit
+in **ibase**.
+
+Single-character numbers (i.e., **A** alone) take the value that they would have
+if they were valid digits, regardless of the value of **ibase**. This means that
+**A** alone always equals decimal **10** and **F** alone always equals decimal
+**15**.
+
+In addition, dc(1) accepts numbers in scientific notation. These have the form
+**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
+an integer. An example is **1.89237e9**, which is equal to **1892370000**.
+Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
+
+**WARNING**: Both the number and the exponent in scientific notation are
+interpreted according to the current **ibase**, but the number is still
+multiplied by **10\^exponent** regardless of the current **ibase**. For example,
+if **ibase** is **16** and dc(1) is given the number string **FFeA**, the
+resulting decimal number will be **2550000000000**, and if dc(1) is given the
+number string **10e_4**, the resulting decimal number will be **0.0016**.
+
+Accepting input as scientific notation is a **non-portable extension**.
+
+# COMMANDS
+
+The valid commands are listed below.
+
+## Printing
+
+These commands are used for printing.
+
+Note that both scientific notation and engineering notation are available for
+printing numbers. Scientific notation is activated by assigning **0** to
+**obase** using **0o**, and engineering notation is activated by assigning **1**
+to **obase** using **1o**. To deactivate them, just assign a different value to
+**obase**.
+
+Printing numbers in scientific notation and/or engineering notation is a
+**non-portable extension**.
+
+**p**
+
+: Prints the value on top of the stack, whether number or string, and prints a
+ newline after.
+
+ This does not alter the stack.
+
+**n**
+
+: Prints the value on top of the stack, whether number or string, and pops it
+ off of the stack.
+
+**P**
+
+: Pops a value off the stack.
+
+ If the value is a number, it is truncated and the absolute value of the
+ 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**
+
+: Prints the entire contents of the stack, in order from newest to oldest,
+ without altering anything.
+
+ Users should use this command when they get lost.
+
+## Arithmetic
+
+These are the commands used for arithmetic.
+
+**+**
+
+: The top two values are popped off the stack, added, and the result is pushed
+ onto the stack. The *scale* of the result is equal to the max *scale* of
+ both operands.
+
+**-**
+
+: The top two values are popped off the stack, subtracted, and the result is
+ pushed onto the stack. The *scale* of the result is equal to the max
+ *scale* of both operands.
+
+**\***
+
+: The top two values are popped off the stack, multiplied, and the result is
+ pushed onto the stack. If **a** is the *scale* of the first expression and
+ **b** is the *scale* of the second expression, the *scale* of the result
+ is equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return
+ the obvious values.
+
+**/**
+
+: The top two values are popped off the stack, divided, and the result is
+ pushed onto the stack. The *scale* of the result is equal to **scale**.
+
+ The first value popped off of the stack must be non-zero.
+
+**%**
+
+: The top two values are popped off the stack, remaindered, and the result is
+ pushed onto the stack.
+
+ Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and
+ 2) Using the result of step 1 to calculate **a-(a/b)\*b** to *scale*
+ **max(scale+scale(b),scale(a))**.
+
+ The first value popped off of the stack must be non-zero.
+
+**~**
+
+: 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 **x y / x y %** except that **x** and **y** are only
+ evaluated once.
+
+ The first value popped off of the stack must be non-zero.
+
+ This is a **non-portable extension**.
+
+**\^**
+
+: 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 *scale* of
+ the result is equal to **scale**.
+
+ The first value popped off of the stack must be an integer, and if that
+ value is negative, the second value popped off of the stack must be
+ non-zero.
+
+**v**
+
+: The top value is popped off the stack, its square root is computed, and the
+ result is pushed onto the stack. The *scale* of the result is equal to
+ **scale**.
+
+ The value popped off of the stack must be non-negative.
+
+**\_**
+
+: If this command *immediately* precedes a number (i.e., no spaces or other
+ commands), then that number is input as a negative number.
+
+ 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**.
+
+**b**
+
+: 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.
+
+ This is a **non-portable extension**.
+
+**|**
+
+: The top three values are popped off the stack, a modular exponentiation is
+ computed, and the result is pushed onto the stack.
+
+ 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.
+
+ This is a **non-portable extension**.
+
+**\$**
+
+: The top value is popped off the stack and copied, and the copy is truncated
+ and pushed onto the stack.
+
+ This is a **non-portable extension**.
+
+**\@**
+
+: 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.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**H**
+
+: The top two values are popped off the stack, and the second is shifted left
+ (radix shifted right) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**h**
+
+: The top two values are popped off the stack, and the second is shifted right
+ (radix shifted left) to the value of the first.
+
+ The first value popped off of the stack must be an integer and non-negative.
+
+ This is a **non-portable extension**.
+
+**G**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if they are equal, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**N**
+
+: The top value is popped off of the stack, and if it a **0**, a **1** is
+ pushed; otherwise, a **0** is pushed.
+
+ This is a **non-portable extension**.
+
+**(**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**{**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is less than or equal to the second, or **0**
+ otherwise.
+
+ This is a **non-portable extension**.
+
+**)**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than the second, or **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**}**
+
+: The top two values are popped off of the stack, they are compared, and a
+ **1** is pushed if the first is greater than or equal to the second, or
+ **0** otherwise.
+
+ This is a **non-portable extension**.
+
+**M**
+
+: The top two values are popped off of the stack. If they are both non-zero, a
+ **1** is pushed onto the stack. If either of them is zero, or both of them
+ are, then a **0** is pushed onto the stack.
+
+ This is like the **&&** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+**m**
+
+: The top two values are popped off of the stack. If at least one of them is
+ non-zero, a **1** is pushed onto the stack. If both of them are zero, then a
+ **0** is pushed onto the stack.
+
+ This is like the **||** operator in bc(1), and it is *not* a short-circuit
+ operator.
+
+ This is a **non-portable extension**.
+
+## Pseudo-Random Number Generator
+
+dc(1) has a built-in pseudo-random number generator. These commands query the
+pseudo-random number generator. (See Parameters for more information about the
+**seed** value that controls the pseudo-random number generator.)
+
+The pseudo-random number generator is guaranteed to **NOT** be
+cryptographically secure.
+
+**'**
+
+: Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the
+ **LIMITS** section).
+
+ 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**.
+
+**"**
+
+: Pops a value off of the stack, which is used as an **exclusive** 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 **RESET**
+ section) while **seed** remains unchanged. If the bound is larger than
+ **DC_RAND_MAX**, the higher bound is honored by generating several
+ pseudo-random integers, multiplying them by appropriate powers of
+ **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that
+ can be generated with this command is unbounded. Using this command will
+ change the value of **seed**, unless the operand is **0** or **1**. In that
+ case, **0** is pushed onto the stack, and **seed** is *not* changed.
+
+ 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**.
+
+## Stack Control
+
+These commands control the stack.
+
+**c**
+
+: Removes all items from ("clears") the stack.
+
+**d**
+
+: Copies the item on top of the stack ("duplicates") and pushes the copy onto
+ the stack.
+
+**r**
+
+: Swaps ("reverses") the two top items on the stack.
+
+**R**
+
+: Pops ("removes") the top value from the stack.
+
+## Register Control
+
+These commands control registers (see the **REGISTERS** section).
+
+**s***r*
+
+: Pops the value off the top of the stack and stores it into register *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*
+
+: 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*
+
+: 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.
+
+## Parameters
+
+These commands control the values of **ibase**, **obase**, **scale**, and
+**seed**. Also see the **SYNTAX** section.
+
+**i**
+
+: Pops the value off of the top of the stack and uses it to set **ibase**,
+ which must be between **2** and **16**, inclusive.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**o**
+
+: Pops the value off of the top of the stack and uses it to set **obase**,
+ which must be between **0** and **DC_BASE_MAX**, inclusive (see the
+ **LIMITS** section and the **NUMBERS** section).
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**k**
+
+: Pops the value off of the top of the stack and uses it to set **scale**,
+ which must be non-negative.
+
+ If the value on top of the stack has any *scale*, the *scale* is ignored.
+
+**j**
+
+: Pops the value off of the top of the stack and uses it to set **seed**. The
+ meaning of **seed** is dependent on the current pseudo-random number
+ generator but is guaranteed to not change except for new major versions.
+
+ 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**.
+
+**I**
+
+: Pushes the current value of **ibase** onto the main stack.
+
+**O**
+
+: Pushes the current value of **obase** onto the main stack.
+
+**K**
+
+: Pushes the current value of **scale** onto the main stack.
+
+**J**
+
+: Pushes the current value of **seed** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**T**
+
+: Pushes the maximum allowable value of **ibase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**U**
+
+: Pushes the maximum allowable value of **obase** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**V**
+
+: Pushes the maximum allowable value of **scale** onto the main stack.
+
+ This is a **non-portable extension**.
+
+**W**
+
+: Pushes the maximum (inclusive) integer that can be generated with the **'**
+ pseudo-random number generator command.
+
+ This is a **non-portable extension**.
+
+## Strings
+
+The following commands control strings.
+
+dc(1) can work with both numbers and strings, and registers (see the
+**REGISTERS** section) can hold both strings and numbers. dc(1) always knows
+whether the contents of a register are a string or a number.
+
+While arithmetic operations have to have numbers, and will print an error if
+given a string, other commands accept strings.
+
+Strings can also be executed as macros. For example, if the string **[1pR]** is
+executed as a macro, then the code **1pR** is executed, meaning that the **1**
+will be printed with a newline after and then popped from the stack.
+
+**\[**_characters_**\]**
+
+: Makes a string containing *characters* and pushes it onto the stack.
+
+ If there are brackets (**\[** and **\]**) in the string, then they must be
+ balanced. Unbalanced brackets can be escaped using a backslash (**\\**)
+ character.
+
+ 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.
+
+**a**
+
+: The value on top of the stack is popped.
+
+ 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**.
+
+**x**
+
+: Pops a value off of the top of the stack.
+
+ If it is a number, it is pushed back onto the stack.
+
+ If it is a string, it is executed as a macro.
+
+ This behavior is the norm whenever a macro is executed, whether by this
+ command or by the conditional execution commands below.
+
+**\>***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
+ *r* are executed.
+
+ 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).
+
+**>***r***e***s*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\>***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**\<***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!\<***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
+ the contents of register *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**=***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*
+ are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**!=***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
+ *r* are executed.
+
+ 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*
+
+: Like the above, but will execute register *s* if the comparison fails.
+
+ 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**.
+
+**?**
+
+: Reads a line from the **stdin** and executes it. This is to allow macros to
+ request input from users.
+
+**q**
+
+: 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.
+
+**Q**
+
+: 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.
+
+## Status
+
+These commands query status of the stack or its top value.
+
+**Z**
+
+: Pops a value off of the stack.
+
+ 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.
+
+**X**
+
+: Pops a value off of the stack.
+
+ If it is a number, pushes the *scale* of the value onto the stack.
+
+ If it is a string, pushes **0**.
+
+**z**
+
+: Pushes the current stack depth (before execution of this command).
+
+## Arrays
+
+These commands manipulate arrays.
+
+**:***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*
+
+: 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.
+
+# REGISTERS
+
+Registers are names that can store strings, numbers, and arrays. (Number/string
+registers do not interfere with array registers.)
+
+Each register is also its own stack, so the current register value is the top of
+the stack for the register. All registers, when first referenced, have one value
+(**0**) in their stack.
+
+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
+(**'\\n'**); it is a parse error for a newline to be used as a register name.
+
+## Extended Register Mode
+
+Unlike most other dc(1) implentations, this dc(1) provides nearly unlimited
+amounts of registers, if extended register mode is enabled.
+
+If extended register mode is enabled (**-x** or **--extended-register**
+command-line arguments are given), then normal single character registers are
+used *unless* the character immediately following a command that needs a
+register name is a space (according to **isspace()**) and not a newline
+(**'\\n'**).
+
+In that case, the register name is found according to the regex
+**\[a-z\]\[a-z0-9\_\]\*** (like bc(1) identifiers), and it is a parse error if
+the next non-space characters do not match that regex.
+
+# RESET
+
+When dc(1) encounters an error or a signal that it has a non-default handler
+for, it resets. This means that several things happen.
+
+First, any macros that are executing are stopped and popped off the stack.
+The behavior is not unlike that of exceptions in programming languages. Then
+the execution point is set so that any code waiting to execute (after all
+macros returned) is skipped.
+
+Thus, when dc(1) resets, it skips any remaining code waiting to be executed.
+Then, if it is interactive mode, and the error was not a fatal error (see the
+**EXIT STATUS** section), it asks for more input; otherwise, it exits with the
+appropriate return code.
+
+# PERFORMANCE
+
+Most dc(1) implementations use **char** types to calculate the value of **1**
+decimal digit at a time, but that can be slow. This dc(1) does something
+different.
+
+It uses large integers to calculate more than **1** decimal digit at a time. If
+built in a environment where **DC_LONG_BIT** (see the **LIMITS** section) is
+**64**, then each integer has **9** decimal digits. If built in an environment
+where **DC_LONG_BIT** is **32** then each integer has **4** decimal digits. This
+value (the number of decimal digits per large integer) is called
+**DC_BASE_DIGS**.
+
+In addition, this dc(1) uses an even larger integer for overflow checking. This
+integer type depends on the value of **DC_LONG_BIT**, but is always at least
+twice as large as the integer type used to store digits.
+
+# LIMITS
+
+The following are the limits on dc(1):
+
+**DC_LONG_BIT**
+
+: The number of bits in the **long** 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 **PERFORMANCE** section).
+
+**DC_BASE_DIGS**
+
+: The number of decimal digits per large integer (see the **PERFORMANCE**
+ section). Depends on **DC_LONG_BIT**.
+
+**DC_BASE_POW**
+
+: The max decimal number that each large integer can store (see
+ **DC_BASE_DIGS**) plus **1**. Depends on **DC_BASE_DIGS**.
+
+**DC_OVERFLOW_MAX**
+
+: The max number that the overflow type (see the **PERFORMANCE** section) can
+ hold. Depends on **DC_LONG_BIT**.
+
+**DC_BASE_MAX**
+
+: The maximum output base. Set at **DC_BASE_POW**.
+
+**DC_DIM_MAX**
+
+: The maximum size of arrays. Set at **SIZE_MAX-1**.
+
+**DC_SCALE_MAX**
+
+: The maximum **scale**. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_STRING_MAX**
+
+: The maximum length of strings. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NAME_MAX**
+
+: The maximum length of identifiers. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_NUM_MAX**
+
+: The maximum length of a number (in decimal digits), which includes digits
+ after the decimal point. Set at **DC_OVERFLOW_MAX-1**.
+
+**DC_RAND_MAX**
+
+: The maximum integer (inclusive) returned by the **'** command, if dc(1). Set
+ at **2\^DC_LONG_BIT-1**.
+
+Exponent
+
+: The maximum allowable exponent (positive or negative). Set at
+ **DC_OVERFLOW_MAX**.
+
+Number of vars
+
+: The maximum number of vars/arrays. Set at **SIZE_MAX-1**.
+
+These limits are meant to be effectively non-existent; the limits are so large
+(at least on 64-bit machines) that there should not be any point at which they
+become a problem. In fact, memory should be exhausted before these limits should
+be hit.
+
+# ENVIRONMENT VARIABLES
+
+dc(1) recognizes the following environment variables:
+
+**DC_ENV_ARGS**
+
+: 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 **DC_ENV_ARGS** will be processed
+ before arguments and files given on the command-line. This gives the user
+ the ability to set up "standard" 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 **-e** option to set **scale** to a value other than **0**.
+
+ The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments,
+ but it does not understand escape sequences. For example, the string
+ **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string
+ **"/home/gavin/some \"dc\" file.dc"** will include the backslashes.
+
+ The quote parsing will handle either kind of quotes, **'** or **"**. 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 **"some 'bc' file.bc"**, 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.
+
+**DC_LINE_LENGTH**
+
+: If this environment variable exists and contains an integer that is greater
+ than **1** and is less than **UINT16_MAX** (**2\^16-1**), dc(1) will output
+ lines to that length, including the backslash newline combo. The default
+ line length is **70**.
+
+**DC_EXPR_EXIT**
+
+: If this variable exists (no matter the contents), dc(1) will exit
+ immediately after executing expressions and files given by the **-e** and/or
+ **-f** command-line options (and any equivalents).
+
+# EXIT STATUS
+
+dc(1) returns the following exit statuses:
+
+**0**
+
+: No error.
+
+**1**
+
+: A math error occurred. This follows standard practice of using **1** for
+ expected errors, since math errors will happen in the process of normal
+ execution.
+
+ 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
+ (**\^**), places (**\@**), left shift (**H**), and right shift (**h**)
+ operators.
+
+**2**
+
+: A parse error occurred.
+
+ 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.
+
+**3**
+
+: A runtime error occurred.
+
+ 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.
+
+**4**
+
+: A fatal error occurred.
+
+ 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.
+
+The exit status **4** is special; when a fatal error occurs, dc(1) always exits
+and returns **4**, no matter what mode dc(1) is in.
+
+The other statuses will only be returned when dc(1) is not in interactive mode
+(see the **INTERACTIVE MODE** section), since dc(1) resets its state (see the
+**RESET** section) and accepts more input when one of those errors occurs in
+interactive mode. This is also the case when interactive mode is forced by the
+**-i** flag or **--interactive** option.
+
+These exit statuses allow dc(1) to be used in shell scripting with error
+checking, and its normal behavior can be forced by using the **-i** flag or
+**--interactive** option.
+
+# INTERACTIVE MODE
+
+Like bc(1), dc(1) has an interactive mode and a non-interactive mode.
+Interactive mode is turned on automatically when both **stdin** and **stdout**
+are hooked to a terminal, but the **-i** flag and **--interactive** option can
+turn it on in other cases.
+
+In interactive mode, dc(1) attempts to recover from errors (see the **RESET**
+section), and in normal execution, flushes **stdout** as soon as execution is
+done for the current input.
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, dc(1) turns
+on "TTY mode."
+
+TTY mode is required for history to be enabled (see the **COMMAND LINE HISTORY**
+section). It is also required to enable special handling for **SIGINT** signals.
+
+TTY mode is different from interactive mode because interactive mode is required
+in the [bc(1) specification][1], and interactive mode requires only **stdin**
+and **stdout** to be connected to a terminal.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to stop execution of the current input. If
+dc(1) is in TTY mode (see the **TTY MODE** section), it will reset (see the
+**RESET** section). Otherwise, it will clean up and exit.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in TTY mode, it will ask for more input. If dc(1) is
+processing input from a file in TTY mode, it will stop processing the file and
+start processing the next file, if one exists, or ask for input from **stdin**
+if no other file exists.
+
+This means that if a **SIGINT** is sent to dc(1) as it is executing a file, it
+can seem as though dc(1) did not respond to the signal since it will immediately
+start executing the next file. This is by design; most files that users execute
+when interacting with dc(1) have function definitions, which are quick to parse.
+If a file takes a long time to execute, there may be a bug in that file. The
+rest of the files could still be executed without problem, allowing the user to
+continue.
+
+**SIGTERM** and **SIGQUIT** cause dc(1) to clean up and exit, and it uses the
+default handler for all other signals. The one exception is **SIGHUP**; in that
+case, when dc(1) is in TTY mode, a **SIGHUP** will cause dc(1) to clean up and
+exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing. If dc(1) is in TTY mode (see
+the **TTY MODE** section), history is enabled. Previous lines can be recalled
+and edited with the arrow keys.
+
+**Note**: tabs are converted to 8 spaces.
+
+# LOCALES
+
+This dc(1) ships with support for adding error messages for different locales
+and thus, supports **LC_MESSAGS**.
+
+# SEE ALSO
+
+bc(1)
+
+# STANDARDS
+
+The dc(1) utility operators are compliant with the operators in the bc(1)
+[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification.
+
+# BUGS
+
+None are known. Report bugs at https://git.yzena.com/gavin/bc.
+
+# AUTHOR
+
+Gavin D. Howard <gavin@yzena.com> and contributors.
+
+[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
diff --git a/contrib/bc/manuals/header.txt b/contrib/bc/manuals/header.txt
new file mode 100644
index 000000000000..071157ebd135
--- /dev/null
+++ b/contrib/bc/manuals/header.txt
@@ -0,0 +1,27 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2020 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.
+.\"
diff --git a/contrib/bc/manuals/header_bc.txt b/contrib/bc/manuals/header_bc.txt
new file mode 100644
index 000000000000..fa1a54f85693
--- /dev/null
+++ b/contrib/bc/manuals/header_bc.txt
@@ -0,0 +1 @@
+.TH "BC" "1" "October 2020" "Gavin D. Howard" "General Commands Manual"
diff --git a/contrib/bc/manuals/header_bcl.txt b/contrib/bc/manuals/header_bcl.txt
new file mode 100644
index 000000000000..ba9338aadad9
--- /dev/null
+++ b/contrib/bc/manuals/header_bcl.txt
@@ -0,0 +1 @@
+.TH "BCL" "3" "October 2020" "Gavin D. Howard" "Libraries Manual"
diff --git a/contrib/bc/manuals/header_dc.txt b/contrib/bc/manuals/header_dc.txt
new file mode 100644
index 000000000000..b0e8b204f4ee
--- /dev/null
+++ b/contrib/bc/manuals/header_dc.txt
@@ -0,0 +1 @@
+.TH "DC" "1" "October 2020" "Gavin D. Howard" "General Commands Manual"
diff --git a/contrib/bc/release.sh b/contrib/bc/release.sh
new file mode 100755
index 000000000000..2cb39f6b38c5
--- /dev/null
+++ b/contrib/bc/release.sh
@@ -0,0 +1,582 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+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'
+ exit 1
+}
+
+header() {
+
+ _header_msg="$1"
+ shift
+
+ printf '\n'
+ printf '*******************\n'
+ printf "$_header_msg"
+ printf '\n'
+ printf '*******************\n'
+ printf '\n'
+}
+
+do_make() {
+ make -j4 "$@"
+}
+
+configure() {
+
+ _configure_CFLAGS="$1"
+ shift
+
+ _configure_CC="$1"
+ shift
+
+ _configure_configure_flags="$1"
+ shift
+
+ _configure_GEN_HOST="$1"
+ shift
+
+ _configure_LONG_BIT="$1"
+ shift
+
+ if [ "$gen_tests" -eq 0 ]; then
+ _configure_configure_flags="-G $_configure_configure_flags"
+ fi
+
+ if [ "$_configure_CC" = "clang" ]; then
+ _configure_CFLAGS="$clang_flags $_configure_CFLAGS"
+ elif [ "$_configure_CC" = "gcc" ]; then
+ _configure_CFLAGS="$gcc_flags $_configure_CFLAGS"
+ fi
+
+ _configure_header=$(printf 'Running ./configure.sh %s ...' "$_configure_configure_flags")
+ _configure_header=$(printf "$_configure_header\n CC=\"%s\"\n" "$_configure_CC")
+ _configure_header=$(printf "$_configure_header\n CFLAGS=\"%s\"\n" "$_configure_CFLAGS")
+ _configure_header=$(printf "$_configure_header\n LONG_BIT=%s" "$_configure_LONG_BIT")
+ _configure_header=$(printf "$_configure_header\n GEN_HOST=%s" "$_configure_GEN_HOST")
+
+ header "$_configure_header"
+ CFLAGS="$_configure_CFLAGS" CC="$_configure_CC" GEN_HOST="$_configure_GEN_HOST" \
+ LONG_BIT="$_configure_LONG_BIT" ./configure.sh $_configure_configure_flags > /dev/null
+}
+
+build() {
+
+ _build_CFLAGS="$1"
+ shift
+
+ _build_CC="$1"
+ shift
+
+ _build_configure_flags="$1"
+ shift
+
+ _build_GEN_HOST="$1"
+ shift
+
+ _build_LONG_BIT="$1"
+ shift
+
+ configure "$_build_CFLAGS" "$_build_CC" "$_build_configure_flags" "$_build_GEN_HOST" "$_build_LONG_BIT"
+
+ _build_header=$(printf 'Building...\n CC=%s' "$_build_CC")
+ _build_header=$(printf "$_build_header\n CFLAGS=\"%s\"" "$_build_CFLAGS")
+ _build_header=$(printf "$_build_header\n LONG_BIT=%s" "$_build_LONG_BIT")
+ _build_header=$(printf "$_build_header\n GEN_HOST=%s" "$_build_GEN_HOST")
+
+ header "$_build_header"
+
+ do_make > /dev/null 2> "$scriptdir/.test.txt"
+
+ if [ -s "$scriptdir/.test.txt" ]; then
+ printf '%s generated warning(s):\n' "$_build_CC"
+ printf '\n'
+ cat "$scriptdir/.test.txt"
+ exit 1
+ fi
+}
+
+runtest() {
+
+ header "Running tests"
+
+ if [ "$#" -gt 0 ]; then
+ do_make "$@"
+ else
+ do_make test
+ fi
+}
+
+runconfigtests() {
+
+ _runconfigtests_CFLAGS="$1"
+ shift
+
+ _runconfigtests_CC="$1"
+ shift
+
+ _runconfigtests_configure_flags="$1"
+ shift
+
+ _runconfigtests_GEN_HOST="$1"
+ shift
+
+ _runconfigtests_LONG_BIT="$1"
+ shift
+
+ _runconfigtests_run_tests="$1"
+ shift
+
+ if [ "$_runconfigtests_run_tests" -ne 0 ]; then
+ _runconfigtests_header=$(printf 'Running tests with configure flags')
+ else
+ _runconfigtests_header=$(printf 'Building with configure flags')
+ fi
+
+ _runconfigtests_header=$(printf "$_runconfigtests_header \"%s\" ...\n" "$_runconfigtests_configure_flags")
+ _runconfigtests_header=$(printf "$_runconfigtests_header\n CC=%s\n" "$_runconfigseries_CC")
+ _runconfigtests_header=$(printf "$_runconfigtests_header\n CFLAGS=\"%s\"" "$_runconfigseries_CFLAGS")
+ _runconfigtests_header=$(printf "$_runconfigtests_header\n LONG_BIT=%s" "$_runconfigtests_LONG_BIT")
+ _runconfigtests_header=$(printf "$_runconfigtests_header\n GEN_HOST=%s" "$_runconfigtests_GEN_HOST")
+
+ header "$_runconfigtests_header"
+
+ build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \
+ "$_runconfigtests_configure_flags" "$_runconfigtests_GEN_HOST" \
+ "$_runconfigtests_LONG_BIT"
+
+ if [ "$_runconfigtests_run_tests" -ne 0 ]; then
+ runtest
+ fi
+
+ do_make clean
+
+ build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \
+ "$_runconfigtests_configure_flags -b" "$_runconfigtests_GEN_HOST" \
+ "$_runconfigtests_LONG_BIT"
+
+ if [ "$_runconfigtests_run_tests" -ne 0 ]; then
+ runtest
+ fi
+
+ do_make clean
+
+ build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \
+ "$_runconfigtests_configure_flags -d" "$_runconfigtests_GEN_HOST" \
+ "$_runconfigtests_LONG_BIT"
+
+ if [ "$_runconfigtests_run_tests" -ne 0 ]; then
+ runtest
+ fi
+
+ do_make clean
+}
+
+runconfigseries() {
+
+ _runconfigseries_CFLAGS="$1"
+ shift
+
+ _runconfigseries_CC="$1"
+ shift
+
+ _runconfigseries_configure_flags="$1"
+ shift
+
+ _runconfigseries_run_tests="$1"
+ shift
+
+ if [ "$run_64_bit" -ne 0 ]; then
+
+ runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
+ "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests"
+
+ if [ "$run_gen_script" -ne 0 ]; then
+ runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
+ "$_runconfigseries_configure_flags" 0 64 "$_runconfigseries_run_tests"
+ fi
+
+ runconfigtests "$_runconfigseries_CFLAGS -DBC_RAND_BUILTIN=0" "$_runconfigseries_CC" \
+ "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests"
+
+ fi
+
+ runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
+ "$_runconfigseries_configure_flags" 1 32 "$_runconfigseries_run_tests"
+
+ if [ "$run_gen_script" -ne 0 ]; then
+ runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \
+ "$_runconfigseries_configure_flags" 0 32 "$_runconfigseries_run_tests"
+ fi
+}
+
+runtestseries() {
+
+ _runtestseries_CFLAGS="$1"
+ shift
+
+ _runtestseries_CC="$1"
+ shift
+
+ _runtestseries_configure_flags="$1"
+ shift
+
+ _runtestseries_run_tests="$1"
+ shift
+
+ _runtestseries_flags="E H N P EH EN EP HN HP NP EHN EHP ENP HNP EHNP"
+
+ runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \
+ "$_runtestseries_configure_flags" "$_runtestseries_run_tests"
+
+ for f in $_runtestseries_flags; do
+ runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \
+ "$_runtestseries_configure_flags -$f" "$_runtestseries_run_tests"
+ done
+}
+
+runlibtests() {
+
+ _runlibtests_CFLAGS="$1"
+ shift
+
+ _runlibtests_CC="$1"
+ shift
+
+ _runlibtests_configure_flags="$1"
+ shift
+
+ _runlibtests_run_tests="$1"
+ shift
+
+ _runlibtests_configure_flags="$_runlibtests_configure_flags -a"
+
+ build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 64
+
+ if [ "$_runlibtests_run_tests" -ne 0 ]; then
+ runtest
+ fi
+
+ build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 32
+
+ if [ "$_runlibtests_run_tests" -ne 0 ]; then
+ runtest
+ fi
+}
+
+runtests() {
+
+ _runtests_CFLAGS="$1"
+ shift
+
+ _runtests_CC="$1"
+ shift
+
+ _runtests_configure_flags="$1"
+ shift
+
+ _runtests_run_tests="$1"
+ 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"
+}
+
+karatsuba() {
+
+ header "Running Karatsuba tests"
+ do_make karatsuba_test
+}
+
+vg() {
+
+ header "Running valgrind"
+
+ if [ "$run_64_bit" -ne 0 ]; then
+ _vg_bits=64
+ else
+ _vg_bits=32
+ fi
+
+ build "$debug" "gcc" "-O0 -g" "1" "$_vg_bits"
+ runtest valgrind
+
+ do_make clean_config
+
+ build "$debug" "gcc" "-O0 -gb" "1" "$_vg_bits"
+ runtest valgrind
+
+ do_make clean_config
+
+ build "$debug" "gcc" "-O0 -gd" "1" "$_vg_bits"
+ runtest valgrind
+
+ do_make clean_config
+}
+
+debug() {
+
+ _debug_CC="$1"
+ shift
+
+ _debug_run_tests="$1"
+ shift
+
+ runtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests"
+
+ if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
+ runtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests"
+ fi
+
+ runlibtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests"
+
+ if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
+ runlibtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests"
+ fi
+}
+
+release() {
+
+ _release_CC="$1"
+ shift
+
+ _release_run_tests="$1"
+ shift
+
+ runtests "$release" "$_release_CC" "-O3" "$_release_run_tests"
+
+ runlibtests "$release" "$_release_CC" "-O3" "$_release_run_tests"
+}
+
+reldebug() {
+
+ _reldebug_CC="$1"
+ shift
+
+ _reldebug_run_tests="$1"
+ shift
+
+ runtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
+
+ if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
+ runtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
+ runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
+ fi
+
+ runlibtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
+
+ if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
+ runlibtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
+ runlibtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
+ fi
+}
+
+minsize() {
+
+ _minsize_CC="$1"
+ shift
+
+ _minsize_run_tests="$1"
+ shift
+
+ runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests"
+
+ runlibtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests"
+}
+
+build_set() {
+
+ _build_set_CC="$1"
+ shift
+
+ _build_set_run_tests="$1"
+ shift
+
+ debug "$_build_set_CC" "$_build_set_run_tests"
+ release "$_build_set_CC" "$_build_set_run_tests"
+ reldebug "$_build_set_CC" "$_build_set_run_tests"
+ minsize "$_build_set_CC" "$_build_set_run_tests"
+}
+
+clang_flags="-Weverything -Wno-padded -Wno-switch-enum -Wno-format-nonliteral"
+clang_flags="$clang_flags -Wno-cast-align -Wno-missing-noreturn -Wno-disabled-macro-expansion"
+clang_flags="$clang_flags -Wno-unreachable-code -Wno-unreachable-code-return"
+clang_flags="$clang_flags -Wno-implicit-fallthrough"
+gcc_flags="-Wno-maybe-uninitialized -Wno-clobbered"
+
+cflags="-Wall -Wextra -Werror -pedantic -Wno-conditional-uninitialized"
+
+debug="$cflags -fno-omit-frame-pointer"
+release="$cflags -DNDEBUG"
+
+set -e
+
+script="$0"
+scriptdir=$(dirname "$script")
+
+if [ "$#" -gt 0 ]; then
+ run_tests="$1"
+ shift
+else
+ run_tests=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ gen_tests="$1"
+ shift
+else
+ gen_tests=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ test_with_clang="$1"
+ shift
+else
+ test_with_clang=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ test_with_gcc="$1"
+ shift
+else
+ test_with_gcc=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ run_sanitizers="$1"
+ shift
+else
+ run_sanitizers=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ run_valgrind="$1"
+ shift
+else
+ run_valgrind=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ run_64_bit="$1"
+ shift
+else
+ run_64_bit=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ run_gen_script="$1"
+ shift
+else
+ run_gen_script=0
+fi
+
+if [ "$run_64_bit" -ne 0 ]; then
+ bits=64
+else
+ bits=32
+fi
+
+cd "$scriptdir"
+
+if [ "$test_with_clang" -ne 0 ]; then
+ defcc="clang"
+elif [ "$test_with_gcc" -ne 0 ]; then
+ defcc="gcc"
+else
+ defcc="c99"
+fi
+
+export ASAN_OPTIONS="abort_on_error=1"
+export UBSAN_OPTIONS="print_stack_trace=1,silence_unsigned_overflow=1"
+
+build "$debug" "$defcc" "-g" "1" "$bits"
+
+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
+ build_set "clang" "$run_tests"
+fi
+
+if [ "$test_with_gcc" -ne 0 ]; then
+ build_set "gcc" "$run_tests"
+fi
+
+if [ "$run_tests" -ne 0 ]; then
+
+ build "$release" "$defcc" "-O3" "1" "$bits"
+
+ karatsuba
+
+ if [ "$run_valgrind" -ne 0 -a "$test_with_gcc" -ne 0 ]; then
+ vg
+ fi
+
+ printf '\n'
+ printf 'Tests successful.\n'
+
+ set +e
+
+ command -v afl-gcc > /dev/null 2>&1
+ err="$?"
+
+ set -e
+
+ if [ "$err" -eq 0 ]; then
+
+ header "Configuring for afl-gcc..."
+
+ configure "$debug $gcc_flags -DBC_ENABLE_RAND=0" "afl-gcc" "-HNP -gO3" "1" "$bits"
+
+ printf '\n'
+ printf 'Run make\n'
+ printf '\n'
+ printf 'Then run %s/tests/randmath.py and the fuzzer.\n' "$scriptdir"
+ printf '\n'
+ printf 'Then run ASan on the fuzzer test cases with the following build:\n'
+ printf '\n'
+ printf ' CFLAGS="-fsanitize=address -fno-omit-frame-pointer -DBC_ENABLE_RAND=0" ./configure.sh -gO3 -HNPS\n'
+ printf ' make\n'
+ printf '\n'
+ printf 'Then run the GitHub release script as follows:\n'
+ printf '\n'
+ printf ' <github_release> %s release.sh RELEASE.md\\\n' "$version"
+ printf ' tests/afl.py tests/radamsa.sh tests/radamsa.txt tests/randmath.py \\\n'
+ printf ' tests/bc/scripts/timeconst.bc\n'
+
+ fi
+
+fi
diff --git a/contrib/bc/safe-install.sh b/contrib/bc/safe-install.sh
new file mode 100755
index 000000000000..041088386682
--- /dev/null
+++ b/contrib/bc/safe-install.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+#
+# Written by Rich Felker, originally as part of musl libc.
+# Multi-licensed under MIT, 0BSD, and CC0.
+#
+# This is an actually-safe install command which installs the new
+# file atomically in the new location, rather than overwriting
+# existing files.
+#
+
+usage() {
+printf "usage: %s [-D] [-l] [-m mode] src dest\n" "$0" 1>&2
+exit 1
+}
+
+mkdirp=
+symlink=
+mode=755
+
+while getopts Dlm: name ; do
+case "$name" in
+D) mkdirp=yes ;;
+l) symlink=yes ;;
+m) mode=$OPTARG ;;
+?) usage ;;
+esac
+done
+shift $(($OPTIND - 1))
+
+test "$#" -eq 2 || usage
+src=$1
+dst=$2
+tmp="$dst.tmp.$$"
+
+case "$dst" in
+*/) printf "%s: %s ends in /\n", "$0" "$dst" 1>&2 ; exit 1 ;;
+esac
+
+set -C
+set -e
+
+if test "$mkdirp" ; then
+umask 022
+case "$2" in
+*/*) mkdir -p "${dst%/*}" ;;
+esac
+fi
+
+trap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP
+
+umask 077
+
+if test "$symlink" ; then
+ln -s "$1" "$tmp"
+else
+cat < "$1" > "$tmp"
+chmod "$mode" "$tmp"
+fi
+
+mv -f "$tmp" "$2"
+test -d "$2" && {
+rm -f "$2/$tmp"
+printf "%s: %s is a directory\n" "$0" "$dst" 1>&2
+exit 1
+}
+
+exit 0
diff --git a/contrib/bc/src/args.c b/contrib/bc/src/args.c
new file mode 100644
index 000000000000..4c9ad3b95549
--- /dev/null
+++ b/contrib/bc/src/args.c
@@ -0,0 +1,219 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code for processing command-line arguments.
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+
+#include <vector.h>
+#include <read.h>
+#include <args.h>
+#include <opt.h>
+
+static const BcOptLong bc_args_lopt[] = {
+
+ { "expression", BC_OPT_REQUIRED, 'e' },
+ { "file", BC_OPT_REQUIRED, 'f' },
+ { "help", BC_OPT_NONE, 'h' },
+ { "interactive", BC_OPT_NONE, 'i' },
+ { "no-prompt", BC_OPT_NONE, 'P' },
+#if BC_ENABLED
+ { "global-stacks", BC_OPT_BC_ONLY, 'g' },
+ { "mathlib", BC_OPT_BC_ONLY, 'l' },
+ { "quiet", BC_OPT_BC_ONLY, 'q' },
+ { "standard", BC_OPT_BC_ONLY, 's' },
+ { "warn", BC_OPT_BC_ONLY, 'w' },
+#endif // BC_ENABLED
+ { "version", BC_OPT_NONE, 'v' },
+ { "version", BC_OPT_NONE, 'V' },
+#if DC_ENABLED
+ { "extended-register", BC_OPT_DC_ONLY, 'x' },
+#endif // DC_ENABLED
+ { NULL, 0, 0 },
+
+};
+
+static void bc_args_exprs(const char *str) {
+ BC_SIG_ASSERT_LOCKED;
+ if (vm.exprs.v == NULL) bc_vec_init(&vm.exprs, sizeof(uchar), NULL);
+ bc_vec_concat(&vm.exprs, str);
+ bc_vec_concat(&vm.exprs, "\n");
+}
+
+static void bc_args_file(const char *file) {
+
+ char *buf;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ vm.file = file;
+
+ bc_read_file(file, &buf);
+ bc_args_exprs(buf);
+ free(buf);
+}
+
+void bc_args(int argc, char *argv[]) {
+
+ int c;
+ size_t i;
+ bool do_exit = false, version = false;
+ BcOpt opts;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ bc_opt_init(&opts, argv);
+
+ while ((c = bc_opt_parse(&opts, bc_args_lopt)) != -1) {
+
+ switch (c) {
+
+ case 'e':
+ {
+ if (vm.no_exit_exprs)
+ bc_vm_verr(BC_ERR_FATAL_OPTION, "-e (--expression)");
+ bc_args_exprs(opts.optarg);
+ break;
+ }
+
+ case 'f':
+ {
+ if (!strcmp(opts.optarg, "-")) vm.no_exit_exprs = true;
+ else {
+ if (vm.no_exit_exprs)
+ bc_vm_verr(BC_ERR_FATAL_OPTION, "-f (--file)");
+ bc_args_file(opts.optarg);
+ }
+ break;
+ }
+
+ case 'h':
+ {
+ bc_vm_info(vm.help);
+ do_exit = true;
+ break;
+ }
+
+ case 'i':
+ {
+ vm.flags |= BC_FLAG_I;
+ break;
+ }
+
+ case 'P':
+ {
+ vm.flags |= BC_FLAG_P;
+ break;
+ }
+
+#if BC_ENABLED
+ case 'g':
+ {
+ assert(BC_IS_BC);
+ vm.flags |= BC_FLAG_G;
+ break;
+ }
+
+ case 'l':
+ {
+ assert(BC_IS_BC);
+ vm.flags |= BC_FLAG_L;
+ break;
+ }
+
+ case 'q':
+ {
+ assert(BC_IS_BC);
+ // Do nothing.
+ break;
+ }
+
+ case 's':
+ {
+ assert(BC_IS_BC);
+ vm.flags |= BC_FLAG_S;
+ break;
+ }
+
+ case 'w':
+ {
+ assert(BC_IS_BC);
+ vm.flags |= BC_FLAG_W;
+ break;
+ }
+#endif // BC_ENABLED
+
+ case 'V':
+ case 'v':
+ {
+ do_exit = version = true;
+ break;
+ }
+
+#if DC_ENABLED
+ case 'x':
+ {
+ assert(BC_IS_DC);
+ vm.flags |= DC_FLAG_X;
+ break;
+ }
+#endif // DC_ENABLED
+
+#ifndef NDEBUG
+ // We shouldn't get here because bc_opt_error()/bc_vm_error() should
+ // longjmp() out.
+ case '?':
+ case ':':
+ default:
+ {
+ abort();
+ }
+#endif // NDEBUG
+ }
+ }
+
+ if (version) bc_vm_info(NULL);
+ if (do_exit) exit((int) vm.status);
+
+ if (opts.optind < (size_t) argc && vm.files.v == NULL)
+ bc_vec_init(&vm.files, sizeof(char*), NULL);
+
+ for (i = opts.optind; i < (size_t) argc; ++i)
+ bc_vec_push(&vm.files, argv + i);
+}
diff --git a/contrib/bc/src/bc.c b/contrib/bc/src/bc.c
new file mode 100644
index 000000000000..cdf3cc9c3a28
--- /dev/null
+++ b/contrib/bc/src/bc.c
@@ -0,0 +1,56 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The main procedure of bc.
+ *
+ */
+
+#if BC_ENABLED
+
+#include <string.h>
+
+#include <bc.h>
+#include <vm.h>
+
+void bc_main(int argc, char **argv) {
+
+ vm.read_ret = BC_INST_RET;
+ vm.help = bc_help;
+ vm.sigmsg = bc_sig_msg;
+ vm.siglen = bc_sig_msg_len;
+
+ vm.next = bc_lex_token;
+ vm.parse = bc_parse_parse;
+ vm.expr = bc_parse_expr;
+
+ bc_vm_boot(argc, argv, "BC_LINE_LENGTH", "BC_ENV_ARGS");
+}
+#endif // BC_ENABLED
diff --git a/contrib/bc/src/bc_lex.c b/contrib/bc/src/bc_lex.c
new file mode 100644
index 000000000000..87475385fe70
--- /dev/null
+++ b/contrib/bc/src/bc_lex.c
@@ -0,0 +1,409 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The lexer for bc.
+ *
+ */
+
+#if BC_ENABLED
+
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <bc.h>
+#include <vm.h>
+
+static void bc_lex_identifier(BcLex *l) {
+
+ size_t i;
+ const char *buf = l->buf + l->i - 1;
+
+ for (i = 0; i < bc_lex_kws_len; ++i) {
+
+ const BcLexKeyword *kw = bc_lex_kws + i;
+ size_t n = BC_LEX_KW_LEN(kw);
+
+ if (!strncmp(buf, kw->name, n) && !isalnum(buf[n]) && buf[n] != '_') {
+
+ l->t = BC_LEX_KW_AUTO + (BcLexType) i;
+
+ if (!BC_LEX_KW_POSIX(kw))
+ bc_lex_verr(l, BC_ERR_POSIX_KW, kw->name);
+
+ // We minus 1 because the index has already been incremented.
+ l->i += n - 1;
+ return;
+ }
+ }
+
+ bc_lex_name(l);
+
+ if (BC_ERR(l->str.len - 1 > 1))
+ bc_lex_verr(l, BC_ERR_POSIX_NAME_LEN, l->str.v);
+}
+
+static void bc_lex_string(BcLex *l) {
+
+ size_t len, nlines = 0, i = l->i;
+ const char *buf = l->buf;
+ char c;
+
+ l->t = BC_LEX_STR;
+
+ for (; (c = buf[i]) && c != '"'; ++i) nlines += c == '\n';
+
+ if (BC_ERR(c == '\0')) {
+ l->i = i;
+ bc_lex_err(l, BC_ERR_PARSE_STRING);
+ }
+
+ len = i - l->i;
+ bc_vec_string(&l->str, len, l->buf + l->i);
+
+ l->i = i + 1;
+ l->line += nlines;
+}
+
+static void bc_lex_assign(BcLex *l, BcLexType with, BcLexType without) {
+ if (l->buf[l->i] == '=') {
+ l->i += 1;
+ l->t = with;
+ }
+ else l->t = without;
+}
+
+void bc_lex_token(BcLex *l) {
+
+ char c = l->buf[l->i++], c2;
+
+ // This is the workhorse of the lexer.
+ switch (c) {
+
+ case '\0':
+ case '\n':
+ case '\t':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ {
+ bc_lex_commonTokens(l, c);
+ break;
+ }
+
+ case '!':
+ {
+ bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT);
+
+ if (l->t == BC_LEX_OP_BOOL_NOT)
+ bc_lex_verr(l, BC_ERR_POSIX_BOOL, "!");
+
+ break;
+ }
+
+ case '"':
+ {
+ bc_lex_string(l);
+ break;
+ }
+
+ case '#':
+ {
+ bc_lex_err(l, BC_ERR_POSIX_COMMENT);
+ bc_lex_lineComment(l);
+ break;
+ }
+
+ case '%':
+ {
+ bc_lex_assign(l, BC_LEX_OP_ASSIGN_MODULUS, BC_LEX_OP_MODULUS);
+ break;
+ }
+
+ case '&':
+ {
+ c2 = l->buf[l->i];
+ if (BC_NO_ERR(c2 == '&')) {
+
+ bc_lex_verr(l, BC_ERR_POSIX_BOOL, "&&");
+
+ l->i += 1;
+ l->t = BC_LEX_OP_BOOL_AND;
+ }
+ else bc_lex_invalidChar(l, c);
+
+ break;
+ }
+#if BC_ENABLE_EXTRA_MATH
+ case '$':
+ {
+ l->t = BC_LEX_OP_TRUNC;
+ break;
+ }
+
+ case '@':
+ {
+ bc_lex_assign(l, BC_LEX_OP_ASSIGN_PLACES, BC_LEX_OP_PLACES);
+ break;
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+ case '(':
+ case ')':
+ {
+ l->t = (BcLexType) (c - '(' + BC_LEX_LPAREN);
+ break;
+ }
+
+ case '*':
+ {
+ bc_lex_assign(l, BC_LEX_OP_ASSIGN_MULTIPLY, BC_LEX_OP_MULTIPLY);
+ break;
+ }
+
+ case '+':
+ {
+ c2 = l->buf[l->i];
+ if (c2 == '+') {
+ l->i += 1;
+ l->t = BC_LEX_OP_INC;
+ }
+ else bc_lex_assign(l, BC_LEX_OP_ASSIGN_PLUS, BC_LEX_OP_PLUS);
+ break;
+ }
+
+ case ',':
+ {
+ l->t = BC_LEX_COMMA;
+ break;
+ }
+
+ case '-':
+ {
+ c2 = l->buf[l->i];
+ if (c2 == '-') {
+ l->i += 1;
+ l->t = BC_LEX_OP_DEC;
+ }
+ else bc_lex_assign(l, BC_LEX_OP_ASSIGN_MINUS, BC_LEX_OP_MINUS);
+ break;
+ }
+
+ case '.':
+ {
+ c2 = l->buf[l->i];
+ if (BC_LEX_NUM_CHAR(c2, true, false)) bc_lex_number(l, c);
+ else {
+ l->t = BC_LEX_KW_LAST;
+ bc_lex_err(l, BC_ERR_POSIX_DOT);
+ }
+ break;
+ }
+
+ case '/':
+ {
+ c2 = l->buf[l->i];
+ if (c2 =='*') bc_lex_comment(l);
+ else bc_lex_assign(l, BC_LEX_OP_ASSIGN_DIVIDE, BC_LEX_OP_DIVIDE);
+ break;
+ }
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ // Apparently, GNU bc (and maybe others) allows any uppercase letter as
+ // a number. When single digits, they act like the ones above. When
+ // multi-digit, any letter above the input base is automatically set to
+ // the biggest allowable digit in the input base.
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ {
+ bc_lex_number(l, c);
+ break;
+ }
+
+ case ';':
+ {
+ l->t = BC_LEX_SCOLON;
+ break;
+ }
+
+ case '<':
+ {
+#if BC_ENABLE_EXTRA_MATH
+ c2 = l->buf[l->i];
+
+ if (c2 == '<') {
+ l->i += 1;
+ bc_lex_assign(l, BC_LEX_OP_ASSIGN_LSHIFT, BC_LEX_OP_LSHIFT);
+ break;
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+ bc_lex_assign(l, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_LT);
+ break;
+ }
+
+ case '=':
+ {
+ bc_lex_assign(l, BC_LEX_OP_REL_EQ, BC_LEX_OP_ASSIGN);
+ break;
+ }
+
+ case '>':
+ {
+#if BC_ENABLE_EXTRA_MATH
+ c2 = l->buf[l->i];
+
+ if (c2 == '>') {
+ l->i += 1;
+ bc_lex_assign(l, BC_LEX_OP_ASSIGN_RSHIFT, BC_LEX_OP_RSHIFT);
+ break;
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+ bc_lex_assign(l, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_GT);
+ break;
+ }
+
+ case '[':
+ case ']':
+ {
+ l->t = (BcLexType) (c - '[' + BC_LEX_LBRACKET);
+ break;
+ }
+
+ case '\\':
+ {
+ if (BC_NO_ERR(l->buf[l->i] == '\n')) {
+ l->i += 1;
+ l->t = BC_LEX_WHITESPACE;
+ }
+ else bc_lex_invalidChar(l, c);
+ break;
+ }
+
+ case '^':
+ {
+ bc_lex_assign(l, BC_LEX_OP_ASSIGN_POWER, BC_LEX_OP_POWER);
+ break;
+ }
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ {
+ bc_lex_identifier(l);
+ break;
+ }
+
+ case '{':
+ case '}':
+ {
+ l->t = (BcLexType) (c - '{' + BC_LEX_LBRACE);
+ break;
+ }
+
+ case '|':
+ {
+ c2 = l->buf[l->i];
+
+ if (BC_NO_ERR(c2 == '|')) {
+
+ bc_lex_verr(l, BC_ERR_POSIX_BOOL, "||");
+
+ l->i += 1;
+ l->t = BC_LEX_OP_BOOL_OR;
+ }
+ else bc_lex_invalidChar(l, c);
+
+ break;
+ }
+
+ default:
+ {
+ bc_lex_invalidChar(l, c);
+ }
+ }
+}
+#endif // BC_ENABLED
diff --git a/contrib/bc/src/bc_parse.c b/contrib/bc/src/bc_parse.c
new file mode 100644
index 000000000000..35d3e45c581c
--- /dev/null
+++ b/contrib/bc/src/bc_parse.c
@@ -0,0 +1,1532 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The parser for bc.
+ *
+ */
+
+#if BC_ENABLED
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <setjmp.h>
+
+#include <bc.h>
+#include <num.h>
+#include <vm.h>
+
+static void bc_parse_else(BcParse *p);
+static void bc_parse_stmt(BcParse *p);
+static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags,
+ BcParseNext next);
+
+static bool bc_parse_inst_isLeaf(BcInst t) {
+ return (t >= BC_INST_NUM && t <= BC_INST_MAXSCALE) ||
+#if BC_ENABLE_EXTRA_MATH
+ t == BC_INST_TRUNC ||
+#endif // BC_ENABLE_EXTRA_MATH
+ t <= BC_INST_DEC;
+}
+
+static bool bc_parse_isDelimiter(const BcParse *p) {
+
+ BcLexType t = p->l.t;
+ bool good = false;
+
+ if (BC_PARSE_DELIMITER(t)) return true;
+
+ if (t == BC_LEX_KW_ELSE) {
+
+ size_t i;
+ uint16_t *fptr = NULL, flags = BC_PARSE_FLAG_ELSE;
+
+ for (i = 0; i < p->flags.len && BC_PARSE_BLOCK_STMT(flags); ++i) {
+
+ fptr = bc_vec_item_rev(&p->flags, i);
+ flags = *fptr;
+
+ if ((flags & BC_PARSE_FLAG_BRACE) && p->l.last != BC_LEX_RBRACE)
+ return false;
+ }
+
+ good = ((flags & BC_PARSE_FLAG_IF) != 0);
+ }
+ else if (t == BC_LEX_RBRACE) {
+
+ size_t i;
+
+ for (i = 0; !good && i < p->flags.len; ++i) {
+ uint16_t *fptr = bc_vec_item_rev(&p->flags, i);
+ good = (((*fptr) & BC_PARSE_FLAG_BRACE) != 0);
+ }
+ }
+
+ return good;
+}
+
+static void bc_parse_setLabel(BcParse *p) {
+
+ BcFunc *func = p->func;
+ BcInstPtr *ip = bc_vec_top(&p->exits);
+ size_t *label;
+
+ assert(func == bc_vec_item(&p->prog->fns, p->fidx));
+
+ label = bc_vec_item(&func->labels, ip->idx);
+ *label = func->code.len;
+
+ bc_vec_pop(&p->exits);
+}
+
+static void bc_parse_createLabel(BcParse *p, size_t idx) {
+ bc_vec_push(&p->func->labels, &idx);
+}
+
+static void bc_parse_createCondLabel(BcParse *p, size_t idx) {
+ bc_parse_createLabel(p, p->func->code.len);
+ bc_vec_push(&p->conds, &idx);
+}
+
+static void bc_parse_createExitLabel(BcParse *p, size_t idx, bool loop) {
+
+ BcInstPtr ip;
+
+ assert(p->func == bc_vec_item(&p->prog->fns, p->fidx));
+
+ ip.func = loop;
+ ip.idx = idx;
+ ip.len = 0;
+
+ bc_vec_push(&p->exits, &ip);
+ bc_parse_createLabel(p, SIZE_MAX);
+}
+
+static void bc_parse_operator(BcParse *p, BcLexType type,
+ size_t start, size_t *nexprs)
+{
+ BcLexType t;
+ uchar l, r = BC_PARSE_OP_PREC(type);
+ uchar left = BC_PARSE_OP_LEFT(type);
+
+ while (p->ops.len > start) {
+
+ t = BC_PARSE_TOP_OP(p);
+ if (t == BC_LEX_LPAREN) break;
+
+ l = BC_PARSE_OP_PREC(t);
+ if (l >= r && (l != r || !left)) break;
+
+ bc_parse_push(p, BC_PARSE_TOKEN_INST(t));
+ bc_vec_pop(&p->ops);
+ *nexprs -= !BC_PARSE_OP_PREFIX(t);
+ }
+
+ bc_vec_push(&p->ops, &type);
+}
+
+static void bc_parse_rightParen(BcParse *p, size_t *nexs) {
+
+ BcLexType top;
+
+ while ((top = BC_PARSE_TOP_OP(p)) != BC_LEX_LPAREN) {
+ bc_parse_push(p, BC_PARSE_TOKEN_INST(top));
+ bc_vec_pop(&p->ops);
+ *nexs -= !BC_PARSE_OP_PREFIX(top);
+ }
+
+ bc_vec_pop(&p->ops);
+
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_params(BcParse *p, uint8_t flags) {
+
+ bool comma = false;
+ size_t nparams;
+
+ bc_lex_next(&p->l);
+
+ flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
+ flags |= (BC_PARSE_ARRAY | BC_PARSE_NEEDVAL);
+
+ for (nparams = 0; p->l.t != BC_LEX_RPAREN; ++nparams) {
+
+ bc_parse_expr_status(p, flags, bc_parse_next_param);
+
+ comma = (p->l.t == BC_LEX_COMMA);
+ if (comma) bc_lex_next(&p->l);
+ }
+
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_parse_push(p, BC_INST_CALL);
+ bc_parse_pushIndex(p, nparams);
+}
+
+static void bc_parse_call(BcParse *p, const char *name, uint8_t flags) {
+
+ size_t idx;
+
+ bc_parse_params(p, flags);
+
+ // We just assert this because bc_parse_params() should
+ // ensure that the next token is what it should be.
+ assert(p->l.t == BC_LEX_RPAREN);
+
+ // We cannot use bc_program_insertFunc() here
+ // because it will overwrite an existing function.
+ idx = bc_map_index(&p->prog->fn_map, name);
+
+ if (idx == BC_VEC_INVALID_IDX) {
+
+ BC_SIG_LOCK;
+
+ idx = bc_program_insertFunc(p->prog, name);
+
+ BC_SIG_UNLOCK;
+
+ assert(idx != BC_VEC_INVALID_IDX);
+
+ // Make sure that this pointer was not invalidated.
+ p->func = bc_vec_item(&p->prog->fns, p->fidx);
+ }
+ else idx = ((BcId*) bc_vec_item(&p->prog->fn_map, idx))->idx;
+
+ bc_parse_pushIndex(p, idx);
+
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_name(BcParse *p, BcInst *type,
+ bool *can_assign, uint8_t flags)
+{
+ char *name;
+
+ BC_SIG_LOCK;
+
+ name = bc_vm_strdup(p->l.str.v);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_lex_next(&p->l);
+
+ if (p->l.t == BC_LEX_LBRACKET) {
+
+ bc_lex_next(&p->l);
+
+ if (p->l.t == BC_LEX_RBRACKET) {
+
+ if (BC_ERR(!(flags & BC_PARSE_ARRAY)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ *type = BC_INST_ARRAY;
+ *can_assign = false;
+ }
+ else {
+
+ uint8_t flags2 = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) |
+ BC_PARSE_NEEDVAL;
+
+ bc_parse_expr_status(p, flags2, bc_parse_next_elem);
+
+ if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ *type = BC_INST_ARRAY_ELEM;
+ *can_assign = true;
+ }
+
+ bc_lex_next(&p->l);
+
+ bc_parse_push(p, *type);
+ bc_parse_pushName(p, name, false);
+ }
+ else if (p->l.t == BC_LEX_LPAREN) {
+
+ if (BC_ERR(flags & BC_PARSE_NOCALL))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ *type = BC_INST_CALL;
+ *can_assign = false;
+
+ bc_parse_call(p, name, flags);
+ }
+ else {
+ *type = BC_INST_VAR;
+ *can_assign = true;
+ bc_parse_push(p, BC_INST_VAR);
+ bc_parse_pushName(p, name, true);
+ }
+
+err:
+ BC_SIG_MAYLOCK;
+ free(name);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_parse_noArgBuiltin(BcParse *p, BcInst inst) {
+
+ bc_lex_next(&p->l);
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+ if ((p->l.t != BC_LEX_RPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_parse_push(p, inst);
+
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_builtin(BcParse *p, BcLexType type,
+ uint8_t flags, BcInst *prev)
+{
+ bc_lex_next(&p->l);
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+
+ flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
+ flags |= BC_PARSE_NEEDVAL;
+ if (type == BC_LEX_KW_LENGTH) flags |= BC_PARSE_ARRAY;
+
+ bc_parse_expr_status(p, flags, bc_parse_next_rel);
+
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ *prev = type - BC_LEX_KW_LENGTH + BC_INST_LENGTH;
+ bc_parse_push(p, *prev);
+
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_scale(BcParse *p, BcInst *type,
+ bool *can_assign, uint8_t flags)
+{
+ bc_lex_next(&p->l);
+
+ if (p->l.t != BC_LEX_LPAREN) {
+ *type = BC_INST_SCALE;
+ *can_assign = true;
+ bc_parse_push(p, BC_INST_SCALE);
+ return;
+ }
+
+ *type = BC_INST_SCALE_FUNC;
+ *can_assign = false;
+ flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
+ flags |= BC_PARSE_NEEDVAL;
+
+ bc_lex_next(&p->l);
+
+ bc_parse_expr_status(p, flags, bc_parse_next_rel);
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_parse_push(p, BC_INST_SCALE_FUNC);
+
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_incdec(BcParse *p, BcInst *prev, bool *can_assign,
+ size_t *nexs, uint8_t flags)
+{
+ BcLexType type;
+ uchar inst;
+ BcInst etype = *prev;
+ BcLexType last = p->l.last;
+
+ assert(prev != NULL && can_assign != NULL);
+
+ if (BC_ERR(last == BC_LEX_OP_INC || last == BC_LEX_OP_DEC ||
+ last == BC_LEX_RPAREN))
+ {
+ bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
+ }
+
+ if (BC_PARSE_INST_VAR(etype)) {
+
+ if (!*can_assign) bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
+
+ *prev = inst = BC_INST_INC + (p->l.t != BC_LEX_OP_INC);
+ bc_parse_push(p, inst);
+ bc_lex_next(&p->l);
+ *can_assign = false;
+ }
+ else {
+
+ *prev = inst = BC_INST_ASSIGN_PLUS + (p->l.t != BC_LEX_OP_INC);
+
+ bc_lex_next(&p->l);
+ type = p->l.t;
+
+ // Because we parse the next part of the expression
+ // right here, we need to increment this.
+ *nexs = *nexs + 1;
+
+ if (type == BC_LEX_NAME) {
+ uint8_t flags2 = flags & ~BC_PARSE_ARRAY;
+ bc_parse_name(p, prev, can_assign, flags2 | BC_PARSE_NOCALL);
+ }
+ else if (type >= BC_LEX_KW_LAST && type <= BC_LEX_KW_OBASE) {
+ bc_parse_push(p, type - BC_LEX_KW_LAST + BC_INST_LAST);
+ bc_lex_next(&p->l);
+ }
+ else if (BC_NO_ERR(type == BC_LEX_KW_SCALE)) {
+
+ bc_lex_next(&p->l);
+
+ if (BC_ERR(p->l.t == BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ else bc_parse_push(p, BC_INST_SCALE);
+ }
+ else bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ *can_assign = false;
+
+ bc_parse_push(p, BC_INST_ONE);
+ bc_parse_push(p, inst);
+ }
+}
+
+static void bc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn,
+ bool rparen, bool binlast, size_t *nexprs)
+{
+ BcLexType type;
+
+ bc_lex_next(&p->l);
+
+ type = BC_PARSE_LEAF(*prev, binlast, rparen) ? BC_LEX_OP_MINUS : BC_LEX_NEG;
+ *prev = BC_PARSE_TOKEN_INST(type);
+
+ // We can just push onto the op stack because this is the largest
+ // precedence operator that gets pushed. Inc/dec does not.
+ if (type != BC_LEX_OP_MINUS) bc_vec_push(&p->ops, &type);
+ else bc_parse_operator(p, type, ops_bgn, nexprs);
+}
+
+static void bc_parse_str(BcParse *p, char inst) {
+ bc_parse_addString(p);
+ bc_parse_push(p, inst);
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_print(BcParse *p) {
+
+ BcLexType t;
+ bool comma = false;
+
+ bc_lex_next(&p->l);
+
+ t = p->l.t;
+
+ if (bc_parse_isDelimiter(p)) bc_parse_err(p, BC_ERR_PARSE_PRINT);
+
+ do {
+ if (t == BC_LEX_STR) bc_parse_str(p, BC_INST_PRINT_POP);
+ else {
+ bc_parse_expr_status(p, BC_PARSE_NEEDVAL, bc_parse_next_print);
+ bc_parse_push(p, BC_INST_PRINT_POP);
+ }
+
+ comma = (p->l.t == BC_LEX_COMMA);
+
+ if (comma) bc_lex_next(&p->l);
+ else {
+ if (!bc_parse_isDelimiter(p))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ else break;
+ }
+
+ t = p->l.t;
+ } while (true);
+
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+}
+
+static void bc_parse_return(BcParse *p) {
+
+ BcLexType t;
+ bool paren;
+ uchar inst = BC_INST_RET0;
+
+ if (BC_ERR(!BC_PARSE_FUNC(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ if (p->func->voidfn) inst = BC_INST_RET_VOID;
+
+ bc_lex_next(&p->l);
+
+ t = p->l.t;
+ paren = t == BC_LEX_LPAREN;
+
+ if (bc_parse_isDelimiter(p)) bc_parse_push(p, inst);
+ else {
+
+ BcParseStatus s;
+
+ s = bc_parse_expr_err(p, BC_PARSE_NEEDVAL, bc_parse_next_expr);
+
+ if (s == BC_PARSE_STATUS_EMPTY_EXPR) {
+ bc_parse_push(p, inst);
+ bc_lex_next(&p->l);
+ }
+
+ if (!paren || p->l.last != BC_LEX_RPAREN) {
+ bc_parse_err(p, BC_ERR_POSIX_RET);
+ }
+ else if (BC_ERR(p->func->voidfn))
+ bc_parse_verr(p, BC_ERR_PARSE_RET_VOID, p->func->name);
+
+ bc_parse_push(p, BC_INST_RET);
+ }
+}
+
+static void bc_parse_noElse(BcParse *p) {
+ uint16_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
+ *flag_ptr = (*flag_ptr & ~(BC_PARSE_FLAG_IF_END));
+ bc_parse_setLabel(p);
+}
+
+static void bc_parse_endBody(BcParse *p, bool brace) {
+
+ bool has_brace, new_else = false;
+
+ if (BC_ERR(p->flags.len <= 1)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ if (brace) {
+
+ assert(p->l.t == BC_LEX_RBRACE);
+
+ bc_lex_next(&p->l);
+ if (BC_ERR(!bc_parse_isDelimiter(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ }
+
+ has_brace = (BC_PARSE_BRACE(p) != 0);
+
+ do {
+ size_t len = p->flags.len;
+ bool loop;
+
+ if (has_brace && !brace) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ loop = (BC_PARSE_LOOP_INNER(p) != 0);
+
+ if (loop || BC_PARSE_ELSE(p)) {
+
+ if (loop) {
+
+ size_t *label = bc_vec_top(&p->conds);
+
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, *label);
+
+ bc_vec_pop(&p->conds);
+ }
+
+ bc_parse_setLabel(p);
+ bc_vec_pop(&p->flags);
+ }
+ else if (BC_PARSE_FUNC_INNER(p)) {
+ BcInst inst = (p->func->voidfn ? BC_INST_RET_VOID : BC_INST_RET0);
+ bc_parse_push(p, inst);
+ bc_parse_updateFunc(p, BC_PROG_MAIN);
+ bc_vec_pop(&p->flags);
+ }
+ else if (BC_PARSE_BRACE(p) && !BC_PARSE_IF(p)) bc_vec_pop(&p->flags);
+
+ // This needs to be last to parse nested if's properly.
+ if (BC_PARSE_IF(p) && (len == p->flags.len || !BC_PARSE_BRACE(p))) {
+
+ while (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
+
+ bc_vec_pop(&p->flags);
+
+ if (!BC_S) {
+
+ *(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_IF_END;
+ new_else = (p->l.t == BC_LEX_KW_ELSE);
+
+ if (new_else) bc_parse_else(p);
+ else if (!has_brace && (!BC_PARSE_IF_END(p) || brace))
+ bc_parse_noElse(p);
+ }
+ else bc_parse_noElse(p);
+ }
+
+ if (brace && has_brace) brace = false;
+
+ } while (p->flags.len > 1 && !new_else && (!BC_PARSE_IF_END(p) || brace) &&
+ !(has_brace = (BC_PARSE_BRACE(p) != 0)));
+
+ if (BC_ERR(p->flags.len == 1 && brace))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ else if (brace && BC_PARSE_BRACE(p)) {
+
+ uint16_t flags = BC_PARSE_TOP_FLAG(p);
+
+ if (!(flags & (BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_LOOP_INNER)) &&
+ !(flags & (BC_PARSE_FLAG_IF | BC_PARSE_FLAG_ELSE)) &&
+ !(flags & (BC_PARSE_FLAG_IF_END)))
+ {
+ bc_vec_pop(&p->flags);
+ }
+ }
+}
+
+static void bc_parse_startBody(BcParse *p, uint16_t flags) {
+ assert(flags);
+ flags |= (BC_PARSE_TOP_FLAG(p) & (BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_LOOP));
+ flags |= BC_PARSE_FLAG_BODY;
+ bc_vec_push(&p->flags, &flags);
+}
+
+static void bc_parse_if(BcParse *p) {
+
+ size_t idx;
+ uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
+
+ bc_lex_next(&p->l);
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+ bc_parse_expr_status(p, flags, bc_parse_next_rel);
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+ bc_parse_push(p, BC_INST_JUMP_ZERO);
+
+ idx = p->func->labels.len;
+
+ bc_parse_pushIndex(p, idx);
+ bc_parse_createExitLabel(p, idx, false);
+ bc_parse_startBody(p, BC_PARSE_FLAG_IF);
+}
+
+static void bc_parse_else(BcParse *p) {
+
+ size_t idx = p->func->labels.len;
+
+ if (BC_ERR(!BC_PARSE_IF_END(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, idx);
+
+ bc_parse_noElse(p);
+
+ bc_parse_createExitLabel(p, idx, false);
+ bc_parse_startBody(p, BC_PARSE_FLAG_ELSE);
+
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_while(BcParse *p) {
+
+ size_t idx;
+ uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
+
+ bc_lex_next(&p->l);
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ bc_parse_createCondLabel(p, p->func->labels.len);
+ idx = p->func->labels.len;
+ bc_parse_createExitLabel(p, idx, true);
+
+ bc_parse_expr_status(p, flags, bc_parse_next_rel);
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ bc_parse_push(p, BC_INST_JUMP_ZERO);
+ bc_parse_pushIndex(p, idx);
+ bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
+}
+
+static void bc_parse_for(BcParse *p) {
+
+ size_t cond_idx, exit_idx, body_idx, update_idx;
+
+ bc_lex_next(&p->l);
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ if (p->l.t != BC_LEX_SCOLON)
+ bc_parse_expr_status(p, 0, bc_parse_next_for);
+ else bc_parse_err(p, BC_ERR_POSIX_FOR);
+
+ if (BC_ERR(p->l.t != BC_LEX_SCOLON))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ cond_idx = p->func->labels.len;
+ update_idx = cond_idx + 1;
+ body_idx = update_idx + 1;
+ exit_idx = body_idx + 1;
+
+ bc_parse_createLabel(p, p->func->code.len);
+
+ if (p->l.t != BC_LEX_SCOLON) {
+ uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
+ bc_parse_expr_status(p, flags, bc_parse_next_for);
+ }
+ else {
+
+ // Set this for the next call to bc_parse_number.
+ // This is safe to set because the current token
+ // is a semicolon, which has no string requirement.
+ bc_vec_string(&p->l.str, sizeof(bc_parse_one) - 1, bc_parse_one);
+ bc_parse_number(p);
+
+ bc_parse_err(p, BC_ERR_POSIX_FOR);
+ }
+
+ if (BC_ERR(p->l.t != BC_LEX_SCOLON))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+
+ bc_parse_push(p, BC_INST_JUMP_ZERO);
+ bc_parse_pushIndex(p, exit_idx);
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, body_idx);
+
+ bc_parse_createCondLabel(p, update_idx);
+
+ if (p->l.t != BC_LEX_RPAREN)
+ bc_parse_expr_status(p, 0, bc_parse_next_rel);
+ else bc_parse_err(p, BC_ERR_POSIX_FOR);
+
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, cond_idx);
+ bc_parse_createLabel(p, p->func->code.len);
+
+ bc_parse_createExitLabel(p, exit_idx, true);
+ bc_lex_next(&p->l);
+ bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
+}
+
+static void bc_parse_loopExit(BcParse *p, BcLexType type) {
+
+ size_t i;
+ BcInstPtr *ip;
+
+ if (BC_ERR(!BC_PARSE_LOOP(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ if (type == BC_LEX_KW_BREAK) {
+
+ if (BC_ERR(!p->exits.len)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ i = p->exits.len - 1;
+ ip = bc_vec_item(&p->exits, i);
+
+ while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--);
+ assert(ip != NULL && (i < p->exits.len || ip->func));
+ i = ip->idx;
+ }
+ else i = *((size_t*) bc_vec_top(&p->conds));
+
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, i);
+
+ bc_lex_next(&p->l);
+}
+
+static void bc_parse_func(BcParse *p) {
+
+ bool comma = false, voidfn;
+ uint16_t flags;
+ size_t idx;
+
+ bc_lex_next(&p->l);
+
+ if (BC_ERR(p->l.t != BC_LEX_NAME))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ voidfn = (!BC_IS_POSIX && p->l.t == BC_LEX_NAME &&
+ !strcmp(p->l.str.v, "void"));
+
+ bc_lex_next(&p->l);
+
+ voidfn = (voidfn && p->l.t == BC_LEX_NAME);
+
+ if (voidfn) {
+ bc_parse_err(p, BC_ERR_POSIX_VOID);
+ bc_lex_next(&p->l);
+ }
+
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ assert(p->prog->fns.len == p->prog->fn_map.len);
+
+ BC_SIG_LOCK;
+
+ idx = bc_program_insertFunc(p->prog, p->l.str.v);
+
+ BC_SIG_UNLOCK;
+
+ assert(idx);
+ bc_parse_updateFunc(p, idx);
+ p->func->voidfn = voidfn;
+
+ bc_lex_next(&p->l);
+
+ while (p->l.t != BC_LEX_RPAREN) {
+
+ BcType t = BC_TYPE_VAR;
+
+ if (p->l.t == BC_LEX_OP_MULTIPLY) {
+ t = BC_TYPE_REF;
+ bc_lex_next(&p->l);
+ bc_parse_err(p, BC_ERR_POSIX_REF);
+ }
+
+ if (BC_ERR(p->l.t != BC_LEX_NAME))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ p->func->nparams += 1;
+
+ bc_vec_string(&p->buf, p->l.str.len, p->l.str.v);
+
+ bc_lex_next(&p->l);
+
+ if (p->l.t == BC_LEX_LBRACKET) {
+
+ if (t == BC_TYPE_VAR) t = BC_TYPE_ARRAY;
+
+ bc_lex_next(&p->l);
+
+ if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ bc_lex_next(&p->l);
+ }
+ else if (BC_ERR(t == BC_TYPE_REF))
+ bc_parse_verr(p, BC_ERR_PARSE_REF_VAR, p->buf.v);
+
+ comma = (p->l.t == BC_LEX_COMMA);
+ if (comma) {
+ bc_lex_next(&p->l);
+ }
+
+ bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line);
+ }
+
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER;
+ bc_parse_startBody(p, flags);
+
+ bc_lex_next(&p->l);
+
+ if (p->l.t != BC_LEX_LBRACE) bc_parse_err(p, BC_ERR_POSIX_BRACE);
+}
+
+static void bc_parse_auto(BcParse *p) {
+
+ bool comma, one;
+
+ if (BC_ERR(!p->auto_part)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ p->auto_part = comma = false;
+ one = p->l.t == BC_LEX_NAME;
+
+ while (p->l.t == BC_LEX_NAME) {
+
+ BcType t;
+
+ bc_vec_string(&p->buf, p->l.str.len - 1, p->l.str.v);
+
+ bc_lex_next(&p->l);
+
+ if (p->l.t == BC_LEX_LBRACKET) {
+
+ t = BC_TYPE_ARRAY;
+
+ bc_lex_next(&p->l);
+
+ if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ bc_lex_next(&p->l);
+ }
+ else t = BC_TYPE_VAR;
+
+ comma = (p->l.t == BC_LEX_COMMA);
+ if (comma) bc_lex_next(&p->l);
+
+ bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line);
+ }
+
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC);
+ if (BC_ERR(!one)) bc_parse_err(p, BC_ERR_PARSE_NO_AUTO);
+ if (BC_ERR(!bc_parse_isDelimiter(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+}
+
+static void bc_parse_body(BcParse *p, bool brace) {
+
+ uint16_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
+
+ assert(flag_ptr != NULL);
+ assert(p->flags.len >= 2);
+
+ *flag_ptr &= ~(BC_PARSE_FLAG_BODY);
+
+ if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) {
+
+ if (BC_ERR(!brace)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ p->auto_part = (p->l.t != BC_LEX_KW_AUTO);
+
+ if (!p->auto_part) {
+
+ // Make sure this is true to not get a parse error.
+ p->auto_part = true;
+
+ bc_parse_auto(p);
+ }
+
+ if (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
+ }
+ else {
+
+ size_t len = p->flags.len;
+
+ assert(*flag_ptr);
+
+ bc_parse_stmt(p);
+
+ if (!brace && !BC_PARSE_BODY(p) && len <= p->flags.len)
+ bc_parse_endBody(p, false);
+ }
+}
+
+static void bc_parse_stmt(BcParse *p) {
+
+ size_t len;
+ uint16_t flags;
+ BcLexType type = p->l.t;
+
+ if (type == BC_LEX_NLINE) {
+ bc_lex_next(&p->l);
+ return;
+ }
+ if (type == BC_LEX_KW_AUTO) {
+ bc_parse_auto(p);
+ return;
+ }
+
+ p->auto_part = false;
+
+ if (type != BC_LEX_KW_ELSE) {
+
+ if (BC_PARSE_IF_END(p)) {
+ bc_parse_noElse(p);
+ if (p->flags.len > 1 && !BC_PARSE_BRACE(p))
+ bc_parse_endBody(p, false);
+ return;
+ }
+ else if (type == BC_LEX_LBRACE) {
+
+ if (!BC_PARSE_BODY(p)) {
+ bc_parse_startBody(p, BC_PARSE_FLAG_BRACE);
+ bc_lex_next(&p->l);
+ }
+ else {
+ *(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_BRACE;
+ bc_lex_next(&p->l);
+ bc_parse_body(p, true);
+ }
+
+ return;
+ }
+ else if (BC_PARSE_BODY(p) && !BC_PARSE_BRACE(p)) {
+ bc_parse_body(p, false);
+ return;
+ }
+ }
+
+ len = p->flags.len;
+ flags = BC_PARSE_TOP_FLAG(p);
+
+ switch (type) {
+
+ case BC_LEX_OP_INC:
+ case BC_LEX_OP_DEC:
+ case BC_LEX_OP_MINUS:
+ case BC_LEX_OP_BOOL_NOT:
+ case BC_LEX_LPAREN:
+ case BC_LEX_NAME:
+ case BC_LEX_NUMBER:
+ case BC_LEX_KW_IBASE:
+ case BC_LEX_KW_LAST:
+ case BC_LEX_KW_LENGTH:
+ case BC_LEX_KW_OBASE:
+ case BC_LEX_KW_SCALE:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_SEED:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_SQRT:
+ case BC_LEX_KW_ABS:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_IRAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_READ:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_RAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_MAXIBASE:
+ case BC_LEX_KW_MAXOBASE:
+ case BC_LEX_KW_MAXSCALE:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_MAXRAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ {
+ bc_parse_expr_status(p, BC_PARSE_PRINT, bc_parse_next_expr);
+ break;
+ }
+
+ case BC_LEX_KW_ELSE:
+ {
+ bc_parse_else(p);
+ break;
+ }
+
+ case BC_LEX_SCOLON:
+ {
+ // Do nothing.
+ break;
+ }
+
+ case BC_LEX_RBRACE:
+ {
+ bc_parse_endBody(p, true);
+ break;
+ }
+
+ case BC_LEX_STR:
+ {
+ bc_parse_str(p, BC_INST_PRINT_STR);
+ break;
+ }
+
+ case BC_LEX_KW_BREAK:
+ case BC_LEX_KW_CONTINUE:
+ {
+ bc_parse_loopExit(p, p->l.t);
+ break;
+ }
+
+ case BC_LEX_KW_FOR:
+ {
+ bc_parse_for(p);
+ break;
+ }
+
+ case BC_LEX_KW_HALT:
+ {
+ bc_parse_push(p, BC_INST_HALT);
+ bc_lex_next(&p->l);
+ break;
+ }
+
+ case BC_LEX_KW_IF:
+ {
+ bc_parse_if(p);
+ break;
+ }
+
+ case BC_LEX_KW_LIMITS:
+ {
+ bc_vm_printf("BC_LONG_BIT = %lu\n", (ulong) BC_LONG_BIT);
+ bc_vm_printf("BC_BASE_DIGS = %lu\n", (ulong) BC_BASE_DIGS);
+ bc_vm_printf("BC_BASE_POW = %lu\n", (ulong) BC_BASE_POW);
+ bc_vm_printf("BC_OVERFLOW_MAX = %lu\n", (ulong) BC_NUM_BIGDIG_MAX);
+ bc_vm_printf("\n");
+ bc_vm_printf("BC_BASE_MAX = %lu\n", BC_MAX_OBASE);
+ bc_vm_printf("BC_DIM_MAX = %lu\n", BC_MAX_DIM);
+ bc_vm_printf("BC_SCALE_MAX = %lu\n", BC_MAX_SCALE);
+ bc_vm_printf("BC_STRING_MAX = %lu\n", BC_MAX_STRING);
+ bc_vm_printf("BC_NAME_MAX = %lu\n", BC_MAX_NAME);
+ bc_vm_printf("BC_NUM_MAX = %lu\n", BC_MAX_NUM);
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ bc_vm_printf("BC_RAND_MAX = %lu\n", BC_MAX_RAND);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ bc_vm_printf("MAX Exponent = %lu\n", BC_MAX_EXP);
+ bc_vm_printf("Number of vars = %lu\n", BC_MAX_VARS);
+
+ bc_lex_next(&p->l);
+
+ break;
+ }
+
+ case BC_LEX_KW_PRINT:
+ {
+ bc_parse_print(p);
+ break;
+ }
+
+ case BC_LEX_KW_QUIT:
+ {
+ // Quit is a compile-time command. We don't exit directly,
+ // so the vm can clean up. Limits do the same thing.
+ vm.status = BC_STATUS_QUIT;
+ BC_VM_JMP;
+ break;
+ }
+
+ case BC_LEX_KW_RETURN:
+ {
+ bc_parse_return(p);
+ break;
+ }
+
+ case BC_LEX_KW_WHILE:
+ {
+ bc_parse_while(p);
+ break;
+ }
+
+ default:
+ {
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ }
+ }
+
+ if (len == p->flags.len && flags == BC_PARSE_TOP_FLAG(p)) {
+ if (BC_ERR(!bc_parse_isDelimiter(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ }
+
+ // Make sure semicolons are eaten.
+ while (p->l.t == BC_LEX_SCOLON) bc_lex_next(&p->l);
+}
+
+void bc_parse_parse(BcParse *p) {
+
+ assert(p);
+
+ BC_SETJMP(exit);
+
+ if (BC_ERR(p->l.t == BC_LEX_EOF)) bc_parse_err(p, BC_ERR_PARSE_EOF);
+ else if (p->l.t == BC_LEX_KW_DEFINE) {
+ if (BC_ERR(BC_PARSE_NO_EXEC(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_parse_func(p);
+ }
+ else bc_parse_stmt(p);
+
+exit:
+ BC_SIG_MAYLOCK;
+ if (BC_ERR(((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig)))
+ bc_parse_reset(p);
+ BC_LONGJMP_CONT;
+}
+
+static BcParseStatus bc_parse_expr_err(BcParse *p, uint8_t flags,
+ BcParseNext next)
+{
+ BcInst prev = BC_INST_PRINT;
+ uchar inst = BC_INST_INVALID;
+ BcLexType top, t = p->l.t;
+ size_t nexprs = 0, ops_bgn = p->ops.len;
+ uint32_t i, nparens, nrelops;
+ bool pfirst, rprn, done, get_token, assign, bin_last, incdec, can_assign;
+
+ assert(!(flags & BC_PARSE_PRINT) || !(flags & BC_PARSE_NEEDVAL));
+
+ pfirst = (p->l.t == BC_LEX_LPAREN);
+ nparens = nrelops = 0;
+ rprn = done = get_token = assign = incdec = can_assign = false;
+ bin_last = true;
+
+ // We want to eat newlines if newlines are not a valid ending token.
+ // This is for spacing in things like for loop headers.
+ if (!(flags & BC_PARSE_NOREAD)) {
+ while ((t = p->l.t) == BC_LEX_NLINE) bc_lex_next(&p->l);
+ }
+
+ for (; !done && BC_PARSE_EXPR(t); t = p->l.t)
+ {
+ switch (t) {
+
+ case BC_LEX_OP_INC:
+ case BC_LEX_OP_DEC:
+ {
+ if (BC_ERR(incdec)) bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
+ bc_parse_incdec(p, &prev, &can_assign, &nexprs, flags);
+ rprn = get_token = bin_last = false;
+ incdec = true;
+ flags &= ~(BC_PARSE_ARRAY);
+ break;
+ }
+
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_OP_TRUNC:
+ {
+ if (BC_ERR(!BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // I can just add the instruction because
+ // negative will already be taken care of.
+ bc_parse_push(p, BC_INST_TRUNC);
+ rprn = can_assign = incdec = false;
+ get_token = true;
+ flags &= ~(BC_PARSE_ARRAY);
+ break;
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+
+ case BC_LEX_OP_MINUS:
+ {
+ bc_parse_minus(p, &prev, ops_bgn, rprn, bin_last, &nexprs);
+ rprn = get_token = can_assign = false;
+ bin_last = (prev == BC_INST_MINUS);
+ if (bin_last) incdec = false;
+ flags &= ~(BC_PARSE_ARRAY);
+ break;
+ }
+
+ case BC_LEX_OP_ASSIGN_POWER:
+ case BC_LEX_OP_ASSIGN_MULTIPLY:
+ case BC_LEX_OP_ASSIGN_DIVIDE:
+ case BC_LEX_OP_ASSIGN_MODULUS:
+ case BC_LEX_OP_ASSIGN_PLUS:
+ case BC_LEX_OP_ASSIGN_MINUS:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_OP_ASSIGN_PLACES:
+ case BC_LEX_OP_ASSIGN_LSHIFT:
+ case BC_LEX_OP_ASSIGN_RSHIFT:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_OP_ASSIGN:
+ {
+ if (!BC_PARSE_INST_VAR(prev))
+ bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
+ }
+ // Fallthrough.
+ BC_FALLTHROUGH
+
+ case BC_LEX_OP_POWER:
+ case BC_LEX_OP_MULTIPLY:
+ case BC_LEX_OP_DIVIDE:
+ case BC_LEX_OP_MODULUS:
+ case BC_LEX_OP_PLUS:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_OP_PLACES:
+ case BC_LEX_OP_LSHIFT:
+ case BC_LEX_OP_RSHIFT:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_OP_REL_EQ:
+ case BC_LEX_OP_REL_LE:
+ case BC_LEX_OP_REL_GE:
+ case BC_LEX_OP_REL_NE:
+ case BC_LEX_OP_REL_LT:
+ case BC_LEX_OP_REL_GT:
+ case BC_LEX_OP_BOOL_NOT:
+ case BC_LEX_OP_BOOL_OR:
+ case BC_LEX_OP_BOOL_AND:
+ {
+ if (BC_PARSE_OP_PREFIX(t)) {
+ if (BC_ERR(!bin_last && !BC_PARSE_OP_PREFIX(p->l.last)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+ }
+ else if (BC_ERR(BC_PARSE_PREV_PREFIX(prev) || bin_last))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ nrelops += (t >= BC_LEX_OP_REL_EQ && t <= BC_LEX_OP_REL_GT);
+ prev = BC_PARSE_TOKEN_INST(t);
+ bc_parse_operator(p, t, ops_bgn, &nexprs);
+ rprn = incdec = can_assign = false;
+ get_token = true;
+ bin_last = !BC_PARSE_OP_PREFIX(t);
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ case BC_LEX_LPAREN:
+ {
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ nparens += 1;
+ rprn = incdec = can_assign = false;
+ get_token = true;
+ bc_vec_push(&p->ops, &t);
+
+ break;
+ }
+
+ case BC_LEX_RPAREN:
+ {
+ // This needs to be a status. The error
+ // is handled in bc_parse_expr_status().
+ if (BC_ERR(p->l.last == BC_LEX_LPAREN))
+ return BC_PARSE_STATUS_EMPTY_EXPR;
+
+ if (BC_ERR(bin_last || BC_PARSE_PREV_PREFIX(prev)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ if (!nparens) {
+ done = true;
+ get_token = false;
+ break;
+ }
+
+ nparens -= 1;
+ rprn = true;
+ get_token = bin_last = incdec = false;
+
+ bc_parse_rightParen(p, &nexprs);
+
+ break;
+ }
+
+ case BC_LEX_NAME:
+ {
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ get_token = bin_last = false;
+ bc_parse_name(p, &prev, &can_assign,
+ flags & ~BC_PARSE_NOCALL);
+ rprn = (prev == BC_INST_CALL);
+ nexprs += 1;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ case BC_LEX_NUMBER:
+ {
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ bc_parse_number(p);
+ nexprs += 1;
+ prev = BC_INST_NUM;
+ get_token = true;
+ rprn = bin_last = can_assign = false;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ case BC_LEX_KW_IBASE:
+ case BC_LEX_KW_LAST:
+ case BC_LEX_KW_OBASE:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_SEED:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ {
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ prev = t - BC_LEX_KW_LAST + BC_INST_LAST;
+ bc_parse_push(p, prev);
+
+ get_token = can_assign = true;
+ rprn = bin_last = false;
+ nexprs += 1;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ case BC_LEX_KW_LENGTH:
+ case BC_LEX_KW_SQRT:
+ case BC_LEX_KW_ABS:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_IRAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ {
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ bc_parse_builtin(p, t, flags, &prev);
+ rprn = get_token = bin_last = incdec = can_assign = false;
+ nexprs += 1;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ case BC_LEX_KW_READ:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_RAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_MAXIBASE:
+ case BC_LEX_KW_MAXOBASE:
+ case BC_LEX_KW_MAXSCALE:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_LEX_KW_MAXRAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ {
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+ else if (t == BC_LEX_KW_READ && BC_ERR(flags & BC_PARSE_NOREAD))
+ bc_parse_err(p, BC_ERR_EXEC_REC_READ);
+ else {
+ prev = t - BC_LEX_KW_READ + BC_INST_READ;
+ bc_parse_noArgBuiltin(p, prev);
+ }
+
+ rprn = get_token = bin_last = incdec = can_assign = false;
+ nexprs += 1;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ case BC_LEX_KW_SCALE:
+ {
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ bc_parse_scale(p, &prev, &can_assign, flags);
+ rprn = get_token = bin_last = false;
+ nexprs += 1;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ default:
+ {
+#ifndef NDEBUG
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ break;
+#endif // NDEBUG
+ }
+ }
+
+ if (get_token) bc_lex_next(&p->l);
+ }
+
+ while (p->ops.len > ops_bgn) {
+
+ top = BC_PARSE_TOP_OP(p);
+ assign = top >= BC_LEX_OP_ASSIGN_POWER && top <= BC_LEX_OP_ASSIGN;
+
+ if (BC_ERR(top == BC_LEX_LPAREN || top == BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ bc_parse_push(p, BC_PARSE_TOKEN_INST(top));
+
+ nexprs -= !BC_PARSE_OP_PREFIX(top);
+ bc_vec_pop(&p->ops);
+
+ incdec = false;
+ }
+
+ if (BC_ERR(nexprs != 1)) bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ for (i = 0; i < next.len && t != next.tokens[i]; ++i);
+ if (BC_ERR(i == next.len && !bc_parse_isDelimiter(p)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ if (!(flags & BC_PARSE_REL) && nrelops)
+ bc_parse_err(p, BC_ERR_POSIX_REL_POS);
+ else if ((flags & BC_PARSE_REL) && nrelops > 1)
+ bc_parse_err(p, BC_ERR_POSIX_MULTIREL);
+
+ if (!(flags & BC_PARSE_NEEDVAL) && !pfirst) {
+
+ if (assign) {
+ inst = *((uchar*) bc_vec_top(&p->func->code));
+ inst += (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER);
+ incdec = false;
+ }
+ else if (incdec && !(flags & BC_PARSE_PRINT)) {
+ inst = *((uchar*) bc_vec_top(&p->func->code));
+ incdec = (inst <= BC_INST_DEC);
+ inst = BC_INST_ASSIGN_PLUS_NO_VAL + (inst != BC_INST_INC &&
+ inst != BC_INST_ASSIGN_PLUS);
+ }
+
+ if (inst >= BC_INST_ASSIGN_POWER_NO_VAL &&
+ inst <= BC_INST_ASSIGN_NO_VAL)
+ {
+ bc_vec_pop(&p->func->code);
+ if (incdec) bc_parse_push(p, BC_INST_ONE);
+ bc_parse_push(p, inst);
+ }
+ }
+
+ if ((flags & BC_PARSE_PRINT)) {
+ if (pfirst || !assign) bc_parse_push(p, BC_INST_PRINT);
+ }
+ else if (!(flags & BC_PARSE_NEEDVAL) &&
+ (inst < BC_INST_ASSIGN_POWER_NO_VAL ||
+ inst > BC_INST_ASSIGN_NO_VAL))
+ {
+ bc_parse_push(p, BC_INST_POP);
+ }
+
+ // We want to eat newlines if newlines are not a valid ending token.
+ // This is for spacing in things like for loop headers.
+ for (incdec = true, i = 0; i < next.len && incdec; ++i)
+ incdec = (next.tokens[i] != BC_LEX_NLINE);
+ if (incdec) {
+ while (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
+ }
+
+ return BC_PARSE_STATUS_SUCCESS;
+}
+
+void bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next) {
+
+ BcParseStatus s = bc_parse_expr_err(p, flags, next);
+
+ if (BC_ERR(s == BC_PARSE_STATUS_EMPTY_EXPR))
+ bc_parse_err(p, BC_ERR_PARSE_EMPTY_EXPR);
+}
+
+void bc_parse_expr(BcParse *p, uint8_t flags) {
+ assert(p);
+ bc_parse_expr_status(p, flags, bc_parse_next_read);
+}
+#endif // BC_ENABLED
diff --git a/contrib/bc/src/data.c b/contrib/bc/src/data.c
new file mode 100644
index 000000000000..a3cf4dbda293
--- /dev/null
+++ b/contrib/bc/src/data.c
@@ -0,0 +1,1025 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Constant data for bc.
+ *
+ */
+
+#include <args.h>
+#include <lex.h>
+#include <parse.h>
+#include <bc.h>
+#include <dc.h>
+#include <num.h>
+#include <rand.h>
+#include <program.h>
+#include <vm.h>
+
+#if !BC_ENABLE_LIBRARY
+
+#if BC_ENABLED
+const char bc_sig_msg[] = "\ninterrupt (type \"quit\" to exit)\n";
+const uchar bc_sig_msg_len = (uchar) (sizeof(bc_sig_msg) - 1);
+#endif // BC_ENABLED
+#if DC_ENABLED
+const char dc_sig_msg[] = "\ninterrupt (type \"q\" to exit)\n";
+const uchar dc_sig_msg_len = (uchar) (sizeof(dc_sig_msg) - 1);
+#endif // DC_ENABLED
+
+const char bc_copyright[] =
+ "Copyright (c) 2018-2020 Gavin D. Howard and contributors\n"
+ "Report bugs at: https://git.yzena.com/gavin/bc\n\n"
+ "This is free software with ABSOLUTELY NO WARRANTY.\n";
+
+const char* const bc_err_func_header = "Function:";
+const char* const bc_err_line = ":%zu";
+
+const char *bc_errs[] = {
+ "Math error:",
+ "Parse error:",
+ "Runtime error:",
+ "Fatal error:",
+#if BC_ENABLED
+ "Warning:",
+#endif // BC_ENABLED
+};
+
+const uchar bc_err_ids[] = {
+
+ BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
+
+ BC_ERR_IDX_FATAL, BC_ERR_IDX_FATAL, BC_ERR_IDX_FATAL, BC_ERR_IDX_FATAL,
+ BC_ERR_IDX_FATAL, BC_ERR_IDX_FATAL, BC_ERR_IDX_FATAL, BC_ERR_IDX_FATAL,
+
+ BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
+ BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
+ BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
+
+ BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
+ BC_ERR_IDX_PARSE,
+#if BC_ENABLED
+ BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
+ BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
+ BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
+
+ BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
+ BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
+ BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
+ BC_ERR_IDX_PARSE,
+#endif // BC_ENABLED
+
+};
+
+const char* const bc_err_msgs[] = {
+
+ "negative number",
+ "non-integer number",
+ "overflow: number cannot fit",
+ "divide by 0",
+
+ "memory allocation failed",
+ "I/O error",
+ "cannot open file: %s",
+ "file is not ASCII: %s",
+ "path is a directory: %s",
+ "bad command-line option: \"%s\"",
+ "option requires an argument: '%c' (\"%s\")",
+ "option takes no arguments: '%c' (\"%s\")",
+
+ "bad ibase: must be [%lu, %lu]",
+ "bad obase: must be [%lu, %lu]",
+ "bad scale: must be [%lu, %lu]",
+ "bad read() expression",
+ "read() call inside of a read() call",
+ "variable or array element is the wrong type",
+#if DC_ENABLED
+ "stack has too few elements",
+#else // DC_ENABLED
+ NULL,
+#endif // DC_ENABLED
+#if BC_ENABLED
+ "wrong number of parameters; need %zu, have %zu",
+ "undefined function: %s()",
+ "cannot use a void value in an expression",
+#else
+ NULL, NULL, NULL,
+#endif // BC_ENABLED
+
+ "end of file",
+ "bad character '%c'",
+ "string end cannot be found",
+ "comment end cannot be found",
+ "bad token",
+#if BC_ENABLED
+ "bad expression",
+ "empty expression",
+ "bad print statement",
+ "bad function definition",
+ ("bad assignment: left side must be scale, ibase, "
+ "obase, seed, last, var, or array element"),
+ "no auto variable found",
+ "function parameter or auto \"%s%s\" already exists",
+ "block end cannot be found",
+ "cannot return a value from void function: %s()",
+ "var cannot be a reference: %s",
+
+ "POSIX does not allow names longer than 1 character: %s",
+ "POSIX does not allow '#' script comments",
+ "POSIX does not allow the following keyword: %s",
+ "POSIX does not allow a period ('.') as a shortcut for the last result",
+ "POSIX requires parentheses around return expressions",
+ "POSIX does not allow the following operator: %s",
+ "POSIX does not allow comparison operators outside if statements or loops",
+ "POSIX requires 0 or 1 comparison operators per condition",
+ "POSIX requires all 3 parts of a for loop to be non-empty",
+#if BC_ENABLE_EXTRA_MATH
+ "POSIX does not allow exponential notation",
+#else
+ NULL,
+#endif // BC_ENABLE_EXTRA_MATH
+ "POSIX does not allow array references as function parameters",
+ "POSIX does not allow void functions",
+ "POSIX requires the left brace be on the same line as the function header",
+#endif // BC_ENABLED
+
+};
+
+#if BC_ENABLE_HISTORY
+const char *bc_history_bad_terms[] = { "dumb", "cons25", "emacs", NULL };
+
+const char bc_history_tab[] = " ";
+const size_t bc_history_tab_len = sizeof(bc_history_tab) - 1;
+
+// These are listed in ascending order for efficiency.
+const uint32_t bc_history_wchars[][2] = {
+ { 0x1100, 0x115F },
+ { 0x231A, 0x231B },
+ { 0x2329, 0x232A },
+ { 0x23E9, 0x23EC },
+ { 0x23F0, 0x23F0 },
+ { 0x23F3, 0x23F3 },
+ { 0x25FD, 0x25FE },
+ { 0x2614, 0x2615 },
+ { 0x2648, 0x2653 },
+ { 0x267F, 0x267F },
+ { 0x2693, 0x2693 },
+ { 0x26A1, 0x26A1 },
+ { 0x26AA, 0x26AB },
+ { 0x26BD, 0x26BE },
+ { 0x26C4, 0x26C5 },
+ { 0x26CE, 0x26CE },
+ { 0x26D4, 0x26D4 },
+ { 0x26EA, 0x26EA },
+ { 0x26F2, 0x26F3 },
+ { 0x26F5, 0x26F5 },
+ { 0x26FA, 0x26FA },
+ { 0x26FD, 0x26FD },
+ { 0x2705, 0x2705 },
+ { 0x270A, 0x270B },
+ { 0x2728, 0x2728 },
+ { 0x274C, 0x274C },
+ { 0x274E, 0x274E },
+ { 0x2753, 0x2755 },
+ { 0x2757, 0x2757 },
+ { 0x2795, 0x2797 },
+ { 0x27B0, 0x27B0 },
+ { 0x27BF, 0x27BF },
+ { 0x2B1B, 0x2B1C },
+ { 0x2B50, 0x2B50 },
+ { 0x2B55, 0x2B55 },
+ { 0x2E80, 0x2E99 },
+ { 0x2E9B, 0x2EF3 },
+ { 0x2F00, 0x2FD5 },
+ { 0x2FF0, 0x2FFB },
+ { 0x3001, 0x303E },
+ { 0x3041, 0x3096 },
+ { 0x3099, 0x30FF },
+ { 0x3105, 0x312D },
+ { 0x3131, 0x318E },
+ { 0x3190, 0x31BA },
+ { 0x31C0, 0x31E3 },
+ { 0x31F0, 0x321E },
+ { 0x3220, 0x3247 },
+ { 0x3250, 0x32FE },
+ { 0x3300, 0x4DBF },
+ { 0x4E00, 0xA48C },
+ { 0xA490, 0xA4C6 },
+ { 0xA960, 0xA97C },
+ { 0xAC00, 0xD7A3 },
+ { 0xF900, 0xFAFF },
+ { 0xFE10, 0xFE19 },
+ { 0xFE30, 0xFE52 },
+ { 0xFE54, 0xFE66 },
+ { 0xFE68, 0xFE6B },
+ { 0x16FE0, 0x16FE0 },
+ { 0x17000, 0x187EC },
+ { 0x18800, 0x18AF2 },
+ { 0x1B000, 0x1B001 },
+ { 0x1F004, 0x1F004 },
+ { 0x1F0CF, 0x1F0CF },
+ { 0x1F18E, 0x1F18E },
+ { 0x1F191, 0x1F19A },
+ { 0x1F200, 0x1F202 },
+ { 0x1F210, 0x1F23B },
+ { 0x1F240, 0x1F248 },
+ { 0x1F250, 0x1F251 },
+ { 0x1F300, 0x1F320 },
+ { 0x1F32D, 0x1F335 },
+ { 0x1F337, 0x1F37C },
+ { 0x1F37E, 0x1F393 },
+ { 0x1F3A0, 0x1F3CA },
+ { 0x1F3CF, 0x1F3D3 },
+ { 0x1F3E0, 0x1F3F0 },
+ { 0x1F3F4, 0x1F3F4 },
+ { 0x1F3F8, 0x1F43E },
+ { 0x1F440, 0x1F440 },
+ { 0x1F442, 0x1F4FC },
+ { 0x1F4FF, 0x1F53D },
+ { 0x1F54B, 0x1F54E },
+ { 0x1F550, 0x1F567 },
+ { 0x1F57A, 0x1F57A },
+ { 0x1F595, 0x1F596 },
+ { 0x1F5A4, 0x1F5A4 },
+ { 0x1F5FB, 0x1F64F },
+ { 0x1F680, 0x1F6C5 },
+ { 0x1F6CC, 0x1F6CC },
+ { 0x1F6D0, 0x1F6D2 },
+ { 0x1F6EB, 0x1F6EC },
+ { 0x1F6F4, 0x1F6F6 },
+ { 0x1F910, 0x1F91E },
+ { 0x1F920, 0x1F927 },
+ { 0x1F930, 0x1F930 },
+ { 0x1F933, 0x1F93E },
+ { 0x1F940, 0x1F94B },
+ { 0x1F950, 0x1F95E },
+ { 0x1F980, 0x1F991 },
+ { 0x1F9C0, 0x1F9C0 },
+ { 0x20000, 0x2FFFD },
+ { 0x30000, 0x3FFFD },
+};
+
+const size_t bc_history_wchars_len =
+ sizeof(bc_history_wchars) / sizeof(bc_history_wchars[0]);
+
+// These are listed in ascending order for efficiency.
+const uint32_t bc_history_combo_chars[] = {
+ 0x0300,0x0301,0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,
+ 0x0308,0x0309,0x030A,0x030B,0x030C,0x030D,0x030E,0x030F,
+ 0x0310,0x0311,0x0312,0x0313,0x0314,0x0315,0x0316,0x0317,
+ 0x0318,0x0319,0x031A,0x031B,0x031C,0x031D,0x031E,0x031F,
+ 0x0320,0x0321,0x0322,0x0323,0x0324,0x0325,0x0326,0x0327,
+ 0x0328,0x0329,0x032A,0x032B,0x032C,0x032D,0x032E,0x032F,
+ 0x0330,0x0331,0x0332,0x0333,0x0334,0x0335,0x0336,0x0337,
+ 0x0338,0x0339,0x033A,0x033B,0x033C,0x033D,0x033E,0x033F,
+ 0x0340,0x0341,0x0342,0x0343,0x0344,0x0345,0x0346,0x0347,
+ 0x0348,0x0349,0x034A,0x034B,0x034C,0x034D,0x034E,0x034F,
+ 0x0350,0x0351,0x0352,0x0353,0x0354,0x0355,0x0356,0x0357,
+ 0x0358,0x0359,0x035A,0x035B,0x035C,0x035D,0x035E,0x035F,
+ 0x0360,0x0361,0x0362,0x0363,0x0364,0x0365,0x0366,0x0367,
+ 0x0368,0x0369,0x036A,0x036B,0x036C,0x036D,0x036E,0x036F,
+ 0x0483,0x0484,0x0485,0x0486,0x0487,0x0591,0x0592,0x0593,
+ 0x0594,0x0595,0x0596,0x0597,0x0598,0x0599,0x059A,0x059B,
+ 0x059C,0x059D,0x059E,0x059F,0x05A0,0x05A1,0x05A2,0x05A3,
+ 0x05A4,0x05A5,0x05A6,0x05A7,0x05A8,0x05A9,0x05AA,0x05AB,
+ 0x05AC,0x05AD,0x05AE,0x05AF,0x05B0,0x05B1,0x05B2,0x05B3,
+ 0x05B4,0x05B5,0x05B6,0x05B7,0x05B8,0x05B9,0x05BA,0x05BB,
+ 0x05BC,0x05BD,0x05BF,0x05C1,0x05C2,0x05C4,0x05C5,0x05C7,
+ 0x0610,0x0611,0x0612,0x0613,0x0614,0x0615,0x0616,0x0617,
+ 0x0618,0x0619,0x061A,0x064B,0x064C,0x064D,0x064E,0x064F,
+ 0x0650,0x0651,0x0652,0x0653,0x0654,0x0655,0x0656,0x0657,
+ 0x0658,0x0659,0x065A,0x065B,0x065C,0x065D,0x065E,0x065F,
+ 0x0670,0x06D6,0x06D7,0x06D8,0x06D9,0x06DA,0x06DB,0x06DC,
+ 0x06DF,0x06E0,0x06E1,0x06E2,0x06E3,0x06E4,0x06E7,0x06E8,
+ 0x06EA,0x06EB,0x06EC,0x06ED,0x0711,0x0730,0x0731,0x0732,
+ 0x0733,0x0734,0x0735,0x0736,0x0737,0x0738,0x0739,0x073A,
+ 0x073B,0x073C,0x073D,0x073E,0x073F,0x0740,0x0741,0x0742,
+ 0x0743,0x0744,0x0745,0x0746,0x0747,0x0748,0x0749,0x074A,
+ 0x07A6,0x07A7,0x07A8,0x07A9,0x07AA,0x07AB,0x07AC,0x07AD,
+ 0x07AE,0x07AF,0x07B0,0x07EB,0x07EC,0x07ED,0x07EE,0x07EF,
+ 0x07F0,0x07F1,0x07F2,0x07F3,0x0816,0x0817,0x0818,0x0819,
+ 0x081B,0x081C,0x081D,0x081E,0x081F,0x0820,0x0821,0x0822,
+ 0x0823,0x0825,0x0826,0x0827,0x0829,0x082A,0x082B,0x082C,
+ 0x082D,0x0859,0x085A,0x085B,0x08D4,0x08D5,0x08D6,0x08D7,
+ 0x08D8,0x08D9,0x08DA,0x08DB,0x08DC,0x08DD,0x08DE,0x08DF,
+ 0x08E0,0x08E1,0x08E3,0x08E4,0x08E5,0x08E6,0x08E7,0x08E8,
+ 0x08E9,0x08EA,0x08EB,0x08EC,0x08ED,0x08EE,0x08EF,0x08F0,
+ 0x08F1,0x08F2,0x08F3,0x08F4,0x08F5,0x08F6,0x08F7,0x08F8,
+ 0x08F9,0x08FA,0x08FB,0x08FC,0x08FD,0x08FE,0x08FF,0x0900,
+ 0x0901,0x0902,0x093A,0x093C,0x0941,0x0942,0x0943,0x0944,
+ 0x0945,0x0946,0x0947,0x0948,0x094D,0x0951,0x0952,0x0953,
+ 0x0954,0x0955,0x0956,0x0957,0x0962,0x0963,0x0981,0x09BC,
+ 0x09C1,0x09C2,0x09C3,0x09C4,0x09CD,0x09E2,0x09E3,0x0A01,
+ 0x0A02,0x0A3C,0x0A41,0x0A42,0x0A47,0x0A48,0x0A4B,0x0A4C,
+ 0x0A4D,0x0A51,0x0A70,0x0A71,0x0A75,0x0A81,0x0A82,0x0ABC,
+ 0x0AC1,0x0AC2,0x0AC3,0x0AC4,0x0AC5,0x0AC7,0x0AC8,0x0ACD,
+ 0x0AE2,0x0AE3,0x0B01,0x0B3C,0x0B3F,0x0B41,0x0B42,0x0B43,
+ 0x0B44,0x0B4D,0x0B56,0x0B62,0x0B63,0x0B82,0x0BC0,0x0BCD,
+ 0x0C00,0x0C3E,0x0C3F,0x0C40,0x0C46,0x0C47,0x0C48,0x0C4A,
+ 0x0C4B,0x0C4C,0x0C4D,0x0C55,0x0C56,0x0C62,0x0C63,0x0C81,
+ 0x0CBC,0x0CBF,0x0CC6,0x0CCC,0x0CCD,0x0CE2,0x0CE3,0x0D01,
+ 0x0D41,0x0D42,0x0D43,0x0D44,0x0D4D,0x0D62,0x0D63,0x0DCA,
+ 0x0DD2,0x0DD3,0x0DD4,0x0DD6,0x0E31,0x0E34,0x0E35,0x0E36,
+ 0x0E37,0x0E38,0x0E39,0x0E3A,0x0E47,0x0E48,0x0E49,0x0E4A,
+ 0x0E4B,0x0E4C,0x0E4D,0x0E4E,0x0EB1,0x0EB4,0x0EB5,0x0EB6,
+ 0x0EB7,0x0EB8,0x0EB9,0x0EBB,0x0EBC,0x0EC8,0x0EC9,0x0ECA,
+ 0x0ECB,0x0ECC,0x0ECD,0x0F18,0x0F19,0x0F35,0x0F37,0x0F39,
+ 0x0F71,0x0F72,0x0F73,0x0F74,0x0F75,0x0F76,0x0F77,0x0F78,
+ 0x0F79,0x0F7A,0x0F7B,0x0F7C,0x0F7D,0x0F7E,0x0F80,0x0F81,
+ 0x0F82,0x0F83,0x0F84,0x0F86,0x0F87,0x0F8D,0x0F8E,0x0F8F,
+ 0x0F90,0x0F91,0x0F92,0x0F93,0x0F94,0x0F95,0x0F96,0x0F97,
+ 0x0F99,0x0F9A,0x0F9B,0x0F9C,0x0F9D,0x0F9E,0x0F9F,0x0FA0,
+ 0x0FA1,0x0FA2,0x0FA3,0x0FA4,0x0FA5,0x0FA6,0x0FA7,0x0FA8,
+ 0x0FA9,0x0FAA,0x0FAB,0x0FAC,0x0FAD,0x0FAE,0x0FAF,0x0FB0,
+ 0x0FB1,0x0FB2,0x0FB3,0x0FB4,0x0FB5,0x0FB6,0x0FB7,0x0FB8,
+ 0x0FB9,0x0FBA,0x0FBB,0x0FBC,0x0FC6,0x102D,0x102E,0x102F,
+ 0x1030,0x1032,0x1033,0x1034,0x1035,0x1036,0x1037,0x1039,
+ 0x103A,0x103D,0x103E,0x1058,0x1059,0x105E,0x105F,0x1060,
+ 0x1071,0x1072,0x1073,0x1074,0x1082,0x1085,0x1086,0x108D,
+ 0x109D,0x135D,0x135E,0x135F,0x1712,0x1713,0x1714,0x1732,
+ 0x1733,0x1734,0x1752,0x1753,0x1772,0x1773,0x17B4,0x17B5,
+ 0x17B7,0x17B8,0x17B9,0x17BA,0x17BB,0x17BC,0x17BD,0x17C6,
+ 0x17C9,0x17CA,0x17CB,0x17CC,0x17CD,0x17CE,0x17CF,0x17D0,
+ 0x17D1,0x17D2,0x17D3,0x17DD,0x180B,0x180C,0x180D,0x1885,
+ 0x1886,0x18A9,0x1920,0x1921,0x1922,0x1927,0x1928,0x1932,
+ 0x1939,0x193A,0x193B,0x1A17,0x1A18,0x1A1B,0x1A56,0x1A58,
+ 0x1A59,0x1A5A,0x1A5B,0x1A5C,0x1A5D,0x1A5E,0x1A60,0x1A62,
+ 0x1A65,0x1A66,0x1A67,0x1A68,0x1A69,0x1A6A,0x1A6B,0x1A6C,
+ 0x1A73,0x1A74,0x1A75,0x1A76,0x1A77,0x1A78,0x1A79,0x1A7A,
+ 0x1A7B,0x1A7C,0x1A7F,0x1AB0,0x1AB1,0x1AB2,0x1AB3,0x1AB4,
+ 0x1AB5,0x1AB6,0x1AB7,0x1AB8,0x1AB9,0x1ABA,0x1ABB,0x1ABC,
+ 0x1ABD,0x1B00,0x1B01,0x1B02,0x1B03,0x1B34,0x1B36,0x1B37,
+ 0x1B38,0x1B39,0x1B3A,0x1B3C,0x1B42,0x1B6B,0x1B6C,0x1B6D,
+ 0x1B6E,0x1B6F,0x1B70,0x1B71,0x1B72,0x1B73,0x1B80,0x1B81,
+ 0x1BA2,0x1BA3,0x1BA4,0x1BA5,0x1BA8,0x1BA9,0x1BAB,0x1BAC,
+ 0x1BAD,0x1BE6,0x1BE8,0x1BE9,0x1BED,0x1BEF,0x1BF0,0x1BF1,
+ 0x1C2C,0x1C2D,0x1C2E,0x1C2F,0x1C30,0x1C31,0x1C32,0x1C33,
+ 0x1C36,0x1C37,0x1CD0,0x1CD1,0x1CD2,0x1CD4,0x1CD5,0x1CD6,
+ 0x1CD7,0x1CD8,0x1CD9,0x1CDA,0x1CDB,0x1CDC,0x1CDD,0x1CDE,
+ 0x1CDF,0x1CE0,0x1CE2,0x1CE3,0x1CE4,0x1CE5,0x1CE6,0x1CE7,
+ 0x1CE8,0x1CED,0x1CF4,0x1CF8,0x1CF9,0x1DC0,0x1DC1,0x1DC2,
+ 0x1DC3,0x1DC4,0x1DC5,0x1DC6,0x1DC7,0x1DC8,0x1DC9,0x1DCA,
+ 0x1DCB,0x1DCC,0x1DCD,0x1DCE,0x1DCF,0x1DD0,0x1DD1,0x1DD2,
+ 0x1DD3,0x1DD4,0x1DD5,0x1DD6,0x1DD7,0x1DD8,0x1DD9,0x1DDA,
+ 0x1DDB,0x1DDC,0x1DDD,0x1DDE,0x1DDF,0x1DE0,0x1DE1,0x1DE2,
+ 0x1DE3,0x1DE4,0x1DE5,0x1DE6,0x1DE7,0x1DE8,0x1DE9,0x1DEA,
+ 0x1DEB,0x1DEC,0x1DED,0x1DEE,0x1DEF,0x1DF0,0x1DF1,0x1DF2,
+ 0x1DF3,0x1DF4,0x1DF5,0x1DFB,0x1DFC,0x1DFD,0x1DFE,0x1DFF,
+ 0x20D0,0x20D1,0x20D2,0x20D3,0x20D4,0x20D5,0x20D6,0x20D7,
+ 0x20D8,0x20D9,0x20DA,0x20DB,0x20DC,0x20E1,0x20E5,0x20E6,
+ 0x20E7,0x20E8,0x20E9,0x20EA,0x20EB,0x20EC,0x20ED,0x20EE,
+ 0x20EF,0x20F0,0x2CEF,0x2CF0,0x2CF1,0x2D7F,0x2DE0,0x2DE1,
+ 0x2DE2,0x2DE3,0x2DE4,0x2DE5,0x2DE6,0x2DE7,0x2DE8,0x2DE9,
+ 0x2DEA,0x2DEB,0x2DEC,0x2DED,0x2DEE,0x2DEF,0x2DF0,0x2DF1,
+ 0x2DF2,0x2DF3,0x2DF4,0x2DF5,0x2DF6,0x2DF7,0x2DF8,0x2DF9,
+ 0x2DFA,0x2DFB,0x2DFC,0x2DFD,0x2DFE,0x2DFF,0x302A,0x302B,
+ 0x302C,0x302D,0x3099,0x309A,0xA66F,0xA674,0xA675,0xA676,
+ 0xA677,0xA678,0xA679,0xA67A,0xA67B,0xA67C,0xA67D,0xA69E,
+ 0xA69F,0xA6F0,0xA6F1,0xA802,0xA806,0xA80B,0xA825,0xA826,
+ 0xA8C4,0xA8C5,0xA8E0,0xA8E1,0xA8E2,0xA8E3,0xA8E4,0xA8E5,
+ 0xA8E6,0xA8E7,0xA8E8,0xA8E9,0xA8EA,0xA8EB,0xA8EC,0xA8ED,
+ 0xA8EE,0xA8EF,0xA8F0,0xA8F1,0xA926,0xA927,0xA928,0xA929,
+ 0xA92A,0xA92B,0xA92C,0xA92D,0xA947,0xA948,0xA949,0xA94A,
+ 0xA94B,0xA94C,0xA94D,0xA94E,0xA94F,0xA950,0xA951,0xA980,
+ 0xA981,0xA982,0xA9B3,0xA9B6,0xA9B7,0xA9B8,0xA9B9,0xA9BC,
+ 0xA9E5,0xAA29,0xAA2A,0xAA2B,0xAA2C,0xAA2D,0xAA2E,0xAA31,
+ 0xAA32,0xAA35,0xAA36,0xAA43,0xAA4C,0xAA7C,0xAAB0,0xAAB2,
+ 0xAAB3,0xAAB4,0xAAB7,0xAAB8,0xAABE,0xAABF,0xAAC1,0xAAEC,
+ 0xAAED,0xAAF6,0xABE5,0xABE8,0xABED,0xFB1E,0xFE00,0xFE01,
+ 0xFE02,0xFE03,0xFE04,0xFE05,0xFE06,0xFE07,0xFE08,0xFE09,
+ 0xFE0A,0xFE0B,0xFE0C,0xFE0D,0xFE0E,0xFE0F,0xFE20,0xFE21,
+ 0xFE22,0xFE23,0xFE24,0xFE25,0xFE26,0xFE27,0xFE28,0xFE29,
+ 0xFE2A,0xFE2B,0xFE2C,0xFE2D,0xFE2E,0xFE2F,
+ 0x101FD,0x102E0,0x10376,0x10377,0x10378,0x10379,0x1037A,0x10A01,
+ 0x10A02,0x10A03,0x10A05,0x10A06,0x10A0C,0x10A0D,0x10A0E,0x10A0F,
+ 0x10A38,0x10A39,0x10A3A,0x10A3F,0x10AE5,0x10AE6,0x11001,0x11038,
+ 0x11039,0x1103A,0x1103B,0x1103C,0x1103D,0x1103E,0x1103F,0x11040,
+ 0x11041,0x11042,0x11043,0x11044,0x11045,0x11046,0x1107F,0x11080,
+ 0x11081,0x110B3,0x110B4,0x110B5,0x110B6,0x110B9,0x110BA,0x11100,
+ 0x11101,0x11102,0x11127,0x11128,0x11129,0x1112A,0x1112B,0x1112D,
+ 0x1112E,0x1112F,0x11130,0x11131,0x11132,0x11133,0x11134,0x11173,
+ 0x11180,0x11181,0x111B6,0x111B7,0x111B8,0x111B9,0x111BA,0x111BB,
+ 0x111BC,0x111BD,0x111BE,0x111CA,0x111CB,0x111CC,0x1122F,0x11230,
+ 0x11231,0x11234,0x11236,0x11237,0x1123E,0x112DF,0x112E3,0x112E4,
+ 0x112E5,0x112E6,0x112E7,0x112E8,0x112E9,0x112EA,0x11300,0x11301,
+ 0x1133C,0x11340,0x11366,0x11367,0x11368,0x11369,0x1136A,0x1136B,
+ 0x1136C,0x11370,0x11371,0x11372,0x11373,0x11374,0x11438,0x11439,
+ 0x1143A,0x1143B,0x1143C,0x1143D,0x1143E,0x1143F,0x11442,0x11443,
+ 0x11444,0x11446,0x114B3,0x114B4,0x114B5,0x114B6,0x114B7,0x114B8,
+ 0x114BA,0x114BF,0x114C0,0x114C2,0x114C3,0x115B2,0x115B3,0x115B4,
+ 0x115B5,0x115BC,0x115BD,0x115BF,0x115C0,0x115DC,0x115DD,0x11633,
+ 0x11634,0x11635,0x11636,0x11637,0x11638,0x11639,0x1163A,0x1163D,
+ 0x1163F,0x11640,0x116AB,0x116AD,0x116B0,0x116B1,0x116B2,0x116B3,
+ 0x116B4,0x116B5,0x116B7,0x1171D,0x1171E,0x1171F,0x11722,0x11723,
+ 0x11724,0x11725,0x11727,0x11728,0x11729,0x1172A,0x1172B,0x11C30,
+ 0x11C31,0x11C32,0x11C33,0x11C34,0x11C35,0x11C36,0x11C38,0x11C39,
+ 0x11C3A,0x11C3B,0x11C3C,0x11C3D,0x11C3F,0x11C92,0x11C93,0x11C94,
+ 0x11C95,0x11C96,0x11C97,0x11C98,0x11C99,0x11C9A,0x11C9B,0x11C9C,
+ 0x11C9D,0x11C9E,0x11C9F,0x11CA0,0x11CA1,0x11CA2,0x11CA3,0x11CA4,
+ 0x11CA5,0x11CA6,0x11CA7,0x11CAA,0x11CAB,0x11CAC,0x11CAD,0x11CAE,
+ 0x11CAF,0x11CB0,0x11CB2,0x11CB3,0x11CB5,0x11CB6,0x16AF0,0x16AF1,
+ 0x16AF2,0x16AF3,0x16AF4,0x16B30,0x16B31,0x16B32,0x16B33,0x16B34,
+ 0x16B35,0x16B36,0x16F8F,0x16F90,0x16F91,0x16F92,0x1BC9D,0x1BC9E,
+ 0x1D167,0x1D168,0x1D169,0x1D17B,0x1D17C,0x1D17D,0x1D17E,0x1D17F,
+ 0x1D180,0x1D181,0x1D182,0x1D185,0x1D186,0x1D187,0x1D188,0x1D189,
+ 0x1D18A,0x1D18B,0x1D1AA,0x1D1AB,0x1D1AC,0x1D1AD,0x1D242,0x1D243,
+ 0x1D244,0x1DA00,0x1DA01,0x1DA02,0x1DA03,0x1DA04,0x1DA05,0x1DA06,
+ 0x1DA07,0x1DA08,0x1DA09,0x1DA0A,0x1DA0B,0x1DA0C,0x1DA0D,0x1DA0E,
+ 0x1DA0F,0x1DA10,0x1DA11,0x1DA12,0x1DA13,0x1DA14,0x1DA15,0x1DA16,
+ 0x1DA17,0x1DA18,0x1DA19,0x1DA1A,0x1DA1B,0x1DA1C,0x1DA1D,0x1DA1E,
+ 0x1DA1F,0x1DA20,0x1DA21,0x1DA22,0x1DA23,0x1DA24,0x1DA25,0x1DA26,
+ 0x1DA27,0x1DA28,0x1DA29,0x1DA2A,0x1DA2B,0x1DA2C,0x1DA2D,0x1DA2E,
+ 0x1DA2F,0x1DA30,0x1DA31,0x1DA32,0x1DA33,0x1DA34,0x1DA35,0x1DA36,
+ 0x1DA3B,0x1DA3C,0x1DA3D,0x1DA3E,0x1DA3F,0x1DA40,0x1DA41,0x1DA42,
+ 0x1DA43,0x1DA44,0x1DA45,0x1DA46,0x1DA47,0x1DA48,0x1DA49,0x1DA4A,
+ 0x1DA4B,0x1DA4C,0x1DA4D,0x1DA4E,0x1DA4F,0x1DA50,0x1DA51,0x1DA52,
+ 0x1DA53,0x1DA54,0x1DA55,0x1DA56,0x1DA57,0x1DA58,0x1DA59,0x1DA5A,
+ 0x1DA5B,0x1DA5C,0x1DA5D,0x1DA5E,0x1DA5F,0x1DA60,0x1DA61,0x1DA62,
+ 0x1DA63,0x1DA64,0x1DA65,0x1DA66,0x1DA67,0x1DA68,0x1DA69,0x1DA6A,
+ 0x1DA6B,0x1DA6C,0x1DA75,0x1DA84,0x1DA9B,0x1DA9C,0x1DA9D,0x1DA9E,
+ 0x1DA9F,0x1DAA1,0x1DAA2,0x1DAA3,0x1DAA4,0x1DAA5,0x1DAA6,0x1DAA7,
+ 0x1DAA8,0x1DAA9,0x1DAAA,0x1DAAB,0x1DAAC,0x1DAAD,0x1DAAE,0x1DAAF,
+ 0x1E000,0x1E001,0x1E002,0x1E003,0x1E004,0x1E005,0x1E006,0x1E008,
+ 0x1E009,0x1E00A,0x1E00B,0x1E00C,0x1E00D,0x1E00E,0x1E00F,0x1E010,
+ 0x1E011,0x1E012,0x1E013,0x1E014,0x1E015,0x1E016,0x1E017,0x1E018,
+ 0x1E01B,0x1E01C,0x1E01D,0x1E01E,0x1E01F,0x1E020,0x1E021,0x1E023,
+ 0x1E024,0x1E026,0x1E027,0x1E028,0x1E029,0x1E02A,0x1E8D0,0x1E8D1,
+ 0x1E8D2,0x1E8D3,0x1E8D4,0x1E8D5,0x1E8D6,0x1E944,0x1E945,0x1E946,
+ 0x1E947,0x1E948,0x1E949,0x1E94A,0xE0100,0xE0101,0xE0102,0xE0103,
+ 0xE0104,0xE0105,0xE0106,0xE0107,0xE0108,0xE0109,0xE010A,0xE010B,
+ 0xE010C,0xE010D,0xE010E,0xE010F,0xE0110,0xE0111,0xE0112,0xE0113,
+ 0xE0114,0xE0115,0xE0116,0xE0117,0xE0118,0xE0119,0xE011A,0xE011B,
+ 0xE011C,0xE011D,0xE011E,0xE011F,0xE0120,0xE0121,0xE0122,0xE0123,
+ 0xE0124,0xE0125,0xE0126,0xE0127,0xE0128,0xE0129,0xE012A,0xE012B,
+ 0xE012C,0xE012D,0xE012E,0xE012F,0xE0130,0xE0131,0xE0132,0xE0133,
+ 0xE0134,0xE0135,0xE0136,0xE0137,0xE0138,0xE0139,0xE013A,0xE013B,
+ 0xE013C,0xE013D,0xE013E,0xE013F,0xE0140,0xE0141,0xE0142,0xE0143,
+ 0xE0144,0xE0145,0xE0146,0xE0147,0xE0148,0xE0149,0xE014A,0xE014B,
+ 0xE014C,0xE014D,0xE014E,0xE014F,0xE0150,0xE0151,0xE0152,0xE0153,
+ 0xE0154,0xE0155,0xE0156,0xE0157,0xE0158,0xE0159,0xE015A,0xE015B,
+ 0xE015C,0xE015D,0xE015E,0xE015F,0xE0160,0xE0161,0xE0162,0xE0163,
+ 0xE0164,0xE0165,0xE0166,0xE0167,0xE0168,0xE0169,0xE016A,0xE016B,
+ 0xE016C,0xE016D,0xE016E,0xE016F,0xE0170,0xE0171,0xE0172,0xE0173,
+ 0xE0174,0xE0175,0xE0176,0xE0177,0xE0178,0xE0179,0xE017A,0xE017B,
+ 0xE017C,0xE017D,0xE017E,0xE017F,0xE0180,0xE0181,0xE0182,0xE0183,
+ 0xE0184,0xE0185,0xE0186,0xE0187,0xE0188,0xE0189,0xE018A,0xE018B,
+ 0xE018C,0xE018D,0xE018E,0xE018F,0xE0190,0xE0191,0xE0192,0xE0193,
+ 0xE0194,0xE0195,0xE0196,0xE0197,0xE0198,0xE0199,0xE019A,0xE019B,
+ 0xE019C,0xE019D,0xE019E,0xE019F,0xE01A0,0xE01A1,0xE01A2,0xE01A3,
+ 0xE01A4,0xE01A5,0xE01A6,0xE01A7,0xE01A8,0xE01A9,0xE01AA,0xE01AB,
+ 0xE01AC,0xE01AD,0xE01AE,0xE01AF,0xE01B0,0xE01B1,0xE01B2,0xE01B3,
+ 0xE01B4,0xE01B5,0xE01B6,0xE01B7,0xE01B8,0xE01B9,0xE01BA,0xE01BB,
+ 0xE01BC,0xE01BD,0xE01BE,0xE01BF,0xE01C0,0xE01C1,0xE01C2,0xE01C3,
+ 0xE01C4,0xE01C5,0xE01C6,0xE01C7,0xE01C8,0xE01C9,0xE01CA,0xE01CB,
+ 0xE01CC,0xE01CD,0xE01CE,0xE01CF,0xE01D0,0xE01D1,0xE01D2,0xE01D3,
+ 0xE01D4,0xE01D5,0xE01D6,0xE01D7,0xE01D8,0xE01D9,0xE01DA,0xE01DB,
+ 0xE01DC,0xE01DD,0xE01DE,0xE01DF,0xE01E0,0xE01E1,0xE01E2,0xE01E3,
+ 0xE01E4,0xE01E5,0xE01E6,0xE01E7,0xE01E8,0xE01E9,0xE01EA,0xE01EB,
+ 0xE01EC,0xE01ED,0xE01EE,0xE01EF,
+};
+
+const size_t bc_history_combo_chars_len =
+ sizeof(bc_history_combo_chars) / sizeof(bc_history_combo_chars[0]);
+
+#if BC_DEBUG_CODE
+BcFile bc_history_debug_fp;
+char *bc_history_debug_buf;
+#endif // BC_DEBUG_CODE
+#endif // BC_ENABLE_HISTORY
+
+const char bc_func_main[] = "(main)";
+const char bc_func_read[] = "(read)";
+
+#if BC_DEBUG_CODE
+const char* bc_inst_names[] = {
+
+#if BC_ENABLED
+ "BC_INST_INC",
+ "BC_INST_DEC",
+#endif // BC_ENABLED
+
+ "BC_INST_NEG",
+ "BC_INST_BOOL_NOT",
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_TRUNC",
+#endif // BC_ENABLE_EXTRA_MATH
+
+ "BC_INST_POWER",
+ "BC_INST_MULTIPLY",
+ "BC_INST_DIVIDE",
+ "BC_INST_MODULUS",
+ "BC_INST_PLUS",
+ "BC_INST_MINUS",
+
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_PLACES",
+
+ "BC_INST_LSHIFT",
+ "BC_INST_RSHIFT",
+#endif // BC_ENABLE_EXTRA_MATH
+
+ "BC_INST_REL_EQ",
+ "BC_INST_REL_LE",
+ "BC_INST_REL_GE",
+ "BC_INST_REL_NE",
+ "BC_INST_REL_LT",
+ "BC_INST_REL_GT",
+
+ "BC_INST_BOOL_OR",
+ "BC_INST_BOOL_AND",
+
+#if BC_ENABLED
+ "BC_INST_ASSIGN_POWER",
+ "BC_INST_ASSIGN_MULTIPLY",
+ "BC_INST_ASSIGN_DIVIDE",
+ "BC_INST_ASSIGN_MODULUS",
+ "BC_INST_ASSIGN_PLUS",
+ "BC_INST_ASSIGN_MINUS",
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_ASSIGN_PLACES",
+ "BC_INST_ASSIGN_LSHIFT",
+ "BC_INST_ASSIGN_RSHIFT",
+#endif // BC_ENABLE_EXTRA_MATH
+ "BC_INST_ASSIGN",
+
+ "BC_INST_ASSIGN_POWER_NO_VAL",
+ "BC_INST_ASSIGN_MULTIPLY_NO_VAL",
+ "BC_INST_ASSIGN_DIVIDE_NO_VAL",
+ "BC_INST_ASSIGN_MODULUS_NO_VAL",
+ "BC_INST_ASSIGN_PLUS_NO_VAL",
+ "BC_INST_ASSIGN_MINUS_NO_VAL",
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_ASSIGN_PLACES_NO_VAL",
+ "BC_INST_ASSIGN_LSHIFT_NO_VAL",
+ "BC_INST_ASSIGN_RSHIFT_NO_VAL",
+#endif // BC_ENABLE_EXTRA_MATH
+#endif // BC_ENABLED
+ "BC_INST_ASSIGN_NO_VAL",
+
+ "BC_INST_NUM",
+ "BC_INST_VAR",
+ "BC_INST_ARRAY_ELEM",
+#if BC_ENABLED
+ "BC_INST_ARRAY",
+#endif // BC_ENABLED
+
+ "BC_INST_ZERO",
+ "BC_INST_ONE",
+
+#if BC_ENABLED
+ "BC_INST_LAST",
+#endif // BC_ENABLED
+ "BC_INST_IBASE",
+ "BC_INST_OBASE",
+ "BC_INST_SCALE",
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_SEED",
+#endif // BC_ENABLE_EXTRA_MATH
+ "BC_INST_LENGTH",
+ "BC_INST_SCALE_FUNC",
+ "BC_INST_SQRT",
+ "BC_INST_ABS",
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_IRAND",
+#endif // BC_ENABLE_EXTRA_MATH
+ "BC_INST_READ",
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_RAND",
+#endif // BC_ENABLE_EXTRA_MATH
+ "BC_INST_MAXIBASE",
+ "BC_INST_MAXOBASE",
+ "BC_INST_MAXSCALE",
+#if BC_ENABLE_EXTRA_MATH
+ "BC_INST_MAXRAND",
+#endif // BC_ENABLE_EXTRA_MATH
+
+ "BC_INST_PRINT",
+ "BC_INST_PRINT_POP",
+ "BC_INST_STR",
+ "BC_INST_PRINT_STR",
+
+#if BC_ENABLED
+ "BC_INST_JUMP",
+ "BC_INST_JUMP_ZERO",
+
+ "BC_INST_CALL",
+
+ "BC_INST_RET",
+ "BC_INST_RET0",
+ "BC_INST_RET_VOID",
+
+ "BC_INST_HALT",
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+ "BC_INST_POP",
+ "BC_INST_POP_EXEC",
+ "BC_INST_MODEXP",
+ "BC_INST_DIVMOD",
+
+ "BC_INST_EXECUTE",
+ "BC_INST_EXEC_COND",
+
+ "BC_INST_ASCIIFY",
+ "BC_INST_PRINT_STREAM",
+
+ "BC_INST_PRINT_STACK",
+ "BC_INST_CLEAR_STACK",
+ "BC_INST_STACK_LEN",
+ "BC_INST_DUPLICATE",
+ "BC_INST_SWAP",
+
+ "BC_INST_LOAD",
+ "BC_INST_PUSH_VAR",
+ "BC_INST_PUSH_TO_VAR",
+
+ "BC_INST_QUIT",
+ "BC_INST_NQUIT",
+#endif // DC_ENABLED
+};
+#endif // BC_DEBUG_CODE
+
+const char bc_parse_zero[2] = "0";
+const char bc_parse_one[2] = "1";
+
+#if BC_ENABLED
+const BcLexKeyword bc_lex_kws[] = {
+ BC_LEX_KW_ENTRY("auto", 4, true),
+ BC_LEX_KW_ENTRY("break", 5, true),
+ BC_LEX_KW_ENTRY("continue", 8, false),
+ BC_LEX_KW_ENTRY("define", 6, true),
+ BC_LEX_KW_ENTRY("for", 3, true),
+ BC_LEX_KW_ENTRY("if", 2, true),
+ BC_LEX_KW_ENTRY("limits", 6, false),
+ BC_LEX_KW_ENTRY("return", 6, true),
+ BC_LEX_KW_ENTRY("while", 5, true),
+ BC_LEX_KW_ENTRY("halt", 4, false),
+ BC_LEX_KW_ENTRY("last", 4, false),
+ BC_LEX_KW_ENTRY("ibase", 5, true),
+ BC_LEX_KW_ENTRY("obase", 5, true),
+ BC_LEX_KW_ENTRY("scale", 5, true),
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("seed", 4, false),
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("length", 6, true),
+ BC_LEX_KW_ENTRY("print", 5, false),
+ BC_LEX_KW_ENTRY("sqrt", 4, true),
+ BC_LEX_KW_ENTRY("abs", 3, false),
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("irand", 5, false),
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("quit", 4, true),
+ BC_LEX_KW_ENTRY("read", 4, false),
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("rand", 4, false),
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("maxibase", 8, false),
+ BC_LEX_KW_ENTRY("maxobase", 8, false),
+ BC_LEX_KW_ENTRY("maxscale", 8, false),
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("maxrand", 7, false),
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_ENTRY("else", 4, false),
+};
+
+const size_t bc_lex_kws_len = sizeof(bc_lex_kws) / sizeof(BcLexKeyword);
+
+// This is an array that corresponds to token types. An entry is
+// true if the token is valid in an expression, false otherwise.
+const uint8_t bc_parse_exprs[] = {
+ BC_PARSE_EXPR_ENTRY(false, false, true, true, true, true, true, true),
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+ BC_PARSE_EXPR_ENTRY(true, true, false, false, true, true, false, false),
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, true, true, false),
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false),
+ BC_PARSE_EXPR_ENTRY(false, true, true, true, true, true, true, false),
+ BC_PARSE_EXPR_ENTRY(true, true, true, false, true, true, true, true),
+ BC_PARSE_EXPR_ENTRY(true, true, false, 0, 0, 0, 0, 0)
+#elif BC_ENABLE_EXTRA_MATH // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+ BC_PARSE_EXPR_ENTRY(true, true, false, false, true, true, false, false),
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, true, true, false),
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false),
+ BC_PARSE_EXPR_ENTRY(false, true, true, true, true, true, false, true),
+ BC_PARSE_EXPR_ENTRY(true, false, true, true, true, true, false, 0),
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_PARSE_EXPR_ENTRY(true, true, true, false, false, true, true, false),
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, true, true),
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false),
+ BC_PARSE_EXPR_ENTRY(false, false, true, true, true, true, true, false),
+ BC_PARSE_EXPR_ENTRY(true, true, false, true, true, true, true, false)
+#endif // BC_ENABLE_EXTRA_MATH
+};
+
+// This is an array of data for operators that correspond to token types.
+const uchar bc_parse_ops[] = {
+ BC_PARSE_OP(0, false), BC_PARSE_OP(0, false),
+ BC_PARSE_OP(1, false), BC_PARSE_OP(1, false),
+#if BC_ENABLE_EXTRA_MATH
+ BC_PARSE_OP(2, false),
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_PARSE_OP(4, false),
+ BC_PARSE_OP(5, true), BC_PARSE_OP(5, true), BC_PARSE_OP(5, true),
+ BC_PARSE_OP(6, true), BC_PARSE_OP(6, true),
+#if BC_ENABLE_EXTRA_MATH
+ BC_PARSE_OP(3, false),
+ BC_PARSE_OP(7, true), BC_PARSE_OP(7, true),
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_PARSE_OP(9, true), BC_PARSE_OP(9, true), BC_PARSE_OP(9, true),
+ BC_PARSE_OP(9, true), BC_PARSE_OP(9, true), BC_PARSE_OP(9, true),
+ BC_PARSE_OP(11, true), BC_PARSE_OP(10, true),
+ BC_PARSE_OP(8, false), BC_PARSE_OP(8, false), BC_PARSE_OP(8, false),
+ BC_PARSE_OP(8, false), BC_PARSE_OP(8, false), BC_PARSE_OP(8, false),
+#if BC_ENABLE_EXTRA_MATH
+ BC_PARSE_OP(8, false), BC_PARSE_OP(8, false), BC_PARSE_OP(8, false),
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_PARSE_OP(8, false),
+};
+
+// These identify what tokens can come after expressions in certain cases.
+const BcParseNext bc_parse_next_expr =
+ BC_PARSE_NEXT(4, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_RBRACE, BC_LEX_EOF);
+const BcParseNext bc_parse_next_param =
+ BC_PARSE_NEXT(2, BC_LEX_RPAREN, BC_LEX_COMMA);
+const BcParseNext bc_parse_next_print =
+ BC_PARSE_NEXT(4, BC_LEX_COMMA, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_EOF);
+const BcParseNext bc_parse_next_rel = BC_PARSE_NEXT(1, BC_LEX_RPAREN);
+const BcParseNext bc_parse_next_elem = BC_PARSE_NEXT(1, BC_LEX_RBRACKET);
+const BcParseNext bc_parse_next_for = BC_PARSE_NEXT(1, BC_LEX_SCOLON);
+const BcParseNext bc_parse_next_read =
+ BC_PARSE_NEXT(2, BC_LEX_NLINE, BC_LEX_EOF);
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+const uint8_t dc_lex_regs[] = {
+ BC_LEX_OP_REL_EQ, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_NE,
+ BC_LEX_OP_REL_LT, BC_LEX_OP_REL_GT, BC_LEX_SCOLON, BC_LEX_COLON,
+ BC_LEX_KW_ELSE, BC_LEX_LOAD, BC_LEX_LOAD_POP, BC_LEX_OP_ASSIGN,
+ BC_LEX_STORE_PUSH,
+};
+
+const size_t dc_lex_regs_len = sizeof(dc_lex_regs) / sizeof(uint8_t);
+
+const uchar dc_lex_tokens[] = {
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_IRAND,
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_INVALID,
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_TRUNC,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_MODULUS, BC_LEX_INVALID,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_RAND,
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_LPAREN, BC_LEX_RPAREN, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS,
+ BC_LEX_INVALID, BC_LEX_OP_MINUS, BC_LEX_INVALID, BC_LEX_OP_DIVIDE,
+ BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID,
+ BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID,
+ BC_LEX_INVALID, BC_LEX_INVALID,
+ BC_LEX_COLON, BC_LEX_SCOLON, BC_LEX_OP_REL_GT, BC_LEX_OP_REL_EQ,
+ BC_LEX_OP_REL_LT, BC_LEX_KW_READ,
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_PLACES,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID,
+ BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_EQ_NO_REG,
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_LSHIFT,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_KW_IBASE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_SEED,
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_SCALE, BC_LEX_LOAD_POP, BC_LEX_OP_BOOL_AND, BC_LEX_OP_BOOL_NOT,
+ BC_LEX_KW_OBASE, BC_LEX_PRINT_STREAM, BC_LEX_NQUIT, BC_LEX_POP,
+ BC_LEX_STORE_PUSH, BC_LEX_KW_MAXIBASE, BC_LEX_KW_MAXOBASE,
+ BC_LEX_KW_MAXSCALE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_KW_MAXRAND,
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_SCALE_FACTOR,
+ BC_LEX_INVALID, BC_LEX_KW_LENGTH, BC_LEX_INVALID, BC_LEX_INVALID,
+ BC_LEX_INVALID, BC_LEX_OP_POWER, BC_LEX_NEG, BC_LEX_INVALID,
+ BC_LEX_ASCIIFY, BC_LEX_KW_ABS, BC_LEX_CLEAR_STACK, BC_LEX_DUPLICATE,
+ BC_LEX_KW_ELSE, BC_LEX_PRINT_STACK, BC_LEX_INVALID,
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_OP_RSHIFT,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_STORE_IBASE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_STORE_SEED,
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_LEX_STORE_SCALE, BC_LEX_LOAD,
+ BC_LEX_OP_BOOL_OR, BC_LEX_PRINT_POP, BC_LEX_STORE_OBASE, BC_LEX_KW_PRINT,
+ BC_LEX_KW_QUIT, BC_LEX_SWAP, BC_LEX_OP_ASSIGN, BC_LEX_INVALID,
+ BC_LEX_INVALID, BC_LEX_KW_SQRT, BC_LEX_INVALID, BC_LEX_EXECUTE,
+ BC_LEX_INVALID, BC_LEX_STACK_LEVEL,
+ BC_LEX_LBRACE, BC_LEX_OP_MODEXP, BC_LEX_RBRACE, BC_LEX_OP_DIVMOD,
+ BC_LEX_INVALID
+};
+
+const uchar dc_parse_insts[] = {
+ BC_INST_INVALID, BC_INST_INVALID,
+#if BC_ENABLED
+ BC_INST_INVALID, BC_INST_INVALID,
+#endif // BC_ENABLED
+ BC_INST_INVALID, BC_INST_BOOL_NOT,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_TRUNC,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_INST_POWER, BC_INST_MULTIPLY, BC_INST_DIVIDE, BC_INST_MODULUS,
+ BC_INST_PLUS, BC_INST_MINUS,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_PLACES,
+ BC_INST_LSHIFT, BC_INST_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+ BC_INST_INVALID, BC_INST_INVALID,
+ BC_INST_BOOL_OR, BC_INST_BOOL_AND,
+#if BC_ENABLED
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+ BC_INST_INVALID, BC_INST_INVALID,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+#endif // BC_ENABLED
+ BC_INST_INVALID,
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GT, BC_INST_REL_LT,
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE,
+ BC_INST_INVALID, BC_INST_REL_LE,
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+#if BC_ENABLED
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+#endif // BC_ENABLED
+ BC_INST_IBASE, BC_INST_OBASE, BC_INST_SCALE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_SEED,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_LENGTH, BC_INST_PRINT,
+ BC_INST_SQRT, BC_INST_ABS,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_IRAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_QUIT, BC_INST_INVALID,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_RAND,
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_MAXIBASE,
+ BC_INST_MAXOBASE, BC_INST_MAXSCALE,
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ BC_INST_MAXRAND,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_INST_INVALID,
+ BC_INST_REL_EQ, BC_INST_MODEXP, BC_INST_DIVMOD, BC_INST_INVALID,
+ BC_INST_EXECUTE, BC_INST_PRINT_STACK, BC_INST_CLEAR_STACK,
+ BC_INST_STACK_LEN, BC_INST_DUPLICATE, BC_INST_SWAP, BC_INST_POP,
+ BC_INST_ASCIIFY, BC_INST_PRINT_STREAM,
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID,
+ BC_INST_PRINT_POP, BC_INST_NQUIT, BC_INST_SCALE_FUNC,
+};
+#endif // DC_ENABLED
+
+#endif // !BC_ENABLE_LIBRARY
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+const BcRandState bc_rand_multiplier = BC_RAND_MULTIPLIER;
+
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+#if BC_LONG_BIT >= 64
+const BcDig bc_num_bigdigMax[] = {
+ 709551616U,
+ 446744073U,
+ 18U,
+};
+const BcDig bc_num_bigdigMax2[] = {
+ 768211456U,
+ 374607431U,
+ 938463463U,
+ 282366920U,
+ 340U,
+};
+#else // BC_LONG_BIT >= 64
+const BcDig bc_num_bigdigMax[] = {
+ 7296U,
+ 9496U,
+ 42U,
+};
+const BcDig bc_num_bigdigMax2[] = {
+ 1616U,
+ 955U,
+ 737U,
+ 6744U,
+ 1844U,
+};
+#endif // BC_LONG_BIT >= 64
+
+const size_t bc_num_bigdigMax_size = sizeof(bc_num_bigdigMax) / sizeof(BcDig);
+const size_t bc_num_bigdigMax2_size = sizeof(bc_num_bigdigMax2) / sizeof(BcDig);
+
+const char bc_num_hex_digits[] = "0123456789ABCDEF";
+
+const BcBigDig bc_num_pow10[BC_BASE_DIGS + 1] = {
+ 1,
+ 10,
+ 100,
+ 1000,
+ 10000,
+#if BC_BASE_DIGS > 4
+ 100000,
+ 1000000,
+ 10000000,
+ 100000000,
+ 1000000000,
+#endif // BC_BASE_DIGS > 4
+};
+
+#if !BC_ENABLE_LIBRARY
+
+const BcNumBinaryOp bc_program_ops[] = {
+ bc_num_pow, bc_num_mul, bc_num_div, bc_num_mod, bc_num_add, bc_num_sub,
+#if BC_ENABLE_EXTRA_MATH
+ bc_num_places, bc_num_lshift, bc_num_rshift,
+#endif // BC_ENABLE_EXTRA_MATH
+};
+
+const BcNumBinaryOpReq bc_program_opReqs[] = {
+ bc_num_powReq, bc_num_mulReq, bc_num_divReq, bc_num_divReq,
+ bc_num_addReq, bc_num_addReq,
+#if BC_ENABLE_EXTRA_MATH
+ bc_num_placesReq, bc_num_placesReq, bc_num_placesReq,
+#endif // BC_ENABLE_EXTRA_MATH
+};
+
+const BcProgramUnary bc_program_unarys[] = {
+ bc_program_negate, bc_program_not,
+#if BC_ENABLE_EXTRA_MATH
+ bc_program_trunc,
+#endif // BC_ENABLE_EXTRA_MATH
+};
+
+const char bc_program_exprs_name[] = "<exprs>";
+
+const char bc_program_stdin_name[] = "<stdin>";
+const char bc_program_ready_msg[] = "ready for more input\n";
+const size_t bc_program_ready_msg_len = sizeof(bc_program_ready_msg) - 1;
+const char bc_program_esc_chars[] = "ab\\efnqrt";
+const char bc_program_esc_seqs[] = "\a\b\\\\\f\n\"\r\t";
+
+#endif // !BC_ENABLE_LIBRARY
diff --git a/contrib/bc/src/dc.c b/contrib/bc/src/dc.c
new file mode 100644
index 000000000000..41c49a08b367
--- /dev/null
+++ b/contrib/bc/src/dc.c
@@ -0,0 +1,56 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The main procedure of dc.
+ *
+ */
+
+#if DC_ENABLED
+
+#include <string.h>
+
+#include <dc.h>
+#include <vm.h>
+
+void dc_main(int argc, char **argv) {
+
+ vm.read_ret = BC_INST_POP_EXEC;
+ vm.help = dc_help;
+ vm.sigmsg = dc_sig_msg;
+ vm.siglen = dc_sig_msg_len;
+
+ vm.next = dc_lex_token;
+ vm.parse = dc_parse_parse;
+ vm.expr = dc_parse_expr;
+
+ bc_vm_boot(argc, argv, "DC_LINE_LENGTH", "DC_ENV_ARGS");
+}
+#endif // DC_ENABLED
diff --git a/contrib/bc/src/dc_lex.c b/contrib/bc/src/dc_lex.c
new file mode 100644
index 000000000000..e9a7d2ca1e4b
--- /dev/null
+++ b/contrib/bc/src/dc_lex.c
@@ -0,0 +1,200 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The lexer for dc.
+ *
+ */
+
+#if DC_ENABLED
+
+#include <ctype.h>
+
+#include <dc.h>
+#include <vm.h>
+
+bool dc_lex_negCommand(BcLex *l) {
+ char c = l->buf[l->i];
+ return !BC_LEX_NUM_CHAR(c, false, false);
+}
+
+static void dc_lex_register(BcLex *l) {
+
+ if (DC_X && isspace(l->buf[l->i - 1])) {
+
+ char c;
+
+ bc_lex_whitespace(l);
+ c = l->buf[l->i];
+
+ if (!isalnum(c) && c != '_')
+ bc_lex_verr(l, BC_ERR_PARSE_CHAR, c);
+
+ l->i += 1;
+ bc_lex_name(l);
+ }
+ else {
+ bc_vec_npop(&l->str, l->str.len);
+ bc_vec_pushByte(&l->str, (uchar) l->buf[l->i - 1]);
+ bc_vec_pushByte(&l->str, '\0');
+ l->t = BC_LEX_NAME;
+ }
+}
+
+static void dc_lex_string(BcLex *l) {
+
+ size_t depth = 1, nls = 0, i = l->i;
+ char c;
+
+ l->t = BC_LEX_STR;
+ bc_vec_npop(&l->str, l->str.len);
+
+ for (; (c = l->buf[i]) && depth; ++i) {
+
+ if (c == '\\') {
+ c = l->buf[++i];
+ if (!c) break;
+ }
+ else {
+ depth += (c == '[');
+ depth -= (c == ']');
+ }
+
+ nls += (c == '\n');
+
+ if (depth) bc_vec_push(&l->str, &c);
+ }
+
+ if (BC_ERR(c == '\0' && depth)) {
+ l->i = i;
+ bc_lex_err(l, BC_ERR_PARSE_STRING);
+ }
+
+ bc_vec_pushByte(&l->str, '\0');
+
+ l->i = i;
+ l->line += nls;
+}
+
+void dc_lex_token(BcLex *l) {
+
+ char c = l->buf[l->i++], c2;
+ size_t i;
+
+ for (i = 0; i < dc_lex_regs_len; ++i) {
+ if (l->last == dc_lex_regs[i]) {
+ dc_lex_register(l);
+ return;
+ }
+ }
+
+ if (c >= '"' && c <= '~' &&
+ (l->t = dc_lex_tokens[(c - '"')]) != BC_LEX_INVALID)
+ {
+ return;
+ }
+
+ // This is the workhorse of the lexer.
+ switch (c) {
+
+ case '\0':
+ case '\n':
+ case '\t':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ {
+ bc_lex_commonTokens(l, c);
+ break;
+ }
+
+ case '!':
+ {
+ c2 = l->buf[l->i];
+
+ if (c2 == '=') l->t = BC_LEX_OP_REL_NE;
+ else if (c2 == '<') l->t = BC_LEX_OP_REL_LE;
+ else if (c2 == '>') l->t = BC_LEX_OP_REL_GE;
+ else bc_lex_invalidChar(l, c);
+
+ l->i += 1;
+ break;
+ }
+
+ case '#':
+ {
+ bc_lex_lineComment(l);
+ break;
+ }
+
+ case '.':
+ {
+ c2 = l->buf[l->i];
+ if (BC_NO_ERR(BC_LEX_NUM_CHAR(c2, true, false)))
+ bc_lex_number(l, c);
+ else bc_lex_invalidChar(l, c);
+ break;
+ }
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ {
+ bc_lex_number(l, c);
+ break;
+ }
+
+ case '[':
+ {
+ dc_lex_string(l);
+ break;
+ }
+
+ default:
+ {
+ bc_lex_invalidChar(l, c);
+ }
+ }
+}
+#endif // DC_ENABLED
diff --git a/contrib/bc/src/dc_parse.c b/contrib/bc/src/dc_parse.c
new file mode 100644
index 000000000000..81191541fa83
--- /dev/null
+++ b/contrib/bc/src/dc_parse.c
@@ -0,0 +1,236 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The parser for dc.
+ *
+ */
+
+#if DC_ENABLED
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include <dc.h>
+#include <program.h>
+#include <vm.h>
+
+static void dc_parse_register(BcParse *p, bool var) {
+
+ bc_lex_next(&p->l);
+ if (p->l.t != BC_LEX_NAME) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_parse_pushName(p, p->l.str.v, var);
+}
+
+static inline void dc_parse_string(BcParse *p) {
+ bc_parse_addString(p);
+ bc_lex_next(&p->l);
+}
+
+static void dc_parse_mem(BcParse *p, uchar inst, bool name, bool store) {
+
+ bc_parse_push(p, inst);
+
+ if (name) dc_parse_register(p, inst != BC_INST_ARRAY_ELEM);
+
+ if (store) {
+ bc_parse_push(p, BC_INST_SWAP);
+ bc_parse_push(p, BC_INST_ASSIGN_NO_VAL);
+ }
+
+ bc_lex_next(&p->l);
+}
+
+static void dc_parse_cond(BcParse *p, uchar inst) {
+
+ bc_parse_push(p, inst);
+ bc_parse_push(p, BC_INST_EXEC_COND);
+
+ dc_parse_register(p, true);
+
+ bc_lex_next(&p->l);
+
+ if (p->l.t == BC_LEX_KW_ELSE) {
+ dc_parse_register(p, true);
+ bc_lex_next(&p->l);
+ }
+ else bc_parse_pushIndex(p, SIZE_MAX);
+}
+
+static void dc_parse_token(BcParse *p, BcLexType t, uint8_t flags) {
+
+ uchar inst;
+ bool assign, get_token = false;
+
+ switch (t) {
+
+ case BC_LEX_OP_REL_EQ:
+ case BC_LEX_OP_REL_LE:
+ case BC_LEX_OP_REL_GE:
+ case BC_LEX_OP_REL_NE:
+ case BC_LEX_OP_REL_LT:
+ case BC_LEX_OP_REL_GT:
+ {
+ inst = (uchar) (t - BC_LEX_OP_REL_EQ + BC_INST_REL_EQ);
+ dc_parse_cond(p, inst);
+ break;
+ }
+
+ case BC_LEX_SCOLON:
+ case BC_LEX_COLON:
+ {
+ dc_parse_mem(p, BC_INST_ARRAY_ELEM, true, t == BC_LEX_COLON);
+ break;
+ }
+
+ case BC_LEX_STR:
+ {
+ dc_parse_string(p);
+ break;
+ }
+
+ case BC_LEX_NEG:
+ {
+ if (dc_lex_negCommand(&p->l)) {
+ bc_parse_push(p, BC_INST_NEG);
+ get_token = true;
+ break;
+ }
+
+ bc_lex_next(&p->l);
+ }
+ // Fallthrough.
+ BC_FALLTHROUGH
+
+ case BC_LEX_NUMBER:
+ {
+ bc_parse_number(p);
+
+ if (t == BC_LEX_NEG) bc_parse_push(p, BC_INST_NEG);
+ get_token = true;
+
+ break;
+ }
+
+ case BC_LEX_KW_READ:
+ {
+ if (BC_ERR(flags & BC_PARSE_NOREAD))
+ bc_parse_err(p, BC_ERR_EXEC_REC_READ);
+ else bc_parse_push(p, BC_INST_READ);
+ get_token = true;
+ break;
+ }
+
+ case BC_LEX_OP_ASSIGN:
+ case BC_LEX_STORE_PUSH:
+ {
+ assign = t == BC_LEX_OP_ASSIGN;
+ inst = assign ? BC_INST_VAR : BC_INST_PUSH_TO_VAR;
+ dc_parse_mem(p, inst, true, assign);
+ break;
+ }
+
+ case BC_LEX_LOAD:
+ case BC_LEX_LOAD_POP:
+ {
+ inst = t == BC_LEX_LOAD_POP ? BC_INST_PUSH_VAR : BC_INST_LOAD;
+ dc_parse_mem(p, inst, true, false);
+ break;
+ }
+
+ case BC_LEX_STORE_IBASE:
+ case BC_LEX_STORE_OBASE:
+ case BC_LEX_STORE_SCALE:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_STORE_SEED:
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ inst = (uchar) (t - BC_LEX_STORE_IBASE + BC_INST_IBASE);
+ dc_parse_mem(p, inst, false, true);
+ break;
+ }
+
+ default:
+ {
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ }
+ }
+
+ if (get_token) bc_lex_next(&p->l);
+}
+
+void dc_parse_expr(BcParse *p, uint8_t flags) {
+
+ BcInst inst;
+ BcLexType t;
+ bool have_expr = false, need_expr = (flags & BC_PARSE_NOREAD) != 0;
+
+ while ((t = p->l.t) != BC_LEX_EOF) {
+
+ if (t == BC_LEX_NLINE) {
+ bc_lex_next(&p->l);
+ continue;
+ }
+
+ inst = dc_parse_insts[t];
+
+ if (inst != BC_INST_INVALID) {
+ bc_parse_push(p, inst);
+ bc_lex_next(&p->l);
+ }
+ else dc_parse_token(p, t, flags);
+
+ have_expr = true;
+ }
+
+ if (BC_ERR(need_expr && !have_expr))
+ bc_vm_err(BC_ERR_EXEC_READ_EXPR);
+ else if (p->l.t == BC_LEX_EOF && (flags & BC_PARSE_NOCALL))
+ bc_parse_push(p, BC_INST_POP_EXEC);
+}
+
+void dc_parse_parse(BcParse *p) {
+
+ assert(p != NULL);
+
+ BC_SETJMP(exit);
+
+ if (BC_ERR(p->l.t == BC_LEX_EOF)) bc_parse_err(p, BC_ERR_PARSE_EOF);
+ else dc_parse_expr(p, 0);
+
+exit:
+ BC_SIG_MAYLOCK;
+ if (BC_ERR(vm.status || vm.sig)) bc_parse_reset(p);
+ BC_LONGJMP_CONT;
+}
+#endif // DC_ENABLED
diff --git a/contrib/bc/src/file.c b/contrib/bc/src/file.c
new file mode 100644
index 000000000000..1d4d390f89a4
--- /dev/null
+++ b/contrib/bc/src/file.c
@@ -0,0 +1,225 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code for implementing buffered I/O on my own terms.
+ *
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <file.h>
+#include <vm.h>
+
+static void bc_file_ultoa(unsigned long long val, char buf[BC_FILE_ULL_LENGTH])
+{
+ char buf2[BC_FILE_ULL_LENGTH];
+ size_t i, len;
+
+ memset(buf2, 0, BC_FILE_ULL_LENGTH);
+
+ // The i = 1 is to ensure that there is a null byte at the end.
+ for (i = 1; val; ++i) {
+ unsigned long long mod = val % 10;
+ buf2[i] = ((char) mod) + '0';
+ val /= 10;
+ }
+
+ len = i;
+
+ for (i = 0; i < len; ++i) buf[i] = buf2[len - i - 1];
+}
+
+static BcStatus bc_file_output(int fd, const char *buf, size_t n) {
+
+ size_t bytes = 0;
+ sig_atomic_t lock;
+
+ BC_SIG_TRYLOCK(lock);
+
+ while (bytes < n) {
+
+ ssize_t written = write(fd, buf + bytes, n - bytes);
+
+ if (BC_ERR(written == -1))
+ return errno == EPIPE ? BC_STATUS_EOF : BC_STATUS_ERROR_FATAL;
+
+ bytes += (size_t) written;
+ }
+
+ BC_SIG_TRYUNLOCK(lock);
+
+ return BC_STATUS_SUCCESS;
+}
+
+BcStatus bc_file_flushErr(BcFile *restrict f) {
+
+ BcStatus s;
+
+ if (f->len) {
+ s = bc_file_output(f->fd, f->buf, f->len);
+ f->len = 0;
+ }
+ else s = BC_STATUS_SUCCESS;
+
+ return s;
+}
+
+void bc_file_flush(BcFile *restrict f) {
+
+ BcStatus s = bc_file_flushErr(f);
+
+ if (BC_ERR(s)) {
+
+ if (s == BC_STATUS_EOF) {
+ vm.status = (sig_atomic_t) s;
+ BC_VM_JMP;
+ }
+ else bc_vm_err(BC_ERR_FATAL_IO_ERR);
+ }
+}
+
+void bc_file_write(BcFile *restrict f, const char *buf, size_t n) {
+
+ if (n > f->cap - f->len) {
+ bc_file_flush(f);
+ assert(!f->len);
+ }
+
+ if (BC_UNLIKELY(n > f->cap - f->len)) bc_file_output(f->fd, buf, n);
+ else {
+ memcpy(f->buf + f->len, buf, n);
+ f->len += n;
+ }
+}
+
+void bc_file_printf(BcFile *restrict f, const char *fmt, ...) {
+
+ va_list args;
+
+ va_start(args, fmt);
+ bc_file_vprintf(f, fmt, args);
+ va_end(args);
+}
+
+void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) {
+
+ char *percent;
+ const char *ptr = fmt;
+ char buf[BC_FILE_ULL_LENGTH];
+
+ while ((percent = strchr(ptr, '%')) != NULL) {
+
+ char c;
+
+ if (percent != ptr) {
+ size_t len = (size_t) (percent - ptr);
+ bc_file_write(f, ptr, len);
+ }
+
+ c = percent[1];
+
+ if (c == 'c') {
+
+ uchar uc = (uchar) va_arg(args, int);
+
+ bc_file_putchar(f, uc);
+ }
+ else if (c == 's') {
+
+ char *s = va_arg(args, char*);
+
+ bc_file_puts(f, s);
+ }
+#if BC_DEBUG_CODE
+ else if (c == 'd') {
+
+ int d = va_arg(args, int);
+
+ if (d < 0) {
+ bc_file_putchar(f, '-');
+ d = -d;
+ }
+
+ if (!d) bc_file_putchar(f, '0');
+ else {
+ bc_file_ultoa((unsigned long long) d, buf);
+ bc_file_puts(f, buf);
+ }
+ }
+#endif // BC_DEBUG_CODE
+ else {
+
+ unsigned long long ull;
+
+ assert((c == 'l' || c == 'z') && percent[2] == 'u');
+
+ 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');
+ else {
+ bc_file_ultoa(ull, buf);
+ bc_file_puts(f, buf);
+ }
+ }
+
+ ptr = percent + 2 + (c == 'l' || c == 'z');
+ }
+
+ if (ptr[0]) bc_file_puts(f, ptr);
+}
+
+void bc_file_puts(BcFile *restrict f, const char *str) {
+ bc_file_write(f, str, strlen(str));
+}
+
+void bc_file_putchar(BcFile *restrict f, uchar c) {
+ if (f->len == f->cap) bc_file_flush(f);
+ assert(f->len < f->cap);
+ f->buf[f->len] = (char) c;
+ f->len += 1;
+}
+
+void bc_file_init(BcFile *f, int fd, char *buf, size_t cap) {
+ BC_SIG_ASSERT_LOCKED;
+ f->fd = fd;
+ f->buf = buf;
+ f->len = 0;
+ f->cap = cap;
+}
+
+void bc_file_free(BcFile *f) {
+ BC_SIG_ASSERT_LOCKED;
+ bc_file_flush(f);
+}
diff --git a/contrib/bc/src/history.c b/contrib/bc/src/history.c
new file mode 100644
index 000000000000..ae4b42d326c0
--- /dev/null
+++ b/contrib/bc/src/history.c
@@ -0,0 +1,1449 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Adapted from the following:
+ *
+ * linenoise.c -- guerrilla line editing library against the idea that a
+ * line editing lib needs to be 20,000 lines of C code.
+ *
+ * You can find the original source code at:
+ * http://github.com/antirez/linenoise
+ *
+ * You can find the fork that this code is based on at:
+ * https://github.com/rain-1/linenoise-mob
+ *
+ * ------------------------------------------------------------------------
+ *
+ * This code is also under the following license:
+ *
+ * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * 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.
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Does a number of crazy assumptions that happen to be true in 99.9999% of
+ * the 2010 UNIX computers around.
+ *
+ * References:
+ * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
+ * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html
+ *
+ * Todo list:
+ * - Filter bogus Ctrl+<char> combinations.
+ * - Win32 support
+ *
+ * Bloat:
+ * - History search like Ctrl+r in readline?
+ *
+ * List of escape sequences used by this program, we do everything just
+ * with three sequences. In order to be so cheap we may have some
+ * flickering effect with some slow terminal, but the lesser sequences
+ * the more compatible.
+ *
+ * EL (Erase Line)
+ * Sequence: ESC [ n K
+ * Effect: if n is 0 or missing, clear from cursor to end of line
+ * Effect: if n is 1, clear from beginning of line to cursor
+ * Effect: if n is 2, clear entire line
+ *
+ * CUF (CUrsor Forward)
+ * Sequence: ESC [ n C
+ * Effect: moves cursor forward n chars
+ *
+ * CUB (CUrsor Backward)
+ * Sequence: ESC [ n D
+ * Effect: moves cursor backward n chars
+ *
+ * The following is used to get the terminal width if getting
+ * the width with the TIOCGWINSZ ioctl fails
+ *
+ * DSR (Device Status Report)
+ * Sequence: ESC [ 6 n
+ * Effect: reports the current cusor position as ESC [ n ; m R
+ * where n is the row and m is the column
+ *
+ * When multi line mode is enabled, we also use two additional escape
+ * sequences. However multi line editing is disabled by default.
+ *
+ * CUU (CUrsor Up)
+ * Sequence: ESC [ n A
+ * Effect: moves cursor up of n chars.
+ *
+ * CUD (CUrsor Down)
+ * Sequence: ESC [ n B
+ * Effect: moves cursor down of n chars.
+ *
+ * When bc_history_clearScreen() is called, two additional escape sequences
+ * are used in order to clear the screen and position the cursor at home
+ * position.
+ *
+ * CUP (CUrsor Position)
+ * Sequence: ESC [ H
+ * Effect: moves the cursor to upper left corner
+ *
+ * ED (Erase Display)
+ * Sequence: ESC [ 2 J
+ * Effect: clear the whole screen
+ *
+ * *****************************************************************************
+ *
+ * Code for line history.
+ *
+ */
+
+#if BC_ENABLE_HISTORY
+
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+
+#include <signal.h>
+
+#include <termios.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+
+#include <vector.h>
+#include <history.h>
+#include <read.h>
+#include <file.h>
+#include <vm.h>
+
+static void bc_history_add(BcHistory *h, char *line);
+static void bc_history_add_empty(BcHistory *h);
+
+/**
+ * Check if the code is a wide character.
+ */
+static bool bc_history_wchar(uint32_t cp) {
+
+ size_t i;
+
+ for (i = 0; i < bc_history_wchars_len; ++i) {
+
+ // Ranges are listed in ascending order. Therefore, once the
+ // whole range is higher than the codepoint we're testing, the
+ // codepoint won't be found in any remaining range => bail early.
+ if (bc_history_wchars[i][0] > cp) return false;
+
+ // Test this range.
+ if (bc_history_wchars[i][0] <= cp && cp <= bc_history_wchars[i][1])
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Check if the code is a combining character.
+ */
+static bool bc_history_comboChar(uint32_t cp) {
+
+ size_t i;
+
+ for (i = 0; i < bc_history_combo_chars_len; ++i) {
+
+ // Combining chars are listed in ascending order, so once we pass
+ // the codepoint of interest, we know it's not a combining char.
+ if (bc_history_combo_chars[i] > cp) return false;
+ if (bc_history_combo_chars[i] == cp) return true;
+ }
+
+ return false;
+}
+
+/**
+ * Get length of previous UTF8 character.
+ */
+static size_t bc_history_prevCharLen(const char *buf, size_t pos) {
+ size_t end = pos;
+ for (pos -= 1; pos < end && (buf[pos] & 0xC0) == 0x80; --pos);
+ return end - (pos >= end ? 0 : pos);
+}
+
+/**
+ * Convert UTF-8 to Unicode code point.
+ */
+static size_t bc_history_codePoint(const char *s, size_t len, uint32_t *cp) {
+
+ if (len) {
+
+ uchar byte = (uchar) s[0];
+
+ if ((byte & 0x80) == 0) {
+ *cp = byte;
+ return 1;
+ }
+ else if ((byte & 0xE0) == 0xC0) {
+
+ if (len >= 2) {
+ *cp = (((uint32_t) (s[0] & 0x1F)) << 6) |
+ ((uint32_t) (s[1] & 0x3F));
+ return 2;
+ }
+ }
+ else if ((byte & 0xF0) == 0xE0) {
+
+ if (len >= 3) {
+ *cp = (((uint32_t) (s[0] & 0x0F)) << 12) |
+ (((uint32_t) (s[1] & 0x3F)) << 6) |
+ ((uint32_t) (s[2] & 0x3F));
+ return 3;
+ }
+ }
+ else if ((byte & 0xF8) == 0xF0) {
+
+ if (len >= 4) {
+ *cp = (((uint32_t) (s[0] & 0x07)) << 18) |
+ (((uint32_t) (s[1] & 0x3F)) << 12) |
+ (((uint32_t) (s[2] & 0x3F)) << 6) |
+ ((uint32_t) (s[3] & 0x3F));
+ return 4;
+ }
+ }
+ else {
+ *cp = 0xFFFD;
+ return 1;
+ }
+ }
+
+ *cp = 0;
+
+ return 1;
+}
+
+/**
+ * Get length of next grapheme.
+ */
+static size_t bc_history_nextLen(const char *buf, size_t buf_len,
+ size_t pos, size_t *col_len)
+{
+ uint32_t cp;
+ size_t beg = pos;
+ size_t len = bc_history_codePoint(buf + pos, buf_len - pos, &cp);
+
+ if (bc_history_comboChar(cp)) {
+ // Currently unreachable?
+ return 0;
+ }
+
+ if (col_len != NULL) *col_len = bc_history_wchar(cp) ? 2 : 1;
+
+ pos += len;
+
+ while (pos < buf_len) {
+
+ len = bc_history_codePoint(buf + pos, buf_len - pos, &cp);
+
+ if (!bc_history_comboChar(cp)) return pos - beg;
+
+ pos += len;
+ }
+
+ return pos - beg;
+}
+
+/**
+ * Get length of previous grapheme.
+ */
+static size_t bc_history_prevLen(const char *buf, size_t pos, size_t *col_len) {
+
+ size_t end = pos;
+
+ while (pos > 0) {
+
+ uint32_t cp;
+ size_t len = bc_history_prevCharLen(buf, pos);
+
+ pos -= len;
+ bc_history_codePoint(buf + pos, len, &cp);
+
+ if (!bc_history_comboChar(cp)) {
+ if (col_len != NULL) *col_len = 1 + (bc_history_wchar(cp) != 0);
+ return end - pos;
+ }
+ }
+
+ // Currently unreachable?
+ return 0;
+}
+
+static ssize_t bc_history_read(char *buf, size_t n) {
+
+ ssize_t ret;
+
+ BC_SIG_LOCK;
+
+ do {
+ ret = read(STDIN_FILENO, buf, n);
+ } while (ret == EINTR);
+
+ BC_SIG_UNLOCK;
+
+ return ret;
+}
+
+/**
+ * Read a Unicode code point from a file.
+ */
+static BcStatus bc_history_readCode(char *buf, size_t buf_len,
+ uint32_t *cp, size_t *nread)
+{
+ ssize_t n;
+
+ assert(buf_len >= 1);
+
+ n = bc_history_read(buf, 1);
+ if (BC_ERR(n <= 0)) goto err;
+
+ uchar byte = (uchar) buf[0];
+
+ if ((byte & 0x80) != 0) {
+
+ if ((byte & 0xE0) == 0xC0) {
+ assert(buf_len >= 2);
+ n = bc_history_read(buf + 1, 1);
+ if (BC_ERR(n <= 0)) goto err;
+ }
+ else if ((byte & 0xF0) == 0xE0) {
+ assert(buf_len >= 3);
+ n = bc_history_read(buf + 1, 2);
+ if (BC_ERR(n <= 0)) goto err;
+ }
+ else if ((byte & 0xF8) == 0xF0) {
+ assert(buf_len >= 3);
+ n = bc_history_read(buf + 1, 3);
+ if (BC_ERR(n <= 0)) goto err;
+ }
+ else {
+ n = -1;
+ goto err;
+ }
+ }
+
+ *nread = bc_history_codePoint(buf, buf_len, cp);
+
+ return BC_STATUS_SUCCESS;
+
+err:
+ if (BC_ERR(n < 0)) bc_vm_err(BC_ERR_FATAL_IO_ERR);
+ else *nread = (size_t) n;
+ return BC_STATUS_EOF;
+}
+
+/**
+ * Get column length from begining of buffer to current byte position.
+ */
+static size_t bc_history_colPos(const char *buf, size_t buf_len, size_t pos) {
+
+ size_t ret = 0, off = 0;
+
+ while (off < pos) {
+
+ size_t col_len, len;
+
+ len = bc_history_nextLen(buf, buf_len, off, &col_len);
+
+ off += len;
+ ret += col_len;
+ }
+
+ return ret;
+}
+
+/**
+ * Return true if the terminal name is in the list of terminals we know are
+ * not able to understand basic escape sequences.
+ */
+static inline bool bc_history_isBadTerm(void) {
+
+ size_t i;
+ char *term = getenv("TERM");
+
+ if (term == NULL) return false;
+
+ for (i = 0; bc_history_bad_terms[i]; ++i) {
+ if (!strcasecmp(term, bc_history_bad_terms[i])) return true;
+ }
+
+ return false;
+}
+
+/**
+ * Raw mode: 1960's black magic.
+ */
+static void bc_history_enableRaw(BcHistory *h) {
+
+ struct termios raw;
+ int err;
+
+ assert(BC_TTYIN);
+
+ if (h->rawMode) return;
+
+ BC_SIG_LOCK;
+
+ if (BC_ERR(tcgetattr(STDIN_FILENO, &h->orig_termios) == -1))
+ bc_vm_err(BC_ERR_FATAL_IO_ERR);
+
+ BC_SIG_UNLOCK;
+
+ // Modify the original mode.
+ raw = h->orig_termios;
+
+ // Input modes: no break, no CR to NL, no parity check, no strip char,
+ // no start/stop output control.
+ raw.c_iflag &= (unsigned int) (~(BRKINT | ICRNL | INPCK | ISTRIP | IXON));
+
+ // Control modes - set 8 bit chars.
+ raw.c_cflag |= (CS8);
+
+ // Local modes - choing off, canonical off, no extended functions,
+ // no signal chars (^Z,^C).
+ raw.c_lflag &= (unsigned int) (~(ECHO | ICANON | IEXTEN | ISIG));
+
+ // Control chars - set return condition: min number of bytes and timer.
+ // We want read to give every single byte, w/o timeout (1 byte, no timer).
+ raw.c_cc[VMIN] = 1;
+ raw.c_cc[VTIME] = 0;
+
+ BC_SIG_LOCK;
+
+ // Put terminal in raw mode after flushing.
+ do {
+ err = tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+ } while (BC_ERR(err < 0) && errno == EINTR);
+
+ BC_SIG_UNLOCK;
+
+ if (BC_ERR(err < 0)) bc_vm_err(BC_ERR_FATAL_IO_ERR);
+
+ h->rawMode = true;
+}
+
+static void bc_history_disableRaw(BcHistory *h) {
+
+ sig_atomic_t lock;
+
+ // Don't even check the return value as it's too late.
+ if (!h->rawMode) return;
+
+ BC_SIG_TRYLOCK(lock);
+
+ if (BC_ERR(tcsetattr(STDIN_FILENO, TCSAFLUSH, &h->orig_termios) != -1))
+ h->rawMode = false;
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+/**
+ * Use the ESC [6n escape sequence to query the horizontal cursor position
+ * and return it. On error -1 is returned, on success the position of the
+ * cursor.
+ */
+static size_t bc_history_cursorPos(void) {
+
+ char buf[BC_HIST_SEQ_SIZE];
+ char *ptr, *ptr2;
+ size_t cols, rows, i;
+
+ // Report cursor location.
+ bc_file_write(&vm.fout, "\x1b[6n", 4);
+ bc_file_flush(&vm.fout);
+
+ // Read the response: ESC [ rows ; cols R.
+ for (i = 0; i < sizeof(buf) - 1; ++i) {
+ if (bc_history_read(buf + i, 1) != 1 || buf[i] == 'R') break;
+ }
+
+ buf[i] = '\0';
+
+ if (BC_ERR(buf[0] != BC_ACTION_ESC || buf[1] != '[')) return SIZE_MAX;
+
+ // Parse it.
+ ptr = buf + 2;
+ rows = strtoul(ptr, &ptr2, 10);
+
+ if (BC_ERR(!rows || ptr2[0] != ';')) return SIZE_MAX;
+
+ ptr = ptr2 + 1;
+ cols = strtoul(ptr, NULL, 10);
+
+ if (BC_ERR(!cols)) return SIZE_MAX;
+
+ return cols <= UINT16_MAX ? cols : 0;
+}
+
+/**
+ * Try to get the number of columns in the current terminal, or assume 80
+ * if it fails.
+ */
+static size_t bc_history_columns(void) {
+
+ struct winsize ws;
+ int ret;
+
+ BC_SIG_LOCK;
+
+ ret = ioctl(vm.fout.fd, TIOCGWINSZ, &ws);
+
+ BC_SIG_UNLOCK;
+
+ if (BC_ERR(ret == -1 || !ws.ws_col)) {
+
+ // Calling ioctl() failed. Try to query the terminal itself.
+ size_t start, cols;
+
+ // Get the initial position so we can restore it later.
+ start = bc_history_cursorPos();
+ 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);
+ 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);
+ }
+
+ return cols;
+ }
+
+ return ws.ws_col;
+}
+
+#if BC_ENABLE_PROMPT
+/**
+ * Check if text is an ANSI escape sequence.
+ */
+static bool bc_history_ansiEscape(const char *buf, size_t buf_len, size_t *len)
+{
+ if (buf_len > 2 && !memcmp("\033[", buf, 2)) {
+
+ size_t off = 2;
+
+ while (off < buf_len) {
+
+ char c = buf[off++];
+
+ if ((c >= 'A' && c <= 'K' && c != 'I') ||
+ c == 'S' || c == 'T' || c == 'f' || c == 'm')
+ {
+ *len = off;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Get column length of prompt text.
+ */
+static size_t bc_history_promptColLen(const char *prompt, size_t plen) {
+
+ char buf[BC_HIST_MAX_LINE + 1];
+ size_t buf_len = 0, off = 0;
+
+ while (off < plen) {
+
+ size_t len;
+
+ if (bc_history_ansiEscape(prompt + off, plen - off, &len)) {
+ off += len;
+ continue;
+ }
+
+ buf[buf_len++] = prompt[off++];
+ }
+
+ return bc_history_colPos(buf, buf_len, buf_len);
+}
+#endif // BC_ENABLE_PROMPT
+
+/**
+ * Rewrites the currently edited line accordingly to the buffer content,
+ * cursor position, and number of columns of the terminal.
+ */
+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);
+
+ while(h->pcol + bc_history_colPos(buf, len, pos) >= h->cols) {
+
+ size_t chlen = bc_history_nextLen(buf, len, 0, NULL);
+
+ buf += chlen;
+ len -= chlen;
+ pos -= chlen;
+ }
+
+ while (h->pcol + bc_history_colPos(buf, len, len) > h->cols)
+ len -= bc_history_prevLen(buf, len, NULL);
+
+ // Cursor to left edge.
+ bc_file_write(&vm.fout, "\r", 1);
+
+ // Write the prompt, if desired.
+#if BC_ENABLE_PROMPT
+ if (BC_USE_PROMPT) bc_file_write(&vm.fout, h->prompt, h->plen);
+#endif // BC_ENABLE_PROMPT
+
+ bc_file_write(&vm.fout, buf, BC_HIST_BUF_LEN(h));
+
+ // Erase to right.
+ bc_file_write(&vm.fout, "\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);
+}
+
+/**
+ * Insert the character 'c' at cursor current position.
+ */
+static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen)
+{
+ bc_vec_grow(&h->buf, clen);
+
+ if (h->pos == BC_HIST_BUF_LEN(h)) {
+
+ size_t colpos = 0, len;
+
+ memcpy(bc_vec_item(&h->buf, h->pos), cbuf, clen);
+
+ h->pos += clen;
+ h->buf.len += clen - 1;
+ bc_vec_pushByte(&h->buf, '\0');
+
+ len = BC_HIST_BUF_LEN(h);
+#if BC_ENABLE_PROMPT
+ colpos = bc_history_promptColLen(h->prompt, h->plen);
+#endif // BC_ENABLE_PROMPT
+ colpos += bc_history_colPos(h->buf.v, len, len);
+
+ 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);
+ }
+ else bc_history_refresh(h);
+ }
+ else {
+
+ size_t amt = BC_HIST_BUF_LEN(h) - h->pos;
+
+ memmove(h->buf.v + h->pos + clen, h->buf.v + h->pos, amt);
+ memcpy(h->buf.v + h->pos, cbuf, clen);
+
+ h->pos += clen;
+ h->buf.len += clen;
+ h->buf.v[BC_HIST_BUF_LEN(h)] = '\0';
+
+ bc_history_refresh(h);
+ }
+}
+
+/**
+ * Move cursor to the left.
+ */
+static void bc_history_edit_left(BcHistory *h) {
+
+ if (h->pos <= 0) return;
+
+ h->pos -= bc_history_prevLen(h->buf.v, h->pos, NULL);
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Move cursor on the right.
+*/
+static void bc_history_edit_right(BcHistory *h) {
+
+ if (h->pos == BC_HIST_BUF_LEN(h)) return;
+
+ h->pos += bc_history_nextLen(h->buf.v, BC_HIST_BUF_LEN(h), h->pos, NULL);
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Move cursor to the end of the current word.
+ */
+static void bc_history_edit_wordEnd(BcHistory *h) {
+
+ size_t len = BC_HIST_BUF_LEN(h);
+
+ if (!len || h->pos >= len) return;
+
+ while (h->pos < len && isspace(h->buf.v[h->pos])) h->pos += 1;
+ while (h->pos < len && !isspace(h->buf.v[h->pos])) h->pos += 1;
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Move cursor to the start of the current word.
+ */
+static void bc_history_edit_wordStart(BcHistory *h) {
+
+ size_t len = BC_HIST_BUF_LEN(h);
+
+ if (!len) return;
+
+ while (h->pos > 0 && isspace(h->buf.v[h->pos - 1])) h->pos -= 1;
+ while (h->pos > 0 && !isspace(h->buf.v[h->pos - 1])) h->pos -= 1;
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Move cursor to the start of the line.
+ */
+static void bc_history_edit_home(BcHistory *h) {
+
+ if (!h->pos) return;
+
+ h->pos = 0;
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Move cursor to the end of the line.
+ */
+static void bc_history_edit_end(BcHistory *h) {
+
+ if (h->pos == BC_HIST_BUF_LEN(h)) return;
+
+ h->pos = BC_HIST_BUF_LEN(h);
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Substitute the currently edited line with the next or previous history
+ * entry as specified by 'dir' (direction).
+ */
+static void bc_history_edit_next(BcHistory *h, bool dir) {
+
+ const char *dup, *str;
+
+ if (h->history.len <= 1) return;
+
+ BC_SIG_LOCK;
+
+ if (h->buf.v[0]) dup = bc_vm_strdup(h->buf.v);
+ else dup = "";
+
+ // Update the current history entry before
+ // overwriting it with the next one.
+ bc_vec_replaceAt(&h->history, h->history.len - 1 - h->idx, &dup);
+
+ BC_SIG_UNLOCK;
+
+ // Show the new entry.
+ h->idx += (dir == BC_HIST_PREV ? 1 : SIZE_MAX);
+
+ if (h->idx == SIZE_MAX) {
+ h->idx = 0;
+ return;
+ }
+ else if (h->idx >= h->history.len) {
+ h->idx = h->history.len - 1;
+ return;
+ }
+
+ str = *((char**) bc_vec_item(&h->history, h->history.len - 1 - h->idx));
+ bc_vec_string(&h->buf, strlen(str), str);
+ assert(h->buf.len > 0);
+
+ h->pos = BC_HIST_BUF_LEN(h);
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Delete the character at the right of the cursor without altering the cursor
+ * position. Basically this is what happens with the "Delete" keyboard key.
+ */
+static void bc_history_edit_delete(BcHistory *h) {
+
+ size_t chlen, len = BC_HIST_BUF_LEN(h);
+
+ if (!len || h->pos >= len) return;
+
+ chlen = bc_history_nextLen(h->buf.v, len, h->pos, NULL);
+
+ memmove(h->buf.v + h->pos, h->buf.v + h->pos + chlen, len - h->pos - chlen);
+
+ h->buf.len -= chlen;
+ h->buf.v[BC_HIST_BUF_LEN(h)] = '\0';
+
+ bc_history_refresh(h);
+}
+
+static void bc_history_edit_backspace(BcHistory *h) {
+
+ size_t chlen, len = BC_HIST_BUF_LEN(h);
+
+ if (!h->pos || !len) return;
+
+ chlen = bc_history_prevLen(h->buf.v, h->pos, NULL);
+
+ memmove(h->buf.v + h->pos - chlen, h->buf.v + h->pos, len - h->pos);
+
+ h->pos -= chlen;
+ h->buf.len -= chlen;
+ h->buf.v[BC_HIST_BUF_LEN(h)] = '\0';
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Delete the previous word, maintaining the cursor at the start of the
+ * current word.
+ */
+static void bc_history_edit_deletePrevWord(BcHistory *h) {
+
+ size_t diff, old_pos = h->pos;
+
+ while (h->pos > 0 && h->buf.v[h->pos - 1] == ' ') --h->pos;
+ while (h->pos > 0 && h->buf.v[h->pos - 1] != ' ') --h->pos;
+
+ diff = old_pos - h->pos;
+ memmove(h->buf.v + h->pos, h->buf.v + old_pos,
+ BC_HIST_BUF_LEN(h) - old_pos + 1);
+ h->buf.len -= diff;
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Delete the next word, maintaining the cursor at the same position.
+ */
+static void bc_history_edit_deleteNextWord(BcHistory *h) {
+
+ size_t next_end = h->pos, len = BC_HIST_BUF_LEN(h);
+
+ while (next_end < len && h->buf.v[next_end] == ' ') ++next_end;
+ while (next_end < len && h->buf.v[next_end] != ' ') ++next_end;
+
+ memmove(h->buf.v + h->pos, h->buf.v + next_end, len - next_end);
+
+ h->buf.len -= next_end - h->pos;
+
+ bc_history_refresh(h);
+}
+
+static void bc_history_swap(BcHistory *h) {
+
+ size_t pcl, ncl;
+ char auxb[5];
+
+ pcl = bc_history_prevLen(h->buf.v, h->pos, NULL);
+ ncl = bc_history_nextLen(h->buf.v, BC_HIST_BUF_LEN(h), h->pos, NULL);
+
+ // To perform a swap we need:
+ // * nonzero char length to the left
+ // * not at the end of the line
+ if (pcl && h->pos != BC_HIST_BUF_LEN(h) && pcl < 5 && ncl < 5) {
+
+ memcpy(auxb, h->buf.v + h->pos - pcl, pcl);
+ memcpy(h->buf.v + h->pos - pcl, h->buf.v + h->pos, ncl);
+ memcpy(h->buf.v + h->pos - pcl + ncl, auxb, pcl);
+
+ h->pos += -pcl + ncl;
+
+ bc_history_refresh(h);
+ }
+}
+
+/**
+ * Handle escape sequences.
+ */
+static void bc_history_escape(BcHistory *h) {
+
+ char c, seq[3];
+
+ if (BC_ERR(BC_HIST_READ(seq, 1))) return;
+
+ c = seq[0];
+
+ // ESC ? sequences.
+ if (c != '[' && c != 'O') {
+ if (c == 'f') bc_history_edit_wordEnd(h);
+ else if (c == 'b') bc_history_edit_wordStart(h);
+ else if (c == 'd') bc_history_edit_deleteNextWord(h);
+ }
+ else {
+
+ if (BC_ERR(BC_HIST_READ(seq + 1, 1))) bc_vm_err(BC_ERR_FATAL_IO_ERR);
+
+ // ESC [ sequences.
+ if (c == '[') {
+
+ c = seq[1];
+
+ if (c >= '0' && c <= '9') {
+
+ // Extended escape, read additional byte.
+ if (BC_ERR(BC_HIST_READ(seq + 2, 1)))
+ bc_vm_err(BC_ERR_FATAL_IO_ERR);
+
+ if (seq[2] == '~' && c == '3') bc_history_edit_delete(h);
+ else if(seq[2] == ';') {
+
+ if (BC_ERR(BC_HIST_READ(seq, 2)))
+ bc_vm_err(BC_ERR_FATAL_IO_ERR);
+
+ if (seq[0] != '5') return;
+ else if (seq[1] == 'C') bc_history_edit_wordEnd(h);
+ else if (seq[1] == 'D') bc_history_edit_wordStart(h);
+ }
+ }
+ else {
+
+ switch(c) {
+
+ // Up.
+ case 'A':
+ {
+ bc_history_edit_next(h, BC_HIST_PREV);
+ break;
+ }
+
+ // Down.
+ case 'B':
+ {
+ bc_history_edit_next(h, BC_HIST_NEXT);
+ break;
+ }
+
+ // Right.
+ case 'C':
+ {
+ bc_history_edit_right(h);
+ break;
+ }
+
+ // Left.
+ case 'D':
+ {
+ bc_history_edit_left(h);
+ break;
+ }
+
+ // Home.
+ case 'H':
+ case '1':
+ {
+ bc_history_edit_home(h);
+ break;
+ }
+
+ // End.
+ case 'F':
+ case '4':
+ {
+ bc_history_edit_end(h);
+ break;
+ }
+
+ case 'd':
+ {
+ bc_history_edit_deleteNextWord(h);
+ break;
+ }
+ }
+ }
+ }
+ // ESC O sequences.
+ else if (c == 'O') {
+
+ switch (seq[1]) {
+
+ case 'A':
+ {
+ bc_history_edit_next(h, BC_HIST_PREV);
+ break;
+ }
+
+ case 'B':
+ {
+ bc_history_edit_next(h, BC_HIST_NEXT);
+ break;
+ }
+
+ case 'C':
+ {
+ bc_history_edit_right(h);
+ break;
+ }
+
+ case 'D':
+ {
+ bc_history_edit_left(h);
+ break;
+ }
+
+ case 'F':
+ {
+ bc_history_edit_end(h);
+ break;
+ }
+
+ case 'H':
+ {
+ bc_history_edit_home(h);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void bc_history_reset(BcHistory *h) {
+
+ h->oldcolpos = h->pos = h->idx = 0;
+ h->cols = bc_history_columns();
+
+ // The latest history entry is always our current buffer, that
+ // initially is just an empty string.
+ bc_history_add_empty(h);
+
+ // Buffer starts empty.
+ bc_vec_empty(&h->buf);
+}
+
+static void bc_history_printCtrl(BcHistory *h, unsigned int c) {
+
+ char str[3] = "^A";
+ const char newline[2] = "\n";
+
+ str[1] = (char) (c + 'A' - BC_ACTION_CTRL_A);
+
+ bc_vec_concat(&h->buf, str);
+
+ bc_history_refresh(h);
+
+ bc_vec_npop(&h->buf, sizeof(str));
+ 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_history_refresh(h);
+ }
+}
+
+/**
+ * This function is the core of the line editing capability of bc history.
+ * It expects 'fd' to be already in "raw mode" so that every key pressed
+ * will be returned ASAP to read().
+ */
+static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
+
+ bc_history_reset(h);
+
+#if BC_ENABLE_PROMPT
+ if (BC_USE_PROMPT) {
+
+ h->prompt = 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);
+ }
+#endif // BC_ENABLE_PROMPT
+
+ for (;;) {
+
+ BcStatus s;
+ // Large enough for any encoding?
+ char cbuf[32];
+ unsigned int c = 0;
+ size_t nread = 0;
+
+ s = bc_history_readCode(cbuf, sizeof(cbuf), &c, &nread);
+ if (BC_ERR(s)) return s;
+
+ switch (c) {
+
+ case BC_ACTION_LINE_FEED:
+ case BC_ACTION_ENTER:
+ {
+ bc_vec_pop(&h->history);
+ return s;
+ }
+
+ case BC_ACTION_TAB:
+ {
+ memcpy(cbuf, bc_history_tab, bc_history_tab_len + 1);
+ bc_history_edit_insert(h, cbuf, bc_history_tab_len);
+ break;
+ }
+
+ 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_program_ready_msg_len);
+ bc_history_reset(h);
+ bc_history_refresh(h);
+ break;
+ }
+
+ case BC_ACTION_BACKSPACE:
+ case BC_ACTION_CTRL_H:
+ {
+ bc_history_edit_backspace(h);
+ break;
+ }
+
+ // Act as end-of-file.
+ case BC_ACTION_CTRL_D:
+ {
+ bc_history_printCtrl(h, c);
+ return BC_STATUS_EOF;
+ }
+
+ // Swaps current character with previous.
+ case BC_ACTION_CTRL_T:
+ {
+ bc_history_swap(h);
+ break;
+ }
+
+ case BC_ACTION_CTRL_B:
+ {
+ bc_history_edit_left(h);
+ break;
+ }
+
+ case BC_ACTION_CTRL_F:
+ {
+ bc_history_edit_right(h);
+ break;
+ }
+
+ case BC_ACTION_CTRL_P:
+ {
+ bc_history_edit_next(h, BC_HIST_PREV);
+ break;
+ }
+
+ case BC_ACTION_CTRL_N:
+ {
+ bc_history_edit_next(h, BC_HIST_NEXT);
+ break;
+ }
+
+ case BC_ACTION_ESC:
+ {
+ bc_history_escape(h);
+ break;
+ }
+
+ // Delete the whole line.
+ case BC_ACTION_CTRL_U:
+ {
+ bc_vec_string(&h->buf, 0, "");
+ h->pos = 0;
+
+ bc_history_refresh(h);
+
+ break;
+ }
+
+ // Delete from current to end of line.
+ case BC_ACTION_CTRL_K:
+ {
+ bc_vec_npop(&h->buf, h->buf.len - h->pos);
+ bc_vec_pushByte(&h->buf, '\0');
+ bc_history_refresh(h);
+ break;
+ }
+
+ // Go to the start of the line.
+ case BC_ACTION_CTRL_A:
+ {
+ bc_history_edit_home(h);
+ break;
+ }
+
+ // Go to the end of the line.
+ case BC_ACTION_CTRL_E:
+ {
+ bc_history_edit_end(h);
+ break;
+ }
+
+ // Clear screen.
+ case BC_ACTION_CTRL_L:
+ {
+ bc_file_write(&vm.fout, "\x1b[H\x1b[2J", 7);
+ bc_history_refresh(h);
+ break;
+ }
+
+ // Delete previous word.
+ case BC_ACTION_CTRL_W:
+ {
+ bc_history_edit_deletePrevWord(h);
+ break;
+ }
+
+ default:
+ {
+ if (c >= BC_ACTION_CTRL_A && c <= BC_ACTION_CTRL_Z)
+ bc_history_printCtrl(h, c);
+ else bc_history_edit_insert(h, cbuf, nread);
+ break;
+ }
+ }
+ }
+
+ return BC_STATUS_SUCCESS;
+}
+
+static inline bool bc_history_stdinHasData(BcHistory *h) {
+ int n;
+ return pselect(1, &h->rdset, NULL, NULL, &h->ts, &h->sigmask) > 0 ||
+ (ioctl(STDIN_FILENO, FIONREAD, &n) >= 0 && n > 0);
+}
+
+/**
+ * This function calls the line editing function bc_history_edit()
+ * using the STDIN file descriptor set in raw mode.
+ */
+static BcStatus bc_history_raw(BcHistory *h, const char *prompt) {
+
+ BcStatus s;
+
+ assert(vm.fout.len == 0);
+
+ bc_history_enableRaw(h);
+
+ s = bc_history_edit(h, 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);
+
+ return s;
+}
+
+BcStatus bc_history_line(BcHistory *h, BcVec *vec, const char *prompt) {
+
+ BcStatus s;
+ char* line;
+
+ s = bc_history_raw(h, prompt);
+ assert(!s || s == BC_STATUS_EOF);
+
+ bc_vec_string(vec, BC_HIST_BUF_LEN(h), h->buf.v);
+
+ if (h->buf.v[0]) {
+
+ BC_SIG_LOCK;
+
+ line = bc_vm_strdup(h->buf.v);
+
+ BC_SIG_UNLOCK;
+
+ bc_history_add(h, line);
+ }
+ else bc_history_add_empty(h);
+
+ bc_vec_concat(vec, "\n");
+
+ return s;
+}
+
+static void bc_history_add(BcHistory *h, char *line) {
+
+ if (h->history.len) {
+
+ char *s = *((char**) bc_vec_item_rev(&h->history, 0));
+
+ if (!strcmp(s, line)) {
+
+ BC_SIG_LOCK;
+
+ free(line);
+
+ BC_SIG_UNLOCK;
+
+ return;
+ }
+ }
+
+ bc_vec_push(&h->history, &line);
+}
+
+static void bc_history_add_empty(BcHistory *h) {
+
+ const char *line = "";
+
+ if (h->history.len) {
+
+ char *s = *((char**) bc_vec_item_rev(&h->history, 0));
+
+ if (!s[0]) return;
+ }
+
+ bc_vec_push(&h->history, &line);
+}
+
+static void bc_history_string_free(void *str) {
+ char *s = *((char**) str);
+ BC_SIG_ASSERT_LOCKED;
+ if (s[0]) free(s);
+}
+
+void bc_history_init(BcHistory *h) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ bc_vec_init(&h->buf, sizeof(char), NULL);
+ bc_vec_init(&h->history, sizeof(char*), bc_history_string_free);
+
+ FD_ZERO(&h->rdset);
+ FD_SET(STDIN_FILENO, &h->rdset);
+ h->ts.tv_sec = 0;
+ h->ts.tv_nsec = 0;
+
+ sigemptyset(&h->sigmask);
+ sigaddset(&h->sigmask, SIGINT);
+
+ h->rawMode = h->stdin_has_data = false;
+ h->badTerm = bc_history_isBadTerm();
+}
+
+void bc_history_free(BcHistory *h) {
+ BC_SIG_ASSERT_LOCKED;
+ bc_history_disableRaw(h);
+#ifndef NDEBUG
+ bc_vec_free(&h->buf);
+ bc_vec_free(&h->history);
+#endif // NDEBUG
+}
+
+/**
+ * This special mode is used by bc history in order to print scan codes
+ * on screen for debugging / development purposes.
+ */
+#if BC_DEBUG_CODE
+void bc_history_printKeyCodes(BcHistory *h) {
+
+ char quit[4];
+
+ bc_vm_printf("Linenoise key codes debugging mode.\n"
+ "Press keys to see scan codes. "
+ "Type 'quit' at any time to exit.\n");
+
+ bc_history_enableRaw(h);
+ memset(quit, ' ', 4);
+
+ while(true) {
+
+ char c;
+ ssize_t nread;
+
+ nread = bc_history_read(&c, 1);
+ if (nread <= 0) continue;
+
+ // Shift string to left.
+ memmove(quit, quit + 1, sizeof(quit) - 1);
+
+ // Insert current char on the right.
+ quit[sizeof(quit) - 1] = c;
+ if (!memcmp(quit, "quit", sizeof(quit))) break;
+
+ bc_vm_printf("'%c' %lu (type quit to exit)\n",
+ 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_history_disableRaw(h);
+}
+#endif // BC_DEBUG_CODE
+
+#endif // BC_ENABLE_HISTORY
diff --git a/contrib/bc/src/lang.c b/contrib/bc/src/lang.c
new file mode 100644
index 000000000000..bc34e7c269f8
--- /dev/null
+++ b/contrib/bc/src/lang.c
@@ -0,0 +1,324 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code to manipulate data structures in programs.
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lang.h>
+#include <vm.h>
+
+#ifndef NDEBUG
+void bc_id_free(void *id) {
+ BC_SIG_ASSERT_LOCKED;
+ assert(id != NULL);
+ free(((BcId*) id)->name);
+}
+#endif // NDEBUG
+
+void bc_string_free(void *string) {
+ BC_SIG_ASSERT_LOCKED;
+ assert(string != NULL && (*((char**) string)) != NULL);
+ if (BC_IS_BC) free(*((char**) string));
+}
+
+void bc_const_free(void *constant) {
+ BcConst *c = constant;
+ BC_SIG_ASSERT_LOCKED;
+ assert(c->val != NULL);
+ free(c->val);
+ bc_num_free(&c->num);
+}
+
+#if BC_ENABLED
+void bc_func_insert(BcFunc *f, BcProgram *p, char *name,
+ BcType type, size_t line)
+{
+ BcLoc a;
+ size_t i, idx;
+
+ assert(f != NULL);
+
+ idx = bc_program_search(p, name, type == BC_TYPE_VAR);
+
+ for (i = 0; i < f->autos.len; ++i) {
+ BcLoc *id = bc_vec_item(&f->autos, i);
+ if (BC_ERR(idx == id->loc && type == (BcType) id->idx)) {
+ const char *array = type == BC_TYPE_ARRAY ? "[]" : "";
+ bc_vm_error(BC_ERR_PARSE_DUP_LOCAL, line, name, array);
+ }
+ }
+
+ a.loc = idx;
+ a.idx = type;
+
+ bc_vec_push(&f->autos, &a);
+}
+#endif // BC_ENABLED
+
+void bc_func_init(BcFunc *f, const char *name) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(f != NULL && name != NULL);
+
+ bc_vec_init(&f->code, sizeof(uchar), NULL);
+
+ bc_vec_init(&f->consts, sizeof(BcConst), bc_const_free);
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+
+ bc_vec_init(&f->strs, sizeof(char*), bc_string_free);
+
+ bc_vec_init(&f->autos, sizeof(BcLoc), NULL);
+ bc_vec_init(&f->labels, sizeof(size_t), NULL);
+
+ f->nparams = 0;
+ f->voidfn = false;
+ }
+#endif // BC_ENABLED
+
+ f->name = name;
+}
+
+void bc_func_reset(BcFunc *f) {
+
+ BC_SIG_ASSERT_LOCKED;
+ assert(f != NULL);
+
+ bc_vec_npop(&f->code, f->code.len);
+
+ bc_vec_npop(&f->consts, f->consts.len);
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+
+ bc_vec_npop(&f->strs, f->strs.len);
+
+ bc_vec_npop(&f->autos, f->autos.len);
+ bc_vec_npop(&f->labels, f->labels.len);
+
+ f->nparams = 0;
+ f->voidfn = false;
+ }
+#endif // BC_ENABLED
+}
+
+void bc_func_free(void *func) {
+
+#if BC_ENABLE_FUNC_FREE
+
+ BcFunc *f = (BcFunc*) func;
+
+ BC_SIG_ASSERT_LOCKED;
+ assert(f != NULL);
+
+ bc_vec_free(&f->code);
+
+ bc_vec_free(&f->consts);
+
+#if BC_ENABLED
+#ifndef NDEBUG
+ if (BC_IS_BC) {
+
+ bc_vec_free(&f->strs);
+
+ bc_vec_free(&f->autos);
+ bc_vec_free(&f->labels);
+ }
+#endif // NDEBUG
+#endif // BC_ENABLED
+
+#else // BC_ENABLE_FUNC_FREE
+ BC_UNUSED(func);
+#endif // BC_ENABLE_FUNC_FREE
+}
+
+void bc_array_init(BcVec *a, bool nums) {
+ BC_SIG_ASSERT_LOCKED;
+ if (nums) bc_vec_init(a, sizeof(BcNum), bc_num_free);
+ else bc_vec_init(a, sizeof(BcVec), bc_vec_free);
+ bc_array_expand(a, 1);
+}
+
+void bc_array_copy(BcVec *d, const BcVec *s) {
+
+ size_t i;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(d != NULL && s != NULL);
+ assert(d != s && d->size == s->size && d->dtor == s->dtor);
+
+ bc_vec_npop(d, d->len);
+ bc_vec_expand(d, s->cap);
+ d->len = s->len;
+
+ for (i = 0; i < s->len; ++i) {
+ BcNum *dnum = bc_vec_item(d, i), *snum = bc_vec_item(s, i);
+ bc_num_createCopy(dnum, snum);
+ }
+}
+
+void bc_array_expand(BcVec *a, size_t len) {
+
+ assert(a != NULL);
+
+ BC_SIG_ASSERT_LOCKED;
+
+ bc_vec_expand(a, len);
+
+ if (a->size == sizeof(BcNum) && a->dtor == bc_num_free) {
+ BcNum n;
+ while (len > a->len) {
+ bc_num_init(&n, BC_NUM_DEF_SIZE);
+ bc_vec_push(a, &n);
+ }
+ }
+ else {
+ BcVec v;
+ assert(a->size == sizeof(BcVec) && a->dtor == bc_vec_free);
+ while (len > a->len) {
+ bc_array_init(&v, true);
+ bc_vec_push(a, &v);
+ }
+ }
+}
+
+void bc_result_clear(BcResult *r) {
+ r->t = BC_RESULT_TEMP;
+ bc_num_clear(&r->d.n);
+}
+
+#if DC_ENABLED
+void bc_result_copy(BcResult *d, BcResult *src) {
+
+ assert(d != NULL && src != NULL);
+
+ BC_SIG_ASSERT_LOCKED;
+
+ d->t = src->t;
+
+ switch (d->t) {
+
+ case BC_RESULT_TEMP:
+ case BC_RESULT_IBASE:
+ case BC_RESULT_SCALE:
+ case BC_RESULT_OBASE:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_RESULT_SEED:
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ bc_num_createCopy(&d->d.n, &src->d.n);
+ break;
+ }
+
+ case BC_RESULT_VAR:
+#if BC_ENABLED
+ case BC_RESULT_ARRAY:
+#endif // BC_ENABLED
+ case BC_RESULT_ARRAY_ELEM:
+ {
+ memcpy(&d->d.loc, &src->d.loc, sizeof(BcLoc));
+ break;
+ }
+
+ case BC_RESULT_STR:
+ {
+ memcpy(&d->d.n, &src->d.n, sizeof(BcNum));
+ break;
+ }
+
+ case BC_RESULT_ZERO:
+ case BC_RESULT_ONE:
+ {
+ // Do nothing.
+ break;
+ }
+
+#if BC_ENABLED
+ case BC_RESULT_VOID:
+ case BC_RESULT_LAST:
+ {
+#ifndef NDEBUG
+ abort();
+#endif // NDEBUG
+ }
+#endif // BC_ENABLED
+ }
+}
+#endif // DC_ENABLED
+
+void bc_result_free(void *result) {
+
+ BcResult *r = (BcResult*) result;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(r != NULL);
+
+ switch (r->t) {
+
+ case BC_RESULT_TEMP:
+ case BC_RESULT_IBASE:
+ case BC_RESULT_SCALE:
+ case BC_RESULT_OBASE:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_RESULT_SEED:
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ bc_num_free(&r->d.n);
+ break;
+ }
+
+ case BC_RESULT_VAR:
+#if BC_ENABLED
+ case BC_RESULT_ARRAY:
+#endif // BC_ENABLED
+ case BC_RESULT_ARRAY_ELEM:
+ case BC_RESULT_STR:
+ case BC_RESULT_ZERO:
+ case BC_RESULT_ONE:
+#if BC_ENABLED
+ case BC_RESULT_VOID:
+ case BC_RESULT_LAST:
+#endif // BC_ENABLED
+ {
+ // Do nothing.
+ break;
+ }
+ }
+}
diff --git a/contrib/bc/src/lex.c b/contrib/bc/src/lex.c
new file mode 100644
index 000000000000..d6f09f995a6a
--- /dev/null
+++ b/contrib/bc/src/lex.c
@@ -0,0 +1,230 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Common code for the lexers.
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <lex.h>
+#include <vm.h>
+#include <bc.h>
+
+void bc_lex_invalidChar(BcLex *l, char c) {
+ l->t = BC_LEX_INVALID;
+ bc_lex_verr(l, BC_ERR_PARSE_CHAR, c);
+}
+
+void bc_lex_lineComment(BcLex *l) {
+ l->t = BC_LEX_WHITESPACE;
+ while (l->i < l->len && l->buf[l->i] != '\n') l->i += 1;
+}
+
+void bc_lex_comment(BcLex *l) {
+
+ size_t i, nlines = 0;
+ const char *buf = l->buf;
+ bool end = false;
+ char c;
+
+ l->i += 1;
+ l->t = BC_LEX_WHITESPACE;
+
+ for (i = l->i; !end; i += !end) {
+
+ for (; (c = buf[i]) && c != '*'; ++i) nlines += (c == '\n');
+
+ if (BC_ERR(!c || buf[i + 1] == '\0')) {
+ l->i = i;
+ bc_lex_err(l, BC_ERR_PARSE_COMMENT);
+ }
+
+ end = buf[i + 1] == '/';
+ }
+
+ l->i = i + 2;
+ l->line += nlines;
+}
+
+void bc_lex_whitespace(BcLex *l) {
+ char c;
+ l->t = BC_LEX_WHITESPACE;
+ for (c = l->buf[l->i]; c != '\n' && isspace(c); c = l->buf[++l->i]);
+}
+
+void bc_lex_commonTokens(BcLex *l, char c) {
+ if (!c) l->t = BC_LEX_EOF;
+ else if (c == '\n') l->t = BC_LEX_NLINE;
+ else bc_lex_whitespace(l);
+}
+
+static size_t bc_lex_num(BcLex *l, char start, bool int_only) {
+
+ const char *buf = l->buf + l->i;
+ size_t i;
+ char c;
+ bool last_pt, pt = (start == '.');
+
+ for (i = 0; (c = buf[i]) && (BC_LEX_NUM_CHAR(c, pt, int_only) ||
+ (c == '\\' && buf[i + 1] == '\n')); ++i)
+ {
+ if (c == '\\') {
+
+ if (buf[i + 1] == '\n') {
+
+ i += 2;
+
+ // Make sure to eat whitespace at the beginning of the line.
+ while(isspace(buf[i]) && buf[i] != '\n') i += 1;
+
+ c = buf[i];
+
+ if (!BC_LEX_NUM_CHAR(c, pt, int_only)) break;
+ }
+ else break;
+ }
+
+ last_pt = (c == '.');
+ if (pt && last_pt) break;
+ pt = pt || last_pt;
+
+ bc_vec_push(&l->str, &c);
+ }
+
+ return i;
+}
+
+void bc_lex_number(BcLex *l, char start) {
+
+ l->t = BC_LEX_NUMBER;
+
+ bc_vec_npop(&l->str, l->str.len);
+ bc_vec_push(&l->str, &start);
+
+ l->i += bc_lex_num(l, start, false);
+
+#if BC_ENABLE_EXTRA_MATH
+ {
+ char c = l->buf[l->i];
+
+ if (c == 'e') {
+
+#if BC_ENABLED
+ if (BC_IS_POSIX) bc_lex_err(l, BC_ERR_POSIX_EXP_NUM);
+#endif // BC_ENABLED
+
+ bc_vec_push(&l->str, &c);
+ l->i += 1;
+ c = l->buf[l->i];
+
+ if (c == BC_LEX_NEG_CHAR) {
+ bc_vec_push(&l->str, &c);
+ l->i += 1;
+ c = l->buf[l->i];
+ }
+
+ if (BC_ERR(!BC_LEX_NUM_CHAR(c, false, true)))
+ bc_lex_verr(l, BC_ERR_PARSE_CHAR, c);
+
+ l->i += bc_lex_num(l, 0, true);
+ }
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+
+ bc_vec_pushByte(&l->str, '\0');
+}
+
+void bc_lex_name(BcLex *l) {
+
+ size_t i = 0;
+ const char *buf = l->buf + l->i - 1;
+ char c = buf[i];
+
+ l->t = BC_LEX_NAME;
+
+ while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i];
+
+ bc_vec_string(&l->str, i, buf);
+
+ // Increment the index. We minus 1 because it has already been incremented.
+ l->i += i - 1;
+}
+
+void bc_lex_init(BcLex *l) {
+ BC_SIG_ASSERT_LOCKED;
+ assert(l != NULL);
+ bc_vec_init(&l->str, sizeof(char), NULL);
+}
+
+void bc_lex_free(BcLex *l) {
+ BC_SIG_ASSERT_LOCKED;
+ assert(l != NULL);
+ bc_vec_free(&l->str);
+}
+
+void bc_lex_file(BcLex *l, const char *file) {
+ assert(l != NULL && file != NULL);
+ l->line = 1;
+ vm.file = file;
+}
+
+void bc_lex_next(BcLex *l) {
+
+ assert(l != NULL);
+
+ l->last = l->t;
+ l->line += (l->i != 0 && l->buf[l->i - 1] == '\n');
+
+ if (BC_ERR(l->last == BC_LEX_EOF)) bc_lex_err(l, BC_ERR_PARSE_EOF);
+
+ l->t = BC_LEX_EOF;
+
+ if (l->i == l->len) return;
+
+ // Loop until failure or we don't have whitespace. This
+ // is so the parser doesn't get inundated with whitespace.
+ do {
+ vm.next(l);
+ } while (l->t == BC_LEX_WHITESPACE);
+}
+
+void bc_lex_text(BcLex *l, const char *text) {
+ assert(l != NULL && text != NULL);
+ l->buf = text;
+ l->i = 0;
+ l->len = strlen(text);
+ l->t = l->last = BC_LEX_INVALID;
+ bc_lex_next(l);
+}
diff --git a/contrib/bc/src/library.c b/contrib/bc/src/library.c
new file mode 100644
index 000000000000..278b0f55a950
--- /dev/null
+++ b/contrib/bc/src/library.c
@@ -0,0 +1,1183 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The public functions for libbc.
+ *
+ */
+
+#if BC_ENABLE_LIBRARY
+
+#include <setjmp.h>
+#include <string.h>
+#include <time.h>
+
+#include <bcl.h>
+
+#include <library.h>
+#include <num.h>
+#include <vm.h>
+
+static void bcl_num_destruct(void *num);
+
+void bcl_handleSignal(void) {
+
+ // Signal already in flight, or bc is not executing.
+ if (vm.sig || !vm.running) return;
+
+ vm.sig = 1;
+
+ assert(vm.jmp_bufs.len);
+
+ if (!vm.sig_lock) BC_VM_JMP;
+}
+
+bool bcl_running(void) {
+ return vm.running != 0;
+}
+
+BclError bcl_init(void) {
+
+ BclError e = BCL_ERROR_NONE;
+
+ vm.refs += 1;
+
+ if (vm.refs > 1) return e;
+
+ vm.ctxts.v = NULL;
+ vm.jmp_bufs.v = NULL;
+ vm.out.v = NULL;
+
+ vm.abrt = false;
+
+ BC_SIG_LOCK;
+
+ bc_vec_init(&vm.jmp_bufs, sizeof(sigjmp_buf), NULL);
+
+ BC_FUNC_HEADER_INIT(err);
+
+ bc_vm_init();
+
+ bc_vec_init(&vm.ctxts, sizeof(BclContext), NULL);
+ bc_vec_init(&vm.out, sizeof(uchar), NULL);
+
+ srand((unsigned int) time(NULL));
+ bc_rand_init(&vm.rng);
+
+err:
+ if (BC_ERR(vm.err)) {
+ if (vm.out.v != NULL) bc_vec_free(&vm.out);
+ if (vm.jmp_bufs.v != NULL) bc_vec_free(&vm.jmp_bufs);
+ if (vm.ctxts.v != NULL) bc_vec_free(&vm.ctxts);
+ }
+
+ BC_FUNC_FOOTER_UNLOCK(e);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return e;
+}
+
+BclError bcl_pushContext(BclContext ctxt) {
+
+ BclError e = BCL_ERROR_NONE;
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_push(&vm.ctxts, &ctxt);
+
+err:
+ BC_FUNC_FOOTER_UNLOCK(e);
+ return e;
+}
+
+void bcl_popContext(void) {
+ if (vm.ctxts.len) bc_vec_pop(&vm.ctxts);
+}
+
+BclContext bcl_context(void) {
+ if (!vm.ctxts.len) return NULL;
+ return *((BclContext*) bc_vec_top(&vm.ctxts));
+}
+
+void bcl_free(void) {
+
+ vm.refs -= 1;
+
+ if (vm.refs) return;
+
+ BC_SIG_LOCK;
+
+#ifndef NDEBUG
+ bc_rand_free(&vm.rng);
+ bc_vec_free(&vm.out);
+
+ {
+ size_t i;
+
+ for (i = 0; i < vm.ctxts.len; ++i) {
+ BclContext ctxt = *((BclContext*) bc_vec_item(&vm.ctxts, i));
+ bcl_ctxt_free(ctxt);
+ }
+ }
+
+ bc_vec_free(&vm.ctxts);
+#endif // NDEBUG
+
+ bc_vm_shutdown();
+
+ bc_vec_free(&vm.jmp_bufs);
+
+ BC_SIG_UNLOCK;
+
+ memset(&vm, 0, sizeof(BcVm));
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+}
+
+void bcl_gc(void) {
+ bc_vm_freeTemps();
+ vm.temps.len = 0;
+}
+
+bool bcl_abortOnFatalError(void) {
+ return vm.abrt;
+}
+
+void bcl_setAbortOnFatalError(bool abrt) {
+ vm.abrt = abrt;
+}
+
+BclContext bcl_ctxt_create(void) {
+
+ BclContext ctxt = NULL;
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ ctxt = bc_vm_malloc(sizeof(BclCtxt));
+
+ bc_vec_init(&ctxt->nums, sizeof(BcNum), bcl_num_destruct);
+ bc_vec_init(&ctxt->free_nums, sizeof(BclNumber), NULL);
+
+ ctxt->scale = 0;
+ ctxt->ibase = 10;
+ ctxt->obase= 10;
+
+err:
+ if (BC_ERR(vm.err && ctxt != NULL)) {
+ if (ctxt->nums.v != NULL) bc_vec_free(&ctxt->nums);
+ free(ctxt);
+ ctxt = NULL;
+ }
+
+ BC_FUNC_FOOTER_NO_ERR;
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return ctxt;
+}
+
+void bcl_ctxt_free(BclContext ctxt) {
+ BC_SIG_LOCK;
+ bc_vec_free(&ctxt->free_nums);
+ bc_vec_free(&ctxt->nums);
+ free(ctxt);
+ BC_SIG_UNLOCK;
+}
+
+void bcl_ctxt_freeNums(BclContext ctxt) {
+ bc_vec_npop(&ctxt->nums, ctxt->nums.len);
+ bc_vec_npop(&ctxt->free_nums, ctxt->free_nums.len);
+}
+
+size_t bcl_ctxt_scale(BclContext ctxt) {
+ return ctxt->scale;
+}
+
+void bcl_ctxt_setScale(BclContext ctxt, size_t scale) {
+ ctxt->scale = scale;
+}
+
+size_t bcl_ctxt_ibase(BclContext ctxt) {
+ return ctxt->ibase;
+}
+
+void bcl_ctxt_setIbase(BclContext ctxt, size_t ibase) {
+ if (ibase < BC_NUM_MIN_BASE) ibase = BC_NUM_MIN_BASE;
+ else if (ibase > BC_NUM_MAX_IBASE) ibase = BC_NUM_MAX_IBASE;
+ ctxt->ibase = ibase;
+}
+
+size_t bcl_ctxt_obase(BclContext ctxt) {
+ return ctxt->obase;
+}
+
+void bcl_ctxt_setObase(BclContext ctxt, size_t obase) {
+ ctxt->obase = obase;
+}
+
+BclError bcl_err(BclNumber n) {
+
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ERR(ctxt);
+
+ if (n.i >= ctxt->nums.len) {
+ if (n.i > 0 - (size_t) BCL_ERROR_NELEMS) return (BclError) (0 - n.i);
+ else return BCL_ERROR_INVALID_NUM;
+ }
+ else return BCL_ERROR_NONE;
+}
+
+static BclNumber bcl_num_insert(BclContext ctxt, BcNum *restrict n) {
+
+ BclNumber idx;
+
+ if (ctxt->free_nums.len) {
+
+ BcNum *ptr;
+
+ idx = *((BclNumber*) bc_vec_top(&ctxt->free_nums));
+
+ bc_vec_pop(&ctxt->free_nums);
+
+ ptr = bc_vec_item(&ctxt->nums, idx.i);
+ memcpy(ptr, n, sizeof(BcNum));
+ }
+ else {
+ idx.i = ctxt->nums.len;
+ bc_vec_push(&ctxt->nums, n);
+ }
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+BclNumber bcl_num_create(void) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum n;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ bc_num_init(&n, BC_NUM_DEF_SIZE);
+
+err:
+ BC_FUNC_FOOTER_UNLOCK(e);
+ BC_MAYBE_SETUP(ctxt, e, n, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+static void bcl_num_dtor(BclContext ctxt, BclNumber n, BcNum *restrict num) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(num != NULL && num->num != NULL);
+
+ bcl_num_destruct(num);
+ bc_vec_push(&ctxt->free_nums, &n);
+}
+
+void bcl_num_free(BclNumber n) {
+
+ BcNum *num;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ BC_SIG_LOCK;
+
+ assert(n.i < ctxt->nums.len);
+
+ num = BC_NUM(ctxt, n);
+
+ bcl_num_dtor(ctxt, n, num);
+
+ BC_SIG_UNLOCK;
+}
+
+BclError bcl_copy(BclNumber d, BclNumber s) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *dest, *src;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ERR(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ assert(d.i < ctxt->nums.len && s.i < ctxt->nums.len);
+
+ dest = BC_NUM(ctxt, d);
+ src = BC_NUM(ctxt, s);
+
+ assert(dest != NULL && src != NULL);
+ assert(dest->num != NULL && src->num != NULL);
+
+ bc_num_copy(dest, src);
+
+err:
+ BC_FUNC_FOOTER_UNLOCK(e);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return e;
+}
+
+BclNumber bcl_dup(BclNumber s) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *src, dest;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ assert(s.i < ctxt->nums.len);
+
+ src = BC_NUM(ctxt, s);
+
+ assert(src != NULL && src->num != NULL);
+
+ bc_num_clear(&dest);
+
+ bc_num_createCopy(&dest, src);
+
+err:
+ BC_FUNC_FOOTER_UNLOCK(e);
+ BC_MAYBE_SETUP(ctxt, e, dest, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+static void bcl_num_destruct(void *num) {
+
+ BcNum *n = (BcNum*) num;
+
+ assert(n != NULL);
+
+ if (n->num == NULL) return;
+
+ bc_num_free(num);
+ bc_num_clear(num);
+}
+
+bool bcl_num_neg(BclNumber n) {
+
+ BcNum *num;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ assert(n.i < ctxt->nums.len);
+
+ num = BC_NUM(ctxt, n);
+
+ assert(num != NULL && num->num != NULL);
+
+ return BC_NUM_NEG(num) != 0;
+}
+
+void bcl_num_setNeg(BclNumber n, bool neg) {
+
+ BcNum *num;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ assert(n.i < ctxt->nums.len);
+
+ num = BC_NUM(ctxt, n);
+
+ assert(num != NULL && num->num != NULL);
+
+ num->rdx = BC_NUM_NEG_VAL(num, neg);
+}
+
+size_t bcl_num_scale(BclNumber n) {
+
+ BcNum *num;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ assert(n.i < ctxt->nums.len);
+
+ num = BC_NUM(ctxt, n);
+
+ assert(num != NULL && num->num != NULL);
+
+ return bc_num_scale(num);
+}
+
+BclError bcl_num_setScale(BclNumber n, size_t scale) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *nptr;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ERR(ctxt);
+
+ BC_CHECK_NUM_ERR(ctxt, n);
+
+ BC_FUNC_HEADER(err);
+
+ assert(n.i < ctxt->nums.len);
+
+ nptr = BC_NUM(ctxt, n);
+
+ assert(nptr != NULL && nptr->num != NULL);
+
+ if (scale > nptr->scale) bc_num_extend(nptr, scale - nptr->scale);
+ else if (scale < nptr->scale) bc_num_truncate(nptr, nptr->scale - scale);
+
+err:
+ BC_SIG_MAYLOCK;
+ BC_FUNC_FOOTER(e);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return e;
+}
+
+size_t bcl_num_len(BclNumber n) {
+
+ BcNum *num;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ assert(n.i < ctxt->nums.len);
+
+ num = BC_NUM(ctxt, n);
+
+ assert(num != NULL && num->num != NULL);
+
+ return bc_num_len(num);
+}
+
+BclError bcl_bigdig(BclNumber n, BclBigDig *result) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *num;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ERR(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ assert(n.i < ctxt->nums.len);
+ assert(result != NULL);
+
+ num = BC_NUM(ctxt, n);
+
+ assert(num != NULL && num->num != NULL);
+
+ bc_num_bigdig(num, result);
+
+err:
+ bcl_num_dtor(ctxt, n, num);
+ BC_FUNC_FOOTER_UNLOCK(e);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return e;
+}
+
+BclNumber bcl_bigdig2num(BclBigDig val) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum n;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ bc_num_createFromBigdig(&n, val);
+
+err:
+ BC_FUNC_FOOTER_UNLOCK(e);
+ BC_MAYBE_SETUP(ctxt, e, n, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+static BclNumber bcl_binary(BclNumber a, BclNumber b,
+ const BcNumBinaryOp op,
+ const BcNumBinaryOpReq req)
+{
+ BclError e = BCL_ERROR_NONE;
+ BcNum *aptr, *bptr;
+ BcNum c;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_CHECK_NUM(ctxt, a);
+ BC_CHECK_NUM(ctxt, b);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ assert(a.i < ctxt->nums.len && b.i < ctxt->nums.len);
+
+ aptr = BC_NUM(ctxt, a);
+ bptr = BC_NUM(ctxt, b);
+
+ assert(aptr != NULL && bptr != NULL);
+ assert(aptr->num != NULL && bptr->num != NULL);
+
+ bc_num_clear(&c);
+
+ bc_num_init(&c, req(aptr, bptr, ctxt->scale));
+
+ BC_SIG_UNLOCK;
+
+ op(aptr, bptr, &c, ctxt->scale);
+
+err:
+ BC_SIG_MAYLOCK;
+ bcl_num_dtor(ctxt, a, aptr);
+ if (b.i != a.i) bcl_num_dtor(ctxt, b, bptr);
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, c, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+BclNumber bcl_add(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_add, bc_num_addReq);
+}
+
+BclNumber bcl_sub(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_sub, bc_num_addReq);
+}
+
+BclNumber bcl_mul(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_mul, bc_num_mulReq);
+}
+
+BclNumber bcl_div(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_div, bc_num_divReq);
+}
+
+BclNumber bcl_mod(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_mod, bc_num_divReq);
+}
+
+BclNumber bcl_pow(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_pow, bc_num_powReq);
+}
+
+BclNumber bcl_lshift(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_lshift, bc_num_placesReq);
+}
+
+BclNumber bcl_rshift(BclNumber a, BclNumber b) {
+ return bcl_binary(a, b, bc_num_rshift, bc_num_placesReq);
+}
+
+BclNumber bcl_sqrt(BclNumber a) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *aptr;
+ BcNum b;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_CHECK_NUM(ctxt, a);
+
+ BC_FUNC_HEADER(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ assert(a.i < ctxt->nums.len);
+
+ aptr = BC_NUM(ctxt, a);
+
+ bc_num_sqrt(aptr, &b, ctxt->scale);
+
+err:
+ BC_SIG_MAYLOCK;
+ bcl_num_dtor(ctxt, a, aptr);
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, b, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+BclError bcl_divmod(BclNumber a, BclNumber b, BclNumber *c, BclNumber *d) {
+
+ BclError e = BCL_ERROR_NONE;
+ size_t req;
+ BcNum *aptr, *bptr;
+ BcNum cnum, dnum;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ERR(ctxt);
+
+ BC_CHECK_NUM_ERR(ctxt, a);
+ BC_CHECK_NUM_ERR(ctxt, b);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 2);
+
+ assert(c != NULL && d != NULL);
+
+ aptr = BC_NUM(ctxt, a);
+ bptr = BC_NUM(ctxt, b);
+
+ assert(aptr != NULL && bptr != NULL);
+ assert(aptr->num != NULL && bptr->num != NULL);
+
+ bc_num_clear(&cnum);
+ bc_num_clear(&dnum);
+
+ req = bc_num_divReq(aptr, bptr, ctxt->scale);
+
+ bc_num_init(&cnum, req);
+ bc_num_init(&dnum, req);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_divmod(aptr, bptr, &cnum, &dnum, ctxt->scale);
+
+err:
+ BC_SIG_MAYLOCK;
+
+ bcl_num_dtor(ctxt, a, aptr);
+ if (b.i != a.i) bcl_num_dtor(ctxt, b, bptr);
+
+ if (BC_ERR(vm.err)) {
+ if (cnum.num != NULL) bc_num_free(&cnum);
+ if (dnum.num != NULL) bc_num_free(&dnum);
+ c->i = 0 - (size_t) BCL_ERROR_INVALID_NUM;
+ d->i = c->i;
+ BC_FUNC_FOOTER(e);
+ }
+ else {
+ BC_FUNC_FOOTER(e);
+ *c = bcl_num_insert(ctxt, &cnum);
+ *d = bcl_num_insert(ctxt, &dnum);
+ }
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return e;
+}
+
+BclNumber bcl_modexp(BclNumber a, BclNumber b, BclNumber c) {
+
+ BclError e = BCL_ERROR_NONE;
+ size_t req;
+ BcNum *aptr, *bptr, *cptr;
+ BcNum d;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_CHECK_NUM(ctxt, a);
+ BC_CHECK_NUM(ctxt, b);
+ BC_CHECK_NUM(ctxt, c);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ assert(a.i < ctxt->nums.len && b.i < ctxt->nums.len);
+ assert(c.i < ctxt->nums.len);
+
+ aptr = BC_NUM(ctxt, a);
+ bptr = BC_NUM(ctxt, b);
+ cptr = BC_NUM(ctxt, c);
+
+ assert(aptr != NULL && bptr != NULL && cptr != NULL);
+ assert(aptr->num != NULL && bptr->num != NULL && cptr->num != NULL);
+
+ bc_num_clear(&d);
+
+ req = bc_num_divReq(aptr, cptr, 0);
+
+ bc_num_init(&d, req);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_modexp(aptr, bptr, cptr, &d);
+
+err:
+ BC_SIG_MAYLOCK;
+
+ bcl_num_dtor(ctxt, a, aptr);
+ if (b.i != a.i) bcl_num_dtor(ctxt, b, bptr);
+ if (c.i != a.i && c.i != b.i) bcl_num_dtor(ctxt, c, cptr);
+
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, d, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+ssize_t bcl_cmp(BclNumber a, BclNumber b) {
+
+ BcNum *aptr, *bptr;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ assert(a.i < ctxt->nums.len && b.i < ctxt->nums.len);
+
+ aptr = BC_NUM(ctxt, a);
+ bptr = BC_NUM(ctxt, b);
+
+ assert(aptr != NULL && bptr != NULL);
+ assert(aptr->num != NULL && bptr->num != NULL);
+
+ return bc_num_cmp(aptr, bptr);
+}
+
+void bcl_zero(BclNumber n) {
+
+ BcNum *nptr;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ assert(n.i < ctxt->nums.len);
+
+ nptr = BC_NUM(ctxt, n);
+
+ assert(nptr != NULL && nptr->num != NULL);
+
+ bc_num_zero(nptr);
+}
+
+void bcl_one(BclNumber n) {
+
+ BcNum *nptr;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ assert(n.i < ctxt->nums.len);
+
+ nptr = BC_NUM(ctxt, n);
+
+ assert(nptr != NULL && nptr->num != NULL);
+
+ bc_num_one(nptr);
+}
+
+BclNumber bcl_parse(const char *restrict val) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum n;
+ BclNumber idx;
+ BclContext ctxt;
+ bool neg;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ assert(val != NULL);
+
+ neg = (val[0] == '-');
+
+ if (neg) val += 1;
+
+ if (!bc_num_strValid(val)) {
+ vm.err = BCL_ERROR_PARSE_INVALID_STR;
+ goto err;
+ }
+
+ bc_num_clear(&n);
+
+ bc_num_init(&n, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_parse(&n, val, (BcBigDig) ctxt->ibase);
+
+ n.rdx = BC_NUM_NEG_VAL_NP(n, neg);
+
+err:
+ BC_SIG_MAYLOCK;
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, n, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+char* bcl_string(BclNumber n) {
+
+ BcNum *nptr;
+ char *str = NULL;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ASSERT(ctxt);
+
+ if (BC_ERR(n.i >= ctxt->nums.len)) return str;
+
+ BC_FUNC_HEADER(err);
+
+ assert(n.i < ctxt->nums.len);
+
+ nptr = BC_NUM(ctxt, n);
+
+ assert(nptr != NULL && nptr->num != NULL);
+
+ bc_vec_npop(&vm.out, vm.out.len);
+
+ bc_num_print(nptr, (BcBigDig) ctxt->obase, false);
+ bc_vec_pushByte(&vm.out, '\0');
+
+ BC_SIG_LOCK;
+ str = bc_vm_strdup(vm.out.v);
+
+err:
+ bcl_num_dtor(ctxt, n, nptr);
+
+ BC_FUNC_FOOTER_NO_ERR;
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return str;
+}
+
+BclNumber bcl_irand(BclNumber a) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *aptr;
+ BcNum b;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_CHECK_NUM(ctxt, a);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ assert(a.i < ctxt->nums.len);
+
+ aptr = BC_NUM(ctxt, a);
+
+ assert(aptr != NULL && aptr->num != NULL);
+
+ bc_num_clear(&b);
+
+ bc_num_init(&b, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_irand(aptr, &b, &vm.rng);
+
+err:
+ BC_SIG_MAYLOCK;
+ bcl_num_dtor(ctxt, a, aptr);
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, b, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+static void bcl_frandHelper(BcNum *restrict b, size_t places) {
+
+ BcNum exp, pow, ten;
+ BcDig exp_digs[BC_NUM_BIGDIG_LOG10];
+ BcDig ten_digs[BC_NUM_BIGDIG_LOG10];
+
+ bc_num_setup(&exp, exp_digs, BC_NUM_BIGDIG_LOG10);
+ bc_num_setup(&ten, ten_digs, BC_NUM_BIGDIG_LOG10);
+
+ ten.num[0] = 10;
+ ten.len = 1;
+
+ bc_num_bigdig2num(&exp, (BcBigDig) places);
+
+ bc_num_clear(&pow);
+
+ BC_SIG_LOCK;
+
+ BC_SETJMP_LOCKED(err);
+
+ bc_num_init(&pow, bc_num_powReq(&ten, &exp, 0));
+
+ BC_SIG_UNLOCK;
+
+ bc_num_pow(&ten, &exp, &pow, 0);
+
+ bc_num_irand(&pow, b, &vm.rng);
+
+ bc_num_shiftRight(b, places);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&pow);
+ BC_LONGJMP_CONT;
+}
+
+BclNumber bcl_frand(size_t places) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum n;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ bc_num_clear(&n);
+
+ bc_num_init(&n, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bcl_frandHelper(&n, places);
+
+err:
+ BC_SIG_MAYLOCK;
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, n, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+static void bcl_ifrandHelper(BcNum *restrict a, BcNum *restrict b,
+ size_t places)
+{
+ BcNum ir, fr;
+
+ bc_num_clear(&ir);
+ bc_num_clear(&fr);
+
+ BC_SIG_LOCK;
+
+ BC_SETJMP_LOCKED(err);
+
+ bc_num_init(&ir, BC_NUM_DEF_SIZE);
+ bc_num_init(&fr, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_irand(a, &ir, &vm.rng);
+ bcl_frandHelper(&fr, places);
+
+ bc_num_add(&ir, &fr, b, 0);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&fr);
+ bc_num_free(&ir);
+ BC_LONGJMP_CONT;
+}
+
+BclNumber bcl_ifrand(BclNumber a, size_t places) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *aptr;
+ BcNum b;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_CHECK_NUM(ctxt, a);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_vec_grow(&ctxt->nums, 1);
+
+ assert(a.i < ctxt->nums.len);
+
+ aptr = BC_NUM(ctxt, a);
+
+ assert(aptr != NULL && aptr->num != NULL);
+
+ bc_num_clear(&b);
+
+ bc_num_init(&b, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bcl_ifrandHelper(aptr, &b, places);
+
+err:
+ BC_SIG_MAYLOCK;
+ bcl_num_dtor(ctxt, a, aptr);
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, b, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+BclError bcl_rand_seedWithNum(BclNumber n) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum *nptr;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT_ERR(ctxt);
+
+ BC_CHECK_NUM_ERR(ctxt, n);
+
+ BC_FUNC_HEADER(err);
+
+ assert(n.i < ctxt->nums.len);
+
+ nptr = BC_NUM(ctxt, n);
+
+ assert(nptr != NULL && nptr->num != NULL);
+
+ bc_num_rng(nptr, &vm.rng);
+
+err:
+ BC_SIG_MAYLOCK;
+ BC_FUNC_FOOTER(e);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return e;
+}
+
+BclError bcl_rand_seed(unsigned char seed[BC_SEED_SIZE]) {
+
+ BclError e = BCL_ERROR_NONE;
+ size_t i;
+ ulong vals[BC_SEED_ULONGS];
+
+ BC_FUNC_HEADER(err);
+
+ for (i = 0; i < BC_SEED_SIZE; ++i) {
+ ulong val = ((ulong) seed[i]) << (((ulong) CHAR_BIT) *
+ (i % sizeof(ulong)));
+ vals[i / sizeof(long)] |= val;
+ }
+
+ bc_rand_seed(&vm.rng, vals[0], vals[1], vals[2], vals[3]);
+
+err:
+ BC_SIG_MAYLOCK;
+ BC_FUNC_FOOTER(e);
+ return e;
+}
+
+void bcl_rand_reseed(void) {
+ bc_rand_srand(bc_vec_top(&vm.rng.v));
+}
+
+BclNumber bcl_rand_seed2num(void) {
+
+ BclError e = BCL_ERROR_NONE;
+ BcNum n;
+ BclNumber idx;
+ BclContext ctxt;
+
+ BC_CHECK_CTXT(ctxt);
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ bc_num_clear(&n);
+
+ bc_num_init(&n, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_createFromRNG(&n, &vm.rng);
+
+err:
+ BC_SIG_MAYLOCK;
+ BC_FUNC_FOOTER(e);
+ BC_MAYBE_SETUP(ctxt, e, n, idx);
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+
+ return idx;
+}
+
+BclRandInt bcl_rand_int(void) {
+ return (BclRandInt) bc_rand_int(&vm.rng);
+}
+
+BclRandInt bcl_rand_bounded(BclRandInt bound) {
+ if (bound <= 1) return 0;
+ return (BclRandInt) bc_rand_bounded(&vm.rng, (BcRand) bound);
+}
+
+#endif // BC_ENABLE_LIBRARY
diff --git a/contrib/bc/src/main.c b/contrib/bc/src/main.c
new file mode 100644
index 000000000000..9c16e766e798
--- /dev/null
+++ b/contrib/bc/src/main.c
@@ -0,0 +1,90 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * The entry point for bc.
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <locale.h>
+#include <libgen.h>
+
+#include <setjmp.h>
+
+#include <status.h>
+#include <vm.h>
+#include <bc.h>
+#include <dc.h>
+
+int main(int argc, char *argv[]) {
+
+ int s;
+ char *name;
+ size_t len = strlen(BC_EXECPREFIX);
+
+ vm.locale = setlocale(LC_ALL, "");
+
+ name = strrchr(argv[0], '/');
+ vm.name = (name == NULL) ? argv[0] : name + 1;
+
+ if (strlen(vm.name) > len) vm.name += len;
+
+ BC_SIG_LOCK;
+
+ bc_vec_init(&vm.jmp_bufs, sizeof(sigjmp_buf), NULL);
+
+ BC_SETJMP_LOCKED(exit);
+
+#if !DC_ENABLED
+ bc_main(argc, argv);
+#elif !BC_ENABLED
+ dc_main(argc, argv);
+#else
+ if (BC_IS_BC) bc_main(argc, argv);
+ else dc_main(argc, argv);
+#endif
+
+exit:
+ BC_SIG_MAYLOCK;
+
+ s = !BC_STATUS_IS_ERROR(vm.status) ? BC_STATUS_SUCCESS : (int) vm.status;
+
+ bc_vm_shutdown();
+
+#ifndef NDEBUG
+ bc_vec_free(&vm.jmp_bufs);
+#endif // NDEBUG
+
+ return s;
+}
diff --git a/contrib/bc/src/num.c b/contrib/bc/src/num.c
new file mode 100644
index 000000000000..0b8823a3fec2
--- /dev/null
+++ b/contrib/bc/src/num.c
@@ -0,0 +1,2971 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code for the number type.
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include <num.h>
+#include <rand.h>
+#include <vm.h>
+
+static void bc_num_m(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale);
+
+static inline ssize_t bc_num_neg(size_t n, bool neg) {
+ return (((ssize_t) n) ^ -((ssize_t) neg)) + neg;
+}
+
+ssize_t bc_num_cmpZero(const BcNum *n) {
+ return bc_num_neg((n)->len != 0, BC_NUM_NEG(n));
+}
+
+static inline size_t bc_num_int(const BcNum *n) {
+ return n->len ? n->len - BC_NUM_RDX_VAL(n) : 0;
+}
+
+static void bc_num_expand(BcNum *restrict n, size_t req) {
+
+ assert(n != NULL);
+
+ req = req >= BC_NUM_DEF_SIZE ? req : BC_NUM_DEF_SIZE;
+
+ if (req > n->cap) {
+
+ BC_SIG_LOCK;
+
+ n->num = bc_vm_realloc(n->num, BC_NUM_SIZE(req));
+ n->cap = req;
+
+ BC_SIG_UNLOCK;
+ }
+}
+
+static void bc_num_setToZero(BcNum *restrict n, size_t scale) {
+ assert(n != NULL);
+ n->scale = scale;
+ n->len = n->rdx = 0;
+}
+
+void bc_num_zero(BcNum *restrict n) {
+ bc_num_setToZero(n, 0);
+}
+
+void bc_num_one(BcNum *restrict n) {
+ bc_num_zero(n);
+ n->len = 1;
+ n->num[0] = 1;
+}
+
+static void bc_num_clean(BcNum *restrict n) {
+
+ while (BC_NUM_NONZERO(n) && !n->num[n->len - 1]) n->len -= 1;
+
+ if (BC_NUM_ZERO(n)) n->rdx = 0;
+ else {
+ size_t rdx = BC_NUM_RDX_VAL(n);
+ if (n->len < rdx) n->len = rdx;
+ }
+}
+
+static size_t bc_num_log10(size_t i) {
+ size_t len;
+ for (len = 1; i; i /= BC_BASE, ++len);
+ assert(len - 1 <= BC_BASE_DIGS + 1);
+ return len - 1;
+}
+
+static inline size_t bc_num_zeroDigits(const BcDig *n) {
+ assert(*n >= 0);
+ assert(((size_t) *n) < BC_BASE_POW);
+ return BC_BASE_DIGS - bc_num_log10((size_t) *n);
+}
+
+static size_t bc_num_intDigits(const BcNum *n) {
+ size_t digits = bc_num_int(n) * BC_BASE_DIGS;
+ if (digits > 0) digits -= bc_num_zeroDigits(n->num + n->len - 1);
+ return digits;
+}
+
+static size_t bc_num_nonzeroLen(const BcNum *restrict n) {
+ size_t i, len = n->len;
+ assert(len == BC_NUM_RDX_VAL(n));
+ for (i = len - 1; i < len && !n->num[i]; --i);
+ assert(i + 1 > 0);
+ return i + 1;
+}
+
+static BcDig bc_num_addDigits(BcDig a, BcDig b, bool *carry) {
+
+ assert(((BcBigDig) BC_BASE_POW) * 2 == ((BcDig) BC_BASE_POW) * 2);
+ assert(a < BC_BASE_POW);
+ assert(b < BC_BASE_POW);
+
+ a += b + *carry;
+ *carry = (a >= BC_BASE_POW);
+ if (*carry) a -= BC_BASE_POW;
+
+ assert(a >= 0);
+ assert(a < BC_BASE_POW);
+
+ return a;
+}
+
+static BcDig bc_num_subDigits(BcDig a, BcDig b, bool *carry) {
+
+ assert(a < BC_BASE_POW);
+ assert(b < BC_BASE_POW);
+
+ b += *carry;
+ *carry = (a < b);
+ if (*carry) a += BC_BASE_POW;
+
+ assert(a - b >= 0);
+ assert(a - b < BC_BASE_POW);
+
+ return a - b;
+}
+
+static void bc_num_addArrays(BcDig *restrict a, const BcDig *restrict b,
+ size_t len)
+{
+ size_t i;
+ bool carry = false;
+
+ for (i = 0; i < len; ++i) a[i] = bc_num_addDigits(a[i], b[i], &carry);
+
+ for (; carry; ++i) a[i] = bc_num_addDigits(a[i], 0, &carry);
+}
+
+static void bc_num_subArrays(BcDig *restrict a, const BcDig *restrict b,
+ size_t len)
+{
+ size_t i;
+ bool carry = false;
+
+ for (i = 0; i < len; ++i) a[i] = bc_num_subDigits(a[i], b[i], &carry);
+
+ for (; carry; ++i) a[i] = bc_num_subDigits(a[i], 0, &carry);
+}
+
+static void bc_num_mulArray(const BcNum *restrict a, BcBigDig b,
+ BcNum *restrict c)
+{
+ size_t i;
+ BcBigDig carry = 0;
+
+ assert(b <= BC_BASE_POW);
+
+ if (a->len + 1 > c->cap) bc_num_expand(c, a->len + 1);
+
+ memset(c->num, 0, BC_NUM_SIZE(c->cap));
+
+ for (i = 0; i < a->len; ++i) {
+ BcBigDig in = ((BcBigDig) a->num[i]) * b + carry;
+ c->num[i] = in % BC_BASE_POW;
+ carry = in / BC_BASE_POW;
+ }
+
+ assert(carry < BC_BASE_POW);
+ c->num[i] = (BcDig) carry;
+ c->len = a->len;
+ c->len += (carry != 0);
+
+ bc_num_clean(c);
+
+ assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
+ assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
+ assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
+}
+
+static void bc_num_divArray(const BcNum *restrict a, BcBigDig b,
+ BcNum *restrict c, BcBigDig *rem)
+{
+ size_t i;
+ BcBigDig carry = 0;
+
+ assert(c->cap >= a->len);
+
+ for (i = a->len - 1; i < a->len; --i) {
+ BcBigDig in = ((BcBigDig) a->num[i]) + carry * BC_BASE_POW;
+ assert(in / b < BC_BASE_POW);
+ c->num[i] = (BcDig) (in / b);
+ carry = in % b;
+ }
+
+ c->len = a->len;
+ bc_num_clean(c);
+ *rem = carry;
+
+ assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
+ assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
+ assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
+}
+
+static ssize_t bc_num_compare(const BcDig *restrict a, const BcDig *restrict b,
+ size_t len)
+{
+ size_t i;
+ BcDig c = 0;
+ for (i = len - 1; i < len && !(c = a[i] - b[i]); --i);
+ return bc_num_neg(i + 1, c < 0);
+}
+
+ssize_t bc_num_cmp(const BcNum *a, const BcNum *b) {
+
+ size_t i, min, a_int, b_int, diff, ardx, brdx;
+ BcDig *max_num, *min_num;
+ bool a_max, neg = false;
+ ssize_t cmp;
+
+ assert(a != NULL && b != NULL);
+
+ if (a == b) return 0;
+ if (BC_NUM_ZERO(a)) return bc_num_neg(b->len != 0, !BC_NUM_NEG(b));
+ if (BC_NUM_ZERO(b)) return bc_num_cmpZero(a);
+ if (BC_NUM_NEG(a)) {
+ if (BC_NUM_NEG(b)) neg = true;
+ else return -1;
+ }
+ else if (BC_NUM_NEG(b)) return 1;
+
+ a_int = bc_num_int(a);
+ b_int = bc_num_int(b);
+ a_int -= b_int;
+
+ if (a_int) return neg ? -((ssize_t) a_int) : (ssize_t) a_int;
+
+ ardx = BC_NUM_RDX_VAL(a);
+ brdx = BC_NUM_RDX_VAL(b);
+ a_max = (ardx > brdx);
+
+ if (a_max) {
+ min = brdx;
+ diff = ardx - brdx;
+ max_num = a->num + diff;
+ min_num = b->num;
+ }
+ else {
+ min = ardx;
+ diff = brdx - ardx;
+ max_num = b->num + diff;
+ min_num = a->num;
+ }
+
+ cmp = bc_num_compare(max_num, min_num, b_int + min);
+
+ if (cmp) return bc_num_neg((size_t) cmp, !a_max == !neg);
+
+ for (max_num -= diff, i = diff - 1; i < diff; --i) {
+ if (max_num[i]) return bc_num_neg(1, !a_max == !neg);
+ }
+
+ return 0;
+}
+
+void bc_num_truncate(BcNum *restrict n, size_t places) {
+
+ size_t nrdx, places_rdx;
+
+ if (!places) return;
+
+ nrdx = BC_NUM_RDX_VAL(n);
+ places_rdx = nrdx ? nrdx - BC_NUM_RDX(n->scale - places) : 0;
+ assert(places <= n->scale && (BC_NUM_ZERO(n) || places_rdx <= n->len));
+
+ n->scale -= places;
+ BC_NUM_RDX_SET(n, nrdx - places_rdx);
+
+ if (BC_NUM_NONZERO(n)) {
+
+ size_t pow;
+
+ pow = n->scale % BC_BASE_DIGS;
+ pow = pow ? BC_BASE_DIGS - pow : 0;
+ pow = bc_num_pow10[pow];
+
+ n->len -= places_rdx;
+ memmove(n->num, n->num + places_rdx, BC_NUM_SIZE(n->len));
+
+ // Clear the lower part of the last digit.
+ if (BC_NUM_NONZERO(n)) n->num[0] -= n->num[0] % (BcDig) pow;
+
+ bc_num_clean(n);
+ }
+}
+
+void bc_num_extend(BcNum *restrict n, size_t places) {
+
+ size_t nrdx, places_rdx;
+
+ if (!places) return;
+ if (BC_NUM_ZERO(n)) {
+ n->scale += places;
+ return;
+ }
+
+ nrdx = BC_NUM_RDX_VAL(n);
+ places_rdx = BC_NUM_RDX(places + n->scale) - nrdx;
+
+ if (places_rdx) {
+ bc_num_expand(n, bc_vm_growSize(n->len, places_rdx));
+ memmove(n->num + places_rdx, n->num, BC_NUM_SIZE(n->len));
+ memset(n->num, 0, BC_NUM_SIZE(places_rdx));
+ }
+
+ BC_NUM_RDX_SET(n, nrdx + places_rdx);
+ n->scale += places;
+ n->len += places_rdx;
+
+ assert(BC_NUM_RDX_VAL(n) == BC_NUM_RDX(n->scale));
+}
+
+static void bc_num_retireMul(BcNum *restrict n, size_t scale,
+ bool neg1, bool neg2)
+{
+ if (n->scale < scale) bc_num_extend(n, scale - n->scale);
+ else bc_num_truncate(n, n->scale - scale);
+
+ bc_num_clean(n);
+ if (BC_NUM_NONZERO(n)) n->rdx = BC_NUM_NEG_VAL(n, !neg1 != !neg2);
+}
+
+static void bc_num_split(const BcNum *restrict n, size_t idx,
+ BcNum *restrict a, BcNum *restrict b)
+{
+ assert(BC_NUM_ZERO(a));
+ assert(BC_NUM_ZERO(b));
+
+ if (idx < n->len) {
+
+ b->len = n->len - idx;
+ a->len = idx;
+ a->scale = b->scale = 0;
+ BC_NUM_RDX_SET(a, 0);
+ BC_NUM_RDX_SET(b, 0);
+
+ assert(a->cap >= a->len);
+ assert(b->cap >= b->len);
+
+ memcpy(b->num, n->num + idx, BC_NUM_SIZE(b->len));
+ memcpy(a->num, n->num, BC_NUM_SIZE(idx));
+
+ bc_num_clean(b);
+ }
+ else bc_num_copy(a, n);
+
+ bc_num_clean(a);
+}
+
+static size_t bc_num_shiftZero(BcNum *restrict n) {
+
+ size_t i;
+
+ assert(!BC_NUM_RDX_VAL(n) || BC_NUM_ZERO(n));
+
+ for (i = 0; i < n->len && !n->num[i]; ++i);
+
+ n->len -= i;
+ n->num += i;
+
+ return i;
+}
+
+static void bc_num_unshiftZero(BcNum *restrict n, size_t places_rdx) {
+ n->len += places_rdx;
+ n->num -= places_rdx;
+}
+
+static void bc_num_shift(BcNum *restrict n, BcBigDig dig) {
+
+ size_t i, len = n->len;
+ BcBigDig carry = 0, pow;
+ BcDig *ptr = n->num;
+
+ assert(dig < BC_BASE_DIGS);
+
+ pow = bc_num_pow10[dig];
+ dig = bc_num_pow10[BC_BASE_DIGS - dig];
+
+ for (i = len - 1; i < len; --i) {
+ BcBigDig in, temp;
+ in = ((BcBigDig) ptr[i]);
+ temp = carry * dig;
+ carry = in % pow;
+ ptr[i] = ((BcDig) (in / pow)) + (BcDig) temp;
+ }
+
+ assert(!carry);
+}
+
+static void bc_num_shiftLeft(BcNum *restrict n, size_t places) {
+
+ BcBigDig dig;
+ size_t places_rdx;
+ bool shift;
+
+ if (!places) return;
+ if (places > n->scale) {
+ size_t size = bc_vm_growSize(BC_NUM_RDX(places - n->scale), n->len);
+ if (size > SIZE_MAX - 1) bc_vm_err(BC_ERR_MATH_OVERFLOW);
+ }
+ if (BC_NUM_ZERO(n)) {
+ if (n->scale >= places) n->scale -= places;
+ else n->scale = 0;
+ return;
+ }
+
+ dig = (BcBigDig) (places % BC_BASE_DIGS);
+ shift = (dig != 0);
+ places_rdx = BC_NUM_RDX(places);
+
+ if (n->scale) {
+
+ size_t nrdx = BC_NUM_RDX_VAL(n);
+
+ if (nrdx >= places_rdx) {
+
+ size_t mod = n->scale % BC_BASE_DIGS, revdig;
+
+ mod = mod ? mod : BC_BASE_DIGS;
+ revdig = dig ? BC_BASE_DIGS - dig : 0;
+
+ if (mod + revdig > BC_BASE_DIGS) places_rdx = 1;
+ else places_rdx = 0;
+ }
+ else places_rdx -= nrdx;
+ }
+
+ if (places_rdx) {
+ bc_num_expand(n, bc_vm_growSize(n->len, places_rdx));
+ memmove(n->num + places_rdx, n->num, BC_NUM_SIZE(n->len));
+ memset(n->num, 0, BC_NUM_SIZE(places_rdx));
+ n->len += places_rdx;
+ }
+
+ if (places > n->scale) {
+ n->scale = 0;
+ BC_NUM_RDX_SET(n, 0);
+ }
+ else {
+ n->scale -= places;
+ BC_NUM_RDX_SET(n, BC_NUM_RDX(n->scale));
+ }
+
+ if (shift) bc_num_shift(n, BC_BASE_DIGS - dig);
+
+ bc_num_clean(n);
+}
+
+void bc_num_shiftRight(BcNum *restrict n, size_t places) {
+
+ BcBigDig dig;
+ size_t places_rdx, scale, scale_mod, int_len, expand;
+ bool shift;
+
+ if (!places) return;
+ if (BC_NUM_ZERO(n)) {
+ n->scale += places;
+ bc_num_expand(n, BC_NUM_RDX(n->scale));
+ return;
+ }
+
+ dig = (BcBigDig) (places % BC_BASE_DIGS);
+ shift = (dig != 0);
+ scale = n->scale;
+ scale_mod = scale % BC_BASE_DIGS;
+ scale_mod = scale_mod ? scale_mod : BC_BASE_DIGS;
+ int_len = bc_num_int(n);
+ places_rdx = BC_NUM_RDX(places);
+
+ if (scale_mod + dig > BC_BASE_DIGS) {
+ expand = places_rdx - 1;
+ places_rdx = 1;
+ }
+ else {
+ expand = places_rdx;
+ places_rdx = 0;
+ }
+
+ if (expand > int_len) expand -= int_len;
+ else expand = 0;
+
+ bc_num_extend(n, places_rdx * BC_BASE_DIGS);
+ bc_num_expand(n, bc_vm_growSize(expand, n->len));
+ memset(n->num + n->len, 0, BC_NUM_SIZE(expand));
+ n->len += expand;
+ n->scale = 0;
+ BC_NUM_RDX_SET(n, 0);
+
+ if (shift) bc_num_shift(n, dig);
+
+ n->scale = scale + places;
+ BC_NUM_RDX_SET(n, BC_NUM_RDX(n->scale));
+
+ bc_num_clean(n);
+
+ assert(BC_NUM_RDX_VAL(n) <= n->len && n->len <= n->cap);
+ assert(BC_NUM_RDX_VAL(n) == BC_NUM_RDX(n->scale));
+}
+
+static void bc_num_inv(BcNum *a, BcNum *b, size_t scale) {
+
+ BcNum one;
+ BcDig num[2];
+
+ assert(BC_NUM_NONZERO(a));
+
+ bc_num_setup(&one, num, sizeof(num) / sizeof(BcDig));
+ bc_num_one(&one);
+
+ bc_num_div(&one, a, b, scale);
+}
+
+#if BC_ENABLE_EXTRA_MATH
+static void bc_num_intop(const BcNum *a, const BcNum *b, BcNum *restrict c,
+ BcBigDig *v)
+{
+ if (BC_ERR(BC_NUM_RDX_VAL(b))) bc_vm_err(BC_ERR_MATH_NON_INTEGER);
+ bc_num_copy(c, a);
+ bc_num_bigdig(b, v);
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+static void bc_num_as(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) {
+
+ BcDig *ptr_c, *ptr_l, *ptr_r;
+ size_t i, min_rdx, max_rdx, diff, a_int, b_int, min_len, max_len, max_int;
+ size_t len_l, len_r, ardx, brdx;
+ bool b_neg, do_sub, do_rev_sub, carry, c_neg;
+
+ // Because this function doesn't need to use scale (per the bc spec),
+ // I am hijacking it to say whether it's doing an add or a subtract.
+ // Convert substraction to addition of negative second operand.
+
+ if (BC_NUM_ZERO(b)) {
+ bc_num_copy(c, a);
+ return;
+ }
+ if (BC_NUM_ZERO(a)) {
+ bc_num_copy(c, b);
+ c->rdx = BC_NUM_NEG_VAL(c, BC_NUM_NEG(b) != sub);
+ return;
+ }
+
+ // Invert sign of b if it is to be subtracted. This operation must
+ // preced the tests for any of the operands being zero.
+ b_neg = (BC_NUM_NEG(b) != sub);
+
+ // Actually add the numbers if their signs are equal, else subtract.
+ do_sub = (BC_NUM_NEG(a) != b_neg);
+
+ a_int = bc_num_int(a);
+ b_int = bc_num_int(b);
+ max_int = BC_MAX(a_int, b_int);
+
+ ardx = BC_NUM_RDX_VAL(a);
+ brdx = BC_NUM_RDX_VAL(b);
+ min_rdx = BC_MIN(ardx, brdx);
+ max_rdx = BC_MAX(ardx, brdx);
+ diff = max_rdx - min_rdx;
+
+ max_len = max_int + max_rdx;
+
+ if (do_sub) {
+
+ // Check whether b has to be subtracted from a or a from b.
+ if (a_int != b_int) do_rev_sub = (a_int < b_int);
+ else if (ardx > brdx)
+ do_rev_sub = (bc_num_compare(a->num + diff, b->num, b->len) < 0);
+ else
+ do_rev_sub = (bc_num_compare(a->num, b->num + diff, a->len) <= 0);
+ }
+ else {
+
+ // The result array of the addition might come out one element
+ // longer than the bigger of the operand arrays.
+ max_len += 1;
+ do_rev_sub = (a_int < b_int);
+ }
+
+ assert(max_len <= c->cap);
+
+ if (do_rev_sub) {
+ ptr_l = b->num;
+ ptr_r = a->num;
+ len_l = b->len;
+ len_r = a->len;
+ }
+ else {
+ ptr_l = a->num;
+ ptr_r = b->num;
+ len_l = a->len;
+ len_r = b->len;
+ }
+
+ ptr_c = c->num;
+ carry = false;
+
+ if (diff) {
+
+ // If the rdx values of the operands do not match, the result will
+ // have low end elements that are the positive or negative trailing
+ // elements of the operand with higher rdx value.
+ if ((ardx > brdx) != do_rev_sub) {
+
+ // !do_rev_sub && ardx > brdx || do_rev_sub && brdx > ardx
+ // The left operand has BcDig values that need to be copied,
+ // either from a or from b (in case of a reversed subtraction).
+ memcpy(ptr_c, ptr_l, BC_NUM_SIZE(diff));
+ ptr_l += diff;
+ len_l -= diff;
+ }
+ else {
+
+ // The right operand has BcDig values that need to be copied
+ // or subtracted from zero (in case of a subtraction).
+ if (do_sub) {
+
+ // do_sub (do_rev_sub && ardx > brdx ||
+ // !do_rev_sub && brdx > ardx)
+ for (i = 0; i < diff; i++)
+ ptr_c[i] = bc_num_subDigits(0, ptr_r[i], &carry);
+ }
+ else {
+
+ // !do_sub && brdx > ardx
+ memcpy(ptr_c, ptr_r, BC_NUM_SIZE(diff));
+ }
+
+ ptr_r += diff;
+ len_r -= diff;
+ }
+
+ ptr_c += diff;
+ }
+
+ min_len = BC_MIN(len_l, len_r);
+
+ // After dealing with possible low array elements that depend on only one
+ // operand, the actual add or subtract can be performed as if the rdx of
+ // both operands was the same.
+ // Inlining takes care of eliminating constant zero arguments to
+ // addDigit/subDigit (checked in disassembly of resulting bc binary
+ // compiled with gcc and clang).
+ if (do_sub) {
+ for (i = 0; i < min_len; ++i)
+ ptr_c[i] = bc_num_subDigits(ptr_l[i], ptr_r[i], &carry);
+ for (; i < len_l; ++i) ptr_c[i] = bc_num_subDigits(ptr_l[i], 0, &carry);
+ }
+ else {
+ for (i = 0; i < min_len; ++i)
+ ptr_c[i] = bc_num_addDigits(ptr_l[i], ptr_r[i], &carry);
+ for (; i < len_l; ++i) ptr_c[i] = bc_num_addDigits(ptr_l[i], 0, &carry);
+ ptr_c[i] = bc_num_addDigits(0, 0, &carry);
+ }
+
+ assert(carry == false);
+
+ // The result has the same sign as a, unless the operation was a
+ // reverse subtraction (b - a).
+ c_neg = BC_NUM_NEG(a) != (do_sub && do_rev_sub);
+ BC_NUM_RDX_SET_NEG(c, max_rdx, c_neg);
+ c->len = max_len;
+ c->scale = BC_MAX(a->scale, b->scale);
+
+ bc_num_clean(c);
+}
+
+static void bc_num_m_simp(const BcNum *a, const BcNum *b, BcNum *restrict c)
+{
+ size_t i, alen = a->len, blen = b->len, clen;
+ BcDig *ptr_a = a->num, *ptr_b = b->num, *ptr_c;
+ BcBigDig sum = 0, carry = 0;
+
+ assert(sizeof(sum) >= sizeof(BcDig) * 2);
+ assert(!BC_NUM_RDX_VAL(a) && !BC_NUM_RDX_VAL(b));
+
+ clen = bc_vm_growSize(alen, blen);
+ bc_num_expand(c, bc_vm_growSize(clen, 1));
+
+ ptr_c = c->num;
+ memset(ptr_c, 0, BC_NUM_SIZE(c->cap));
+
+ for (i = 0; i < clen; ++i) {
+
+ ssize_t sidx = (ssize_t) (i - blen + 1);
+ size_t j = (size_t) BC_MAX(0, sidx), k = BC_MIN(i, blen - 1);
+
+ for (; j < alen && k < blen; ++j, --k) {
+
+ sum += ((BcBigDig) ptr_a[j]) * ((BcBigDig) ptr_b[k]);
+
+ if (sum >= ((BcBigDig) BC_BASE_POW) * BC_BASE_POW) {
+ carry += sum / BC_BASE_POW;
+ sum %= BC_BASE_POW;
+ }
+ }
+
+ if (sum >= BC_BASE_POW) {
+ carry += sum / BC_BASE_POW;
+ sum %= BC_BASE_POW;
+ }
+
+ ptr_c[i] = (BcDig) sum;
+ assert(ptr_c[i] < BC_BASE_POW);
+ sum = carry;
+ carry = 0;
+ }
+
+ // This should always be true because there should be no carry on the last
+ // digit; multiplication never goes above the sum of both lengths.
+ assert(!sum);
+
+ c->len = clen;
+}
+
+static void bc_num_shiftAddSub(BcNum *restrict n, const BcNum *restrict a,
+ size_t shift, BcNumShiftAddOp op)
+{
+ assert(n->len >= shift + a->len);
+ assert(!BC_NUM_RDX_VAL(n) && !BC_NUM_RDX_VAL(a));
+ op(n->num + shift, a->num, a->len);
+}
+
+static void bc_num_k(BcNum *a, BcNum *b, BcNum *restrict c) {
+
+ size_t max, max2, total;
+ BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp;
+ BcDig *digs, *dig_ptr;
+ BcNumShiftAddOp op;
+ bool aone = BC_NUM_ONE(a);
+
+ assert(BC_NUM_ZERO(c));
+
+ if (BC_NUM_ZERO(a) || BC_NUM_ZERO(b)) return;
+ if (aone || BC_NUM_ONE(b)) {
+ bc_num_copy(c, aone ? b : a);
+ if ((aone && BC_NUM_NEG(a)) || BC_NUM_NEG(b)) BC_NUM_NEG_TGL(c);
+ return;
+ }
+ if (a->len < BC_NUM_KARATSUBA_LEN || b->len < BC_NUM_KARATSUBA_LEN) {
+ bc_num_m_simp(a, b, c);
+ return;
+ }
+
+ max = BC_MAX(a->len, b->len);
+ max = BC_MAX(max, BC_NUM_DEF_SIZE);
+ max2 = (max + 1) / 2;
+
+ total = bc_vm_arraySize(BC_NUM_KARATSUBA_ALLOCS, max);
+
+ BC_SIG_LOCK;
+
+ digs = dig_ptr = bc_vm_malloc(BC_NUM_SIZE(total));
+
+ bc_num_setup(&l1, dig_ptr, max);
+ dig_ptr += max;
+ bc_num_setup(&h1, dig_ptr, max);
+ dig_ptr += max;
+ bc_num_setup(&l2, dig_ptr, max);
+ dig_ptr += max;
+ bc_num_setup(&h2, dig_ptr, max);
+ dig_ptr += max;
+ bc_num_setup(&m1, dig_ptr, max);
+ dig_ptr += max;
+ bc_num_setup(&m2, dig_ptr, max);
+ max = bc_vm_growSize(max, 1);
+ bc_num_init(&z0, max);
+ bc_num_init(&z1, max);
+ bc_num_init(&z2, max);
+ max = bc_vm_growSize(max, max) + 1;
+ bc_num_init(&temp, max);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_split(a, max2, &l1, &h1);
+ bc_num_split(b, max2, &l2, &h2);
+
+ bc_num_expand(c, max);
+ c->len = max;
+ memset(c->num, 0, BC_NUM_SIZE(c->len));
+
+ bc_num_sub(&h1, &l1, &m1, 0);
+ bc_num_sub(&l2, &h2, &m2, 0);
+
+ if (BC_NUM_NONZERO(&h1) && BC_NUM_NONZERO(&h2)) {
+
+ assert(BC_NUM_RDX_VALID_NP(h1));
+ assert(BC_NUM_RDX_VALID_NP(h2));
+
+ bc_num_m(&h1, &h2, &z2, 0);
+ bc_num_clean(&z2);
+
+ bc_num_shiftAddSub(c, &z2, max2 * 2, bc_num_addArrays);
+ bc_num_shiftAddSub(c, &z2, max2, bc_num_addArrays);
+ }
+
+ if (BC_NUM_NONZERO(&l1) && BC_NUM_NONZERO(&l2)) {
+
+ assert(BC_NUM_RDX_VALID_NP(l1));
+ assert(BC_NUM_RDX_VALID_NP(l2));
+
+ bc_num_m(&l1, &l2, &z0, 0);
+ bc_num_clean(&z0);
+
+ bc_num_shiftAddSub(c, &z0, max2, bc_num_addArrays);
+ bc_num_shiftAddSub(c, &z0, 0, bc_num_addArrays);
+ }
+
+ if (BC_NUM_NONZERO(&m1) && BC_NUM_NONZERO(&m2)) {
+
+ assert(BC_NUM_RDX_VALID_NP(m1));
+ assert(BC_NUM_RDX_VALID_NP(m1));
+
+ bc_num_m(&m1, &m2, &z1, 0);
+ bc_num_clean(&z1);
+
+ op = (BC_NUM_NEG_NP(m1) != BC_NUM_NEG_NP(m2)) ?
+ bc_num_subArrays : bc_num_addArrays;
+ bc_num_shiftAddSub(c, &z1, max2, op);
+ }
+
+err:
+ BC_SIG_MAYLOCK;
+ free(digs);
+ bc_num_free(&temp);
+ bc_num_free(&z2);
+ bc_num_free(&z1);
+ bc_num_free(&z0);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_num_m(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcNum cpa, cpb;
+ size_t ascale, bscale, ardx, brdx, azero = 0, bzero = 0, zero, len, rscale;
+
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+
+ bc_num_zero(c);
+ ascale = a->scale;
+ bscale = b->scale;
+ scale = BC_MAX(scale, ascale);
+ scale = BC_MAX(scale, bscale);
+
+ rscale = ascale + bscale;
+ scale = BC_MIN(rscale, scale);
+
+ if ((a->len == 1 || b->len == 1) && !a->rdx && !b->rdx) {
+
+ BcNum *operand;
+ BcBigDig dig;
+
+ if (a->len == 1) {
+ dig = (BcBigDig) a->num[0];
+ operand = b;
+ }
+ else {
+ dig = (BcBigDig) b->num[0];
+ operand = a;
+ }
+
+ bc_num_mulArray(operand, dig, c);
+
+ if (BC_NUM_NONZERO(c))
+ c->rdx = BC_NUM_NEG_VAL(c, BC_NUM_NEG(a) != BC_NUM_NEG(b));
+
+ return;
+ }
+
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&cpa, a->len + BC_NUM_RDX_VAL(a));
+ bc_num_init(&cpb, b->len + BC_NUM_RDX_VAL(b));
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_copy(&cpa, a);
+ bc_num_copy(&cpb, b);
+
+ assert(BC_NUM_RDX_VALID_NP(cpa));
+ assert(BC_NUM_RDX_VALID_NP(cpb));
+
+ BC_NUM_NEG_CLR_NP(cpa);
+ BC_NUM_NEG_CLR_NP(cpb);
+
+ assert(BC_NUM_RDX_VALID_NP(cpa));
+ assert(BC_NUM_RDX_VALID_NP(cpb));
+
+ ardx = BC_NUM_RDX_VAL_NP(cpa) * BC_BASE_DIGS;
+ bc_num_shiftLeft(&cpa, ardx);
+
+ brdx = BC_NUM_RDX_VAL_NP(cpb) * BC_BASE_DIGS;
+ bc_num_shiftLeft(&cpb, brdx);
+
+ // We need to reset the jump here because azero and bzero are used in the
+ // cleanup, and local variables are not guaranteed to be the same after a
+ // jump.
+ BC_SIG_LOCK;
+
+ BC_UNSETJMP;
+
+ azero = bc_num_shiftZero(&cpa);
+ bzero = bc_num_shiftZero(&cpb);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_clean(&cpa);
+ bc_num_clean(&cpb);
+
+ bc_num_k(&cpa, &cpb, c);
+
+ zero = bc_vm_growSize(azero, bzero);
+ len = bc_vm_growSize(c->len, zero);
+
+ bc_num_expand(c, len);
+ bc_num_shiftLeft(c, (len - c->len) * BC_BASE_DIGS);
+ bc_num_shiftRight(c, ardx + brdx);
+
+ bc_num_retireMul(c, scale, BC_NUM_NEG(a), BC_NUM_NEG(b));
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_unshiftZero(&cpb, bzero);
+ bc_num_free(&cpb);
+ bc_num_unshiftZero(&cpa, azero);
+ bc_num_free(&cpa);
+ BC_LONGJMP_CONT;
+}
+
+static bool bc_num_nonZeroDig(BcDig *restrict a, size_t len) {
+ size_t i;
+ bool nonzero = false;
+ for (i = len - 1; !nonzero && i < len; --i) nonzero = (a[i] != 0);
+ return nonzero;
+}
+
+static ssize_t bc_num_divCmp(const BcDig *a, const BcNum *b, size_t len) {
+
+ ssize_t cmp;
+
+ if (b->len > len && a[len]) cmp = bc_num_compare(a, b->num, len + 1);
+ else if (b->len <= len) {
+ if (a[len]) cmp = 1;
+ else cmp = bc_num_compare(a, b->num, len);
+ }
+ else cmp = -1;
+
+ return cmp;
+}
+
+static void bc_num_divExtend(BcNum *restrict a, BcNum *restrict b,
+ BcBigDig divisor)
+{
+ size_t pow;
+
+ assert(divisor < BC_BASE_POW);
+
+ pow = BC_BASE_DIGS - bc_num_log10((size_t) divisor);
+
+ bc_num_shiftLeft(a, pow);
+ bc_num_shiftLeft(b, pow);
+}
+
+static void bc_num_d_long(BcNum *restrict a, BcNum *restrict b,
+ BcNum *restrict c, size_t scale)
+{
+ BcBigDig divisor;
+ size_t len, end, i, rdx;
+ BcNum cpb;
+ bool nonzero = false;
+
+ assert(b->len < a->len);
+ len = b->len;
+ end = a->len - len;
+ assert(len >= 1);
+
+ bc_num_expand(c, a->len);
+ memset(c->num, 0, c->cap * sizeof(BcDig));
+
+ BC_NUM_RDX_SET(c, BC_NUM_RDX_VAL(a));
+ c->scale = a->scale;
+ c->len = a->len;
+
+ divisor = (BcBigDig) b->num[len - 1];
+
+ if (len > 1 && bc_num_nonZeroDig(b->num, len - 1)) {
+
+ nonzero = (divisor > 1 << ((10 * BC_BASE_DIGS) / 6 + 1));
+
+ if (!nonzero) {
+
+ bc_num_divExtend(a, b, divisor);
+
+ len = BC_MAX(a->len, b->len);
+ bc_num_expand(a, len + 1);
+
+ if (len + 1 > a->len) a->len = len + 1;
+
+ len = b->len;
+ end = a->len - len;
+ divisor = (BcBigDig) b->num[len - 1];
+
+ nonzero = bc_num_nonZeroDig(b->num, len - 1);
+ }
+ }
+
+ divisor += nonzero;
+
+ bc_num_expand(c, a->len);
+ memset(c->num, 0, BC_NUM_SIZE(c->cap));
+
+ assert(c->scale >= scale);
+ rdx = BC_NUM_RDX_VAL(c) - BC_NUM_RDX(scale);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&cpb, len + 1);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ i = end - 1;
+
+ for (; i < end && i >= rdx && BC_NUM_NONZERO(a); --i) {
+
+ ssize_t cmp;
+ BcDig *n;
+ BcBigDig result;
+
+ n = a->num + i;
+ assert(n >= a->num);
+ result = 0;
+
+ cmp = bc_num_divCmp(n, b, len);
+
+ while (cmp >= 0) {
+
+ BcBigDig n1, dividend, q;
+
+ n1 = (BcBigDig) n[len];
+ dividend = n1 * BC_BASE_POW + (BcBigDig) n[len - 1];
+ q = (dividend / divisor);
+
+ if (q <= 1) {
+ q = 1;
+ bc_num_subArrays(n, b->num, len);
+ }
+ else {
+
+ assert(q <= BC_BASE_POW);
+
+ bc_num_mulArray(b, (BcBigDig) q, &cpb);
+ bc_num_subArrays(n, cpb.num, cpb.len);
+ }
+
+ result += q;
+ assert(result <= BC_BASE_POW);
+
+ if (nonzero) cmp = bc_num_divCmp(n, b, len);
+ else cmp = -1;
+ }
+
+ assert(result < BC_BASE_POW);
+
+ c->num[i] = (BcDig) result;
+ }
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&cpb);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_num_d(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ size_t len, cpardx;
+ BcNum cpa, cpb;
+
+ if (BC_NUM_ZERO(b)) bc_vm_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
+ if (BC_NUM_ZERO(a)) {
+ bc_num_setToZero(c, scale);
+ return;
+ }
+ if (BC_NUM_ONE(b)) {
+ bc_num_copy(c, a);
+ bc_num_retireMul(c, scale, BC_NUM_NEG(a), BC_NUM_NEG(b));
+ return;
+ }
+ if (!BC_NUM_RDX_VAL(a) && !BC_NUM_RDX_VAL(b) && b->len == 1 && !scale) {
+ BcBigDig rem;
+ bc_num_divArray(a, (BcBigDig) b->num[0], c, &rem);
+ bc_num_retireMul(c, scale, BC_NUM_NEG(a), BC_NUM_NEG(b));
+ return;
+ }
+
+ len = bc_num_divReq(a, b, scale);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&cpa, len);
+ bc_num_copy(&cpa, a);
+ bc_num_createCopy(&cpb, b);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ len = b->len;
+
+ if (len > cpa.len) {
+ bc_num_expand(&cpa, bc_vm_growSize(len, 2));
+ bc_num_extend(&cpa, (len - cpa.len) * BC_BASE_DIGS);
+ }
+
+ cpardx = BC_NUM_RDX_VAL_NP(cpa);
+ cpa.scale = cpardx * BC_BASE_DIGS;
+
+ bc_num_extend(&cpa, b->scale);
+ cpardx = BC_NUM_RDX_VAL_NP(cpa) - BC_NUM_RDX(b->scale);
+ BC_NUM_RDX_SET_NP(cpa, cpardx);
+ cpa.scale = cpardx * BC_BASE_DIGS;
+
+ if (scale > cpa.scale) {
+ bc_num_extend(&cpa, scale);
+ cpardx = BC_NUM_RDX_VAL_NP(cpa);
+ cpa.scale = cpardx * BC_BASE_DIGS;
+ }
+
+ if (cpa.cap == cpa.len) bc_num_expand(&cpa, bc_vm_growSize(cpa.len, 1));
+
+ // We want an extra zero in front to make things simpler.
+ cpa.num[cpa.len++] = 0;
+
+ if (cpardx == cpa.len) cpa.len = bc_num_nonzeroLen(&cpa);
+ if (BC_NUM_RDX_VAL_NP(cpb) == cpb.len) cpb.len = bc_num_nonzeroLen(&cpb);
+ cpb.scale = 0;
+ BC_NUM_RDX_SET_NP(cpb, 0);
+
+ bc_num_d_long(&cpa, &cpb, c, scale);
+
+ bc_num_retireMul(c, scale, BC_NUM_NEG(a), BC_NUM_NEG(b));
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&cpb);
+ bc_num_free(&cpa);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_num_r(BcNum *a, BcNum *b, BcNum *restrict c,
+ BcNum *restrict d, size_t scale, size_t ts)
+{
+ BcNum temp;
+ bool neg;
+
+ if (BC_NUM_ZERO(b)) bc_vm_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
+ if (BC_NUM_ZERO(a)) {
+ bc_num_setToZero(c, ts);
+ bc_num_setToZero(d, ts);
+ return;
+ }
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&temp, d->cap);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_d(a, b, c, scale);
+
+ if (scale) scale = ts + 1;
+
+ assert(BC_NUM_RDX_VALID(c));
+ assert(BC_NUM_RDX_VALID(b));
+
+ bc_num_m(c, b, &temp, scale);
+ bc_num_sub(a, &temp, d, scale);
+
+ if (ts > d->scale && BC_NUM_NONZERO(d)) bc_num_extend(d, ts - d->scale);
+
+ neg = BC_NUM_NEG(d);
+ bc_num_retireMul(d, ts, BC_NUM_NEG(a), BC_NUM_NEG(b));
+ d->rdx = BC_NUM_NEG_VAL(d, BC_NUM_NONZERO(d) ? neg : false);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&temp);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_num_rem(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcNum c1;
+ size_t ts;
+
+ ts = bc_vm_growSize(scale, b->scale);
+ ts = BC_MAX(ts, a->scale);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&c1, bc_num_mulReq(a, b, ts));
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_r(a, b, &c1, c, scale, ts);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&c1);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcNum copy;
+ BcBigDig pow = 0;
+ size_t i, powrdx, resrdx;
+ bool neg, zero;
+
+ if (BC_ERR(BC_NUM_RDX_VAL(b))) bc_vm_err(BC_ERR_MATH_NON_INTEGER);
+
+ if (BC_NUM_ZERO(b)) {
+ bc_num_one(c);
+ return;
+ }
+ if (BC_NUM_ZERO(a)) {
+ if (BC_NUM_NEG(b)) bc_vm_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
+ bc_num_setToZero(c, scale);
+ return;
+ }
+ if (BC_NUM_ONE(b)) {
+ if (!BC_NUM_NEG(b)) bc_num_copy(c, a);
+ else bc_num_inv(a, c, scale);
+ return;
+ }
+
+ BC_SIG_LOCK;
+
+ neg = BC_NUM_NEG(b);
+ BC_NUM_NEG_CLR(b);
+ bc_num_bigdig(b, &pow);
+ b->rdx = BC_NUM_NEG_VAL(b, neg);
+
+ bc_num_createCopy(&copy, a);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ if (!neg) {
+ size_t max = BC_MAX(scale, a->scale), scalepow = a->scale * pow;
+ scale = BC_MIN(scalepow, max);
+ }
+
+ for (powrdx = a->scale; !(pow & 1); pow >>= 1) {
+ powrdx <<= 1;
+ assert(BC_NUM_RDX_VALID_NP(copy));
+ bc_num_mul(&copy, &copy, &copy, powrdx);
+ }
+
+ bc_num_copy(c, &copy);
+ resrdx = powrdx;
+
+ while (pow >>= 1) {
+
+ powrdx <<= 1;
+ assert(BC_NUM_RDX_VALID_NP(copy));
+ bc_num_mul(&copy, &copy, &copy, powrdx);
+
+ if (pow & 1) {
+ resrdx += powrdx;
+ assert(BC_NUM_RDX_VALID(c));
+ assert(BC_NUM_RDX_VALID_NP(copy));
+ bc_num_mul(c, &copy, c, resrdx);
+ }
+ }
+
+ if (neg) bc_num_inv(c, c, scale);
+
+ if (c->scale > scale) bc_num_truncate(c, c->scale - scale);
+
+ // We can't use bc_num_clean() here.
+ for (zero = true, i = 0; zero && i < c->len; ++i) zero = !c->num[i];
+ if (zero) bc_num_setToZero(c, scale);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&copy);
+ BC_LONGJMP_CONT;
+}
+
+#if BC_ENABLE_EXTRA_MATH
+static void bc_num_place(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcBigDig val = 0;
+
+ BC_UNUSED(scale);
+
+ bc_num_intop(a, b, c, &val);
+
+ if (val < c->scale) bc_num_truncate(c, c->scale - val);
+ else if (val > c->scale) bc_num_extend(c, val - c->scale);
+}
+
+static void bc_num_left(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcBigDig val = 0;
+
+ BC_UNUSED(scale);
+
+ bc_num_intop(a, b, c, &val);
+
+ bc_num_shiftLeft(c, (size_t) val);
+}
+
+static void bc_num_right(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcBigDig val = 0;
+
+ BC_UNUSED(scale);
+
+ bc_num_intop(a, b, c, &val);
+
+ if (BC_NUM_ZERO(c)) return;
+
+ bc_num_shiftRight(c, (size_t) val);
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+static void bc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale,
+ BcNumBinaryOp op, size_t req)
+{
+ BcNum *ptr_a, *ptr_b, num2;
+ bool init = false;
+
+ assert(a != NULL && b != NULL && c != NULL && op != NULL);
+
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+
+ BC_SIG_LOCK;
+
+ if (c == a) {
+
+ ptr_a = &num2;
+
+ memcpy(ptr_a, c, sizeof(BcNum));
+ init = true;
+ }
+ else {
+ ptr_a = a;
+ }
+
+ if (c == b) {
+
+ ptr_b = &num2;
+
+ if (c != a) {
+ memcpy(ptr_b, c, sizeof(BcNum));
+ init = true;
+ }
+ }
+ else {
+ ptr_b = b;
+ }
+
+ if (init) {
+
+ bc_num_init(c, req);
+
+ BC_SETJMP_LOCKED(err);
+ BC_SIG_UNLOCK;
+ }
+ else {
+ BC_SIG_UNLOCK;
+ bc_num_expand(c, req);
+ }
+
+ op(ptr_a, ptr_b, c, scale);
+
+ assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
+ assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
+ assert(BC_NUM_RDX_VALID(c));
+ assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
+
+err:
+ if (init) {
+ BC_SIG_MAYLOCK;
+ bc_num_free(&num2);
+ BC_LONGJMP_CONT;
+ }
+}
+
+#if !defined(NDEBUG) || BC_ENABLE_LIBRARY
+bool bc_num_strValid(const char *restrict val) {
+
+ bool radix = false;
+ size_t i, len = strlen(val);
+
+ if (!len) return true;
+
+ for (i = 0; i < len; ++i) {
+
+ BcDig c = val[i];
+
+ if (c == '.') {
+
+ if (radix) return false;
+
+ radix = true;
+ continue;
+ }
+
+ if (!(isdigit(c) || isupper(c))) return false;
+ }
+
+ return true;
+}
+#endif // !defined(NDEBUG) || BC_ENABLE_LIBRARY
+
+static BcBigDig bc_num_parseChar(char c, size_t base_t) {
+
+ if (isupper(c)) {
+ c = BC_NUM_NUM_LETTER(c);
+ c = ((size_t) c) >= base_t ? (char) base_t - 1 : c;
+ }
+ else c -= '0';
+
+ return (BcBigDig) (uchar) c;
+}
+
+static void bc_num_parseDecimal(BcNum *restrict n, const char *restrict val) {
+
+ size_t len, i, temp, mod;
+ const char *ptr;
+ bool zero = true, rdx;
+
+ for (i = 0; val[i] == '0'; ++i);
+
+ val += i;
+ assert(!val[0] || isalnum(val[0]) || val[0] == '.');
+
+ // All 0's. We can just return, since this
+ // procedure expects a virgin (already 0) BcNum.
+ if (!val[0]) return;
+
+ len = strlen(val);
+
+ ptr = strchr(val, '.');
+ rdx = (ptr != NULL);
+
+ for (i = 0; i < len && (zero = (val[i] == '0' || val[i] == '.')); ++i);
+
+ n->scale = (size_t) (rdx * (((uintptr_t) (val + len)) -
+ (((uintptr_t) ptr) + 1)));
+
+ BC_NUM_RDX_SET(n, BC_NUM_RDX(n->scale));
+ i = len - (ptr == val ? 0 : i) - rdx;
+ temp = BC_NUM_ROUND_POW(i);
+ mod = n->scale % BC_BASE_DIGS;
+ i = mod ? BC_BASE_DIGS - mod : 0;
+ n->len = ((temp + i) / BC_BASE_DIGS);
+
+ bc_num_expand(n, n->len);
+ memset(n->num, 0, BC_NUM_SIZE(n->len));
+
+ if (zero) {
+ // I think I can set rdx directly to zero here because n should be a
+ // new number with sign set to false.
+ n->len = n->rdx = 0;
+ }
+ else {
+
+ BcBigDig exp, pow;
+
+ assert(i <= BC_NUM_BIGDIG_MAX);
+
+ exp = (BcBigDig) i;
+ pow = bc_num_pow10[exp];
+
+ for (i = len - 1; i < len; --i, ++exp) {
+
+ char c = val[i];
+
+ if (c == '.') exp -= 1;
+ else {
+
+ size_t idx = exp / BC_BASE_DIGS;
+
+ if (isupper(c)) c = '9';
+ n->num[idx] += (((BcBigDig) c) - '0') * pow;
+
+ if ((exp + 1) % BC_BASE_DIGS == 0) pow = 1;
+ else pow *= BC_BASE;
+ }
+ }
+ }
+}
+
+static void bc_num_parseBase(BcNum *restrict n, const char *restrict val,
+ BcBigDig base)
+{
+ BcNum temp, mult1, mult2, result1, result2, *m1, *m2, *ptr;
+ char c = 0;
+ bool zero = true;
+ BcBigDig v;
+ size_t i, digs, len = strlen(val);
+
+ for (i = 0; zero && i < len; ++i) zero = (val[i] == '.' || val[i] == '0');
+ if (zero) return;
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&temp, BC_NUM_BIGDIG_LOG10);
+ bc_num_init(&mult1, BC_NUM_BIGDIG_LOG10);
+
+ BC_SETJMP_LOCKED(int_err);
+
+ BC_SIG_UNLOCK;
+
+ for (i = 0; i < len && (c = val[i]) && c != '.'; ++i) {
+
+ v = bc_num_parseChar(c, base);
+
+ bc_num_mulArray(n, base, &mult1);
+ bc_num_bigdig2num(&temp, v);
+ bc_num_add(&mult1, &temp, n, 0);
+ }
+
+ if (i == len && !(c = val[i])) goto int_err;
+
+ assert(c == '.');
+
+ BC_SIG_LOCK;
+
+ BC_UNSETJMP;
+
+ bc_num_init(&mult2, BC_NUM_BIGDIG_LOG10);
+ bc_num_init(&result1, BC_NUM_DEF_SIZE);
+ bc_num_init(&result2, BC_NUM_DEF_SIZE);
+ bc_num_one(&mult1);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ m1 = &mult1;
+ m2 = &mult2;
+
+ for (i += 1, digs = 0; i < len && (c = val[i]); ++i, ++digs) {
+
+ size_t rdx;
+
+ v = bc_num_parseChar(c, base);
+
+ bc_num_mulArray(&result1, base, &result2);
+
+ bc_num_bigdig2num(&temp, v);
+ bc_num_add(&result2, &temp, &result1, 0);
+ bc_num_mulArray(m1, base, m2);
+
+ rdx = BC_NUM_RDX_VAL(m2);
+
+ if (m2->len < rdx) m2->len = rdx;
+
+ ptr = m1;
+ m1 = m2;
+ m2 = ptr;
+ }
+
+ // This one cannot be a divide by 0 because mult starts out at 1, then is
+ // multiplied by base, and base cannot be 0, so mult cannot be 0.
+ bc_num_div(&result1, m1, &result2, digs * 2);
+ bc_num_truncate(&result2, digs);
+ bc_num_add(n, &result2, n, digs);
+
+ if (BC_NUM_NONZERO(n)) {
+ if (n->scale < digs) bc_num_extend(n, digs - n->scale);
+ }
+ else bc_num_zero(n);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&result2);
+ bc_num_free(&result1);
+ bc_num_free(&mult2);
+int_err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&mult1);
+ bc_num_free(&temp);
+ BC_LONGJMP_CONT;
+}
+
+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');
+ }
+#endif // !BC_ENABLE_LIBRARY
+}
+
+static void bc_num_putchar(int c) {
+ if (c != '\n') bc_num_printNewline();
+ bc_vm_putchar(c);
+}
+
+#if DC_ENABLED && !BC_ENABLE_LIBRARY
+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);
+}
+#endif // DC_ENABLED && !BC_ENABLE_LIBRARY
+
+static void bc_num_printDigits(size_t n, size_t len, bool rdx) {
+
+ size_t exp, pow;
+
+ bc_num_putchar(rdx ? '.' : ' ');
+
+ for (exp = 0, pow = 1; exp < len - 1; ++exp, pow *= BC_BASE);
+
+ for (exp = 0; exp < len; pow /= BC_BASE, ++exp) {
+ size_t dig = n / pow;
+ n -= dig * pow;
+ bc_num_putchar(((uchar) dig) + '0');
+ }
+}
+
+static void bc_num_printHex(size_t n, size_t len, bool rdx) {
+
+ BC_UNUSED(len);
+
+ assert(len == 1);
+
+ if (rdx) bc_num_putchar('.');
+
+ bc_num_putchar(bc_num_hex_digits[n]);
+}
+
+static void bc_num_printDecimal(const BcNum *restrict n) {
+
+ size_t i, j, rdx = BC_NUM_RDX_VAL(n);
+ bool zero = true;
+ size_t buffer[BC_BASE_DIGS];
+
+ if (BC_NUM_NEG(n)) bc_num_putchar('-');
+
+ for (i = n->len - 1; i < n->len; --i) {
+
+ BcDig n9 = n->num[i];
+ size_t temp;
+ bool irdx = (i == rdx - 1);
+
+ zero = (zero & !irdx);
+ temp = n->scale % BC_BASE_DIGS;
+ temp = i || !temp ? 0 : BC_BASE_DIGS - temp;
+
+ memset(buffer, 0, BC_BASE_DIGS * sizeof(size_t));
+
+ for (j = 0; n9 && j < BC_BASE_DIGS; ++j) {
+ buffer[j] = ((size_t) n9) % BC_BASE;
+ n9 /= BC_BASE;
+ }
+
+ for (j = BC_BASE_DIGS - 1; j < BC_BASE_DIGS && j >= temp; --j) {
+ bool print_rdx = (irdx & (j == BC_BASE_DIGS - 1));
+ zero = (zero && buffer[j] == 0);
+ if (!zero) bc_num_printHex(buffer[j], 1, print_rdx);
+ }
+ }
+}
+
+#if BC_ENABLE_EXTRA_MATH
+static void bc_num_printExponent(const BcNum *restrict n, bool eng) {
+
+ size_t places, mod, nrdx = BC_NUM_RDX_VAL(n);
+ bool neg = (n->len <= nrdx);
+ BcNum temp, exp;
+ BcDig digs[BC_NUM_BIGDIG_LOG10];
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&temp, n);
+
+ BC_SETJMP_LOCKED(exit);
+
+ BC_SIG_UNLOCK;
+
+ if (neg) {
+
+ size_t i, idx = bc_num_nonzeroLen(n) - 1;
+
+ places = 1;
+
+ for (i = BC_BASE_DIGS - 1; i < BC_BASE_DIGS; --i) {
+ if (bc_num_pow10[i] > (BcBigDig) n->num[idx]) places += 1;
+ else break;
+ }
+
+ places += (nrdx - (idx + 1)) * BC_BASE_DIGS;
+ mod = places % 3;
+
+ if (eng && mod != 0) places += 3 - mod;
+ bc_num_shiftLeft(&temp, places);
+ }
+ else {
+ places = bc_num_intDigits(n) - 1;
+ mod = places % 3;
+ if (eng && mod != 0) places -= 3 - (3 - mod);
+ bc_num_shiftRight(&temp, places);
+ }
+
+ bc_num_printDecimal(&temp);
+ bc_num_putchar('e');
+
+ if (!places) {
+ bc_num_printHex(0, 1, false);
+ goto exit;
+ }
+
+ if (neg) bc_num_putchar('-');
+
+ bc_num_setup(&exp, digs, BC_NUM_BIGDIG_LOG10);
+ bc_num_bigdig2num(&exp, (BcBigDig) places);
+
+ bc_num_printDecimal(&exp);
+
+exit:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&temp);
+ BC_LONGJMP_CONT;
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+static void bc_num_printFixup(BcNum *restrict n, BcBigDig rem,
+ BcBigDig pow, size_t idx)
+{
+ size_t i, len = n->len - idx;
+ BcBigDig acc;
+ BcDig *a = n->num + idx;
+
+ if (len < 2) return;
+
+ for (i = len - 1; i > 0; --i) {
+
+ acc = ((BcBigDig) a[i]) * rem + ((BcBigDig) a[i - 1]);
+ a[i - 1] = (BcDig) (acc % pow);
+ acc /= pow;
+ acc += (BcBigDig) a[i];
+
+ if (acc >= BC_BASE_POW) {
+
+ if (i == len - 1) {
+ len = bc_vm_growSize(len, 1);
+ bc_num_expand(n, bc_vm_growSize(len, idx));
+ a = n->num + idx;
+ a[len - 1] = 0;
+ }
+
+ a[i + 1] += acc / BC_BASE_POW;
+ acc %= BC_BASE_POW;
+ }
+
+ assert(acc < BC_BASE_POW);
+ a[i] = (BcDig) acc;
+ }
+
+ n->len = len + idx;
+}
+
+static void bc_num_printPrepare(BcNum *restrict n, BcBigDig rem,
+ BcBigDig pow)
+{
+ size_t i;
+
+ for (i = 0; i < n->len; ++i) bc_num_printFixup(n, rem, pow, i);
+
+ for (i = 0; i < n->len; ++i) {
+
+ assert(pow == ((BcBigDig) ((BcDig) pow)));
+
+ if (n->num[i] >= (BcDig) pow) {
+
+ if (i + 1 == n->len) {
+ n->len = bc_vm_growSize(n->len, 1);
+ bc_num_expand(n, n->len);
+ n->num[i + 1] = 0;
+ }
+
+ assert(pow < BC_BASE_POW);
+ n->num[i + 1] += n->num[i] / ((BcDig) pow);
+ n->num[i] %= (BcDig) pow;
+ }
+ }
+}
+
+static void bc_num_printNum(BcNum *restrict n, BcBigDig base,
+ size_t len, BcNumDigitOp print)
+{
+ BcVec stack;
+ BcNum intp, fracp1, fracp2, digit, flen1, flen2, *n1, *n2, *temp;
+ BcBigDig dig = 0, *ptr, acc, exp;
+ size_t i, j, nrdx;
+ bool radix;
+ BcDig digit_digs[BC_NUM_BIGDIG_LOG10 + 1];
+
+ assert(base > 1);
+
+ if (BC_NUM_ZERO(n)) {
+ print(0, len, false);
+ return;
+ }
+
+ // This function uses an algorithm that Stefan Esser <se@freebsd.org> came
+ // up with to print the integer part of a number. What it does is convert
+ // intp into a number of the specified base, but it does it directly,
+ // instead of just doing a series of divisions and printing the remainders
+ // in reverse order.
+ //
+ // Let me explain in a bit more detail:
+ //
+ // The algorithm takes the current least significant digit (after intp has
+ // been converted to an integer) and the next to least significant digit,
+ // and it converts the least significant digit into one of the specified
+ // base, putting any overflow into the next to least significant digit. It
+ // iterates through the whole number, from least significant to most
+ // significant, doing this conversion. At the end of that iteration, the
+ // least significant digit is converted, but the others are not, so it
+ // iterates again, starting at the next to least significant digit. It keeps
+ // doing that conversion, skipping one more digit than the last time, until
+ // all digits have been converted. Then it prints them in reverse order.
+ //
+ // That is the gist of the algorithm. It leaves out several things, such as
+ // the fact that digits are not always converted into the specified base,
+ // but into something close, basically a power of the specified base. In
+ // Stefan's words, "You could consider BcDigs to be of base 10^BC_BASE_DIGS
+ // in the normal case and obase^N for the largest value of N that satisfies
+ // obase^N <= 10^BC_BASE_DIGS. [This means that] the result is not in base
+ // "obase", but in base "obase^N", which happens to be printable as a number
+ // of base "obase" without consideration for neighbouring BcDigs." This fact
+ // is what necessitates the existence of the loop later in this function.
+ //
+ // The conversion happens in bc_num_printPrepare() where the outer loop
+ // happens and bc_num_printFixup() where the inner loop, or actual
+ // conversion, happens.
+
+ nrdx = BC_NUM_RDX_VAL(n);
+
+ BC_SIG_LOCK;
+
+ bc_vec_init(&stack, sizeof(BcBigDig), NULL);
+ bc_num_init(&fracp1, nrdx);
+
+ bc_num_createCopy(&intp, n);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_truncate(&intp, intp.scale);
+
+ bc_num_sub(n, &intp, &fracp1, 0);
+
+ if (base != vm.last_base) {
+
+ vm.last_pow = 1;
+ vm.last_exp = 0;
+
+ while (vm.last_pow * base <= BC_BASE_POW) {
+ vm.last_pow *= base;
+ vm.last_exp += 1;
+ }
+
+ vm.last_rem = BC_BASE_POW - vm.last_pow;
+ vm.last_base = base;
+ }
+
+ exp = vm.last_exp;
+
+ if (vm.last_rem != 0) bc_num_printPrepare(&intp, vm.last_rem, vm.last_pow);
+
+ for (i = 0; i < intp.len; ++i) {
+
+ acc = (BcBigDig) intp.num[i];
+
+ for (j = 0; j < exp && (i < intp.len - 1 || acc != 0); ++j)
+ {
+ if (j != exp - 1) {
+ dig = acc % base;
+ acc /= base;
+ }
+ else {
+ dig = acc;
+ acc = 0;
+ }
+
+ assert(dig < base);
+
+ bc_vec_push(&stack, &dig);
+ }
+
+ assert(acc == 0);
+ }
+
+ for (i = 0; i < stack.len; ++i) {
+ ptr = bc_vec_item_rev(&stack, i);
+ assert(ptr != NULL);
+ print(*ptr, len, false);
+ }
+
+ if (!n->scale) goto err;
+
+ BC_SIG_LOCK;
+
+ BC_UNSETJMP;
+
+ bc_num_init(&fracp2, nrdx);
+ bc_num_setup(&digit, digit_digs, sizeof(digit_digs) / sizeof(BcDig));
+ bc_num_init(&flen1, BC_NUM_BIGDIG_LOG10);
+ bc_num_init(&flen2, BC_NUM_BIGDIG_LOG10);
+
+ BC_SETJMP_LOCKED(frac_err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_one(&flen1);
+
+ radix = true;
+ n1 = &flen1;
+ n2 = &flen2;
+
+ fracp2.scale = n->scale;
+ BC_NUM_RDX_SET_NP(fracp2, BC_NUM_RDX(fracp2.scale));
+
+ while (bc_num_intDigits(n1) < n->scale + 1) {
+
+ bc_num_expand(&fracp2, fracp1.len + 1);
+ bc_num_mulArray(&fracp1, base, &fracp2);
+
+ nrdx = BC_NUM_RDX_VAL_NP(fracp2);
+
+ if (fracp2.len < nrdx) fracp2.len = nrdx;
+
+ // fracp is guaranteed to be non-negative and small enough.
+ bc_num_bigdig2(&fracp2, &dig);
+
+ bc_num_bigdig2num(&digit, dig);
+ bc_num_sub(&fracp2, &digit, &fracp1, 0);
+
+ print(dig, len, radix);
+ bc_num_mulArray(n1, base, n2);
+
+ radix = false;
+ temp = n1;
+ n1 = n2;
+ n2 = temp;
+ }
+
+frac_err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&flen2);
+ bc_num_free(&flen1);
+ bc_num_free(&fracp2);
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&fracp1);
+ bc_num_free(&intp);
+ bc_vec_free(&stack);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_num_printBase(BcNum *restrict n, BcBigDig base) {
+
+ size_t width;
+ BcNumDigitOp print;
+ bool neg = BC_NUM_NEG(n);
+
+ if (neg) bc_num_putchar('-');
+
+ BC_NUM_NEG_CLR(n);
+
+ if (base <= BC_NUM_MAX_POSIX_IBASE) {
+ width = 1;
+ print = bc_num_printHex;
+ }
+ else {
+ assert(base <= BC_BASE_POW);
+ width = bc_num_log10(base - 1);
+ print = bc_num_printDigits;
+ }
+
+ bc_num_printNum(n, base, width, print);
+ n->rdx = BC_NUM_NEG_VAL(n, neg);
+}
+
+#if DC_ENABLED && !BC_ENABLE_LIBRARY
+void bc_num_stream(BcNum *restrict n, BcBigDig base) {
+ bc_num_printNum(n, base, 1, bc_num_printChar);
+}
+#endif // DC_ENABLED && !BC_ENABLE_LIBRARY
+
+void bc_num_setup(BcNum *restrict n, BcDig *restrict num, size_t cap) {
+ assert(n != NULL);
+ n->num = num;
+ n->cap = cap;
+ bc_num_zero(n);
+}
+
+void bc_num_init(BcNum *restrict n, size_t req) {
+
+ BcDig *num;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(n != NULL);
+
+ req = req >= BC_NUM_DEF_SIZE ? req : BC_NUM_DEF_SIZE;
+
+ if (req == BC_NUM_DEF_SIZE && vm.temps.len) {
+ BcNum *nptr = bc_vec_top(&vm.temps);
+ num = nptr->num;
+ bc_vec_pop(&vm.temps);
+ }
+ else num = bc_vm_malloc(BC_NUM_SIZE(req));
+
+ bc_num_setup(n, num, req);
+}
+
+void bc_num_clear(BcNum *restrict n) {
+ n->num = NULL;
+ n->cap = 0;
+}
+
+void bc_num_free(void *num) {
+
+ BcNum *n = (BcNum*) num;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(n != NULL);
+
+ if (n->cap == BC_NUM_DEF_SIZE) bc_vec_push(&vm.temps, n);
+ else free(n->num);
+}
+
+void bc_num_copy(BcNum *d, const BcNum *s) {
+ assert(d != NULL && s != NULL);
+ if (d == s) return;
+ bc_num_expand(d, s->len);
+ d->len = s->len;
+ // I can just copy directly here.
+ d->rdx = s->rdx;
+ d->scale = s->scale;
+ memcpy(d->num, s->num, BC_NUM_SIZE(d->len));
+}
+
+void bc_num_createCopy(BcNum *d, const BcNum *s) {
+ BC_SIG_ASSERT_LOCKED;
+ bc_num_init(d, s->len);
+ bc_num_copy(d, s);
+}
+
+void bc_num_createFromBigdig(BcNum *n, BcBigDig val) {
+ BC_SIG_ASSERT_LOCKED;
+ bc_num_init(n, BC_NUM_BIGDIG_LOG10);
+ bc_num_bigdig2num(n, val);
+}
+
+size_t bc_num_scale(const BcNum *restrict n) {
+ return n->scale;
+}
+
+size_t bc_num_len(const BcNum *restrict n) {
+
+ size_t len = n->len;
+
+ if (BC_NUM_ZERO(n)) return 0;
+
+ if (BC_NUM_RDX_VAL(n) == len) {
+
+ size_t zero, scale;
+
+ len = bc_num_nonzeroLen(n);
+
+ scale = n->scale % BC_BASE_DIGS;
+ scale = scale ? scale : BC_BASE_DIGS;
+
+ zero = bc_num_zeroDigits(n->num + len - 1);
+
+ len = len * BC_BASE_DIGS - zero - (BC_BASE_DIGS - scale);
+ }
+ else len = bc_num_intDigits(n) + n->scale;
+
+ return len;
+}
+
+void bc_num_parse(BcNum *restrict n, const char *restrict val, BcBigDig base) {
+
+ assert(n != NULL && val != NULL && base);
+ assert(base >= BC_NUM_MIN_BASE && base <= vm.maxes[BC_PROG_GLOBALS_IBASE]);
+ assert(bc_num_strValid(val));
+
+ if (!val[1]) {
+ BcBigDig dig = bc_num_parseChar(val[0], BC_NUM_MAX_LBASE);
+ bc_num_bigdig2num(n, dig);
+ }
+ else if (base == BC_BASE) bc_num_parseDecimal(n, val);
+ else bc_num_parseBase(n, val, base);
+
+ assert(BC_NUM_RDX_VALID(n));
+}
+
+void bc_num_print(BcNum *restrict n, BcBigDig base, bool newline) {
+
+ assert(n != NULL);
+ assert(BC_ENABLE_EXTRA_MATH || base >= BC_NUM_MIN_BASE);
+
+ bc_num_printNewline();
+
+ if (BC_NUM_ZERO(n)) bc_num_printHex(0, 1, false);
+ else if (base == BC_BASE) bc_num_printDecimal(n);
+#if BC_ENABLE_EXTRA_MATH
+ else if (base == 0 || base == 1) bc_num_printExponent(n, base != 0);
+#endif // BC_ENABLE_EXTRA_MATH
+ else bc_num_printBase(n, base);
+
+ if (newline) bc_num_putchar('\n');
+}
+
+void bc_num_bigdig2(const BcNum *restrict n, BcBigDig *result) {
+
+ // This function returns no errors because it's guaranteed to succeed if
+ // its preconditions are met. Those preconditions include both parameters
+ // being non-NULL, n being non-negative, and n being less than vm.max. If
+ // all of that is true, then we can just convert without worrying about
+ // negative errors or overflow.
+
+ BcBigDig r = 0;
+ size_t nrdx = BC_NUM_RDX_VAL(n);
+
+ assert(n != NULL && result != NULL);
+ assert(!BC_NUM_NEG(n));
+ assert(bc_num_cmp(n, &vm.max) < 0);
+ assert(n->len - nrdx <= 3);
+
+ // There is a small speed win from unrolling the loop here, and since it
+ // only adds 53 bytes, I decided that it was worth it.
+ switch (n->len - nrdx) {
+
+ case 3:
+ {
+ r = (BcBigDig) n->num[nrdx + 2];
+ }
+ // Fallthrough.
+ BC_FALLTHROUGH
+
+ case 2:
+ {
+ r = r * BC_BASE_POW + (BcBigDig) n->num[nrdx + 1];
+ }
+ // Fallthrough.
+ BC_FALLTHROUGH
+
+ case 1:
+ {
+ r = r * BC_BASE_POW + (BcBigDig) n->num[nrdx];
+ }
+ }
+
+ *result = r;
+}
+
+void bc_num_bigdig(const BcNum *restrict n, BcBigDig *result) {
+
+ assert(n != NULL && result != NULL);
+
+ if (BC_ERR(BC_NUM_NEG(n))) bc_vm_err(BC_ERR_MATH_NEGATIVE);
+ if (BC_ERR(bc_num_cmp(n, &vm.max) >= 0))
+ bc_vm_err(BC_ERR_MATH_OVERFLOW);
+
+ bc_num_bigdig2(n, result);
+}
+
+void bc_num_bigdig2num(BcNum *restrict n, BcBigDig val) {
+
+ BcDig *ptr;
+ size_t i;
+
+ assert(n != NULL);
+
+ bc_num_zero(n);
+
+ if (!val) return;
+
+ bc_num_expand(n, BC_NUM_BIGDIG_LOG10);
+
+ for (ptr = n->num, i = 0; val; ++i, val /= BC_BASE_POW)
+ ptr[i] = val % BC_BASE_POW;
+
+ n->len = i;
+}
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+void bc_num_rng(const BcNum *restrict n, BcRNG *rng) {
+
+ BcNum temp, temp2, intn, frac;
+ BcRand state1, state2, inc1, inc2;
+ size_t nrdx = BC_NUM_RDX_VAL(n);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&temp, n->len);
+ bc_num_init(&temp2, n->len);
+ bc_num_init(&frac, nrdx);
+ bc_num_init(&intn, bc_num_int(n));
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ assert(BC_NUM_RDX_VALID_NP(vm.max));
+
+ memcpy(frac.num, n->num, BC_NUM_SIZE(nrdx));
+ frac.len = nrdx;
+ BC_NUM_RDX_SET_NP(frac, nrdx);
+ frac.scale = n->scale;
+
+ assert(BC_NUM_RDX_VALID_NP(frac));
+ assert(BC_NUM_RDX_VALID_NP(vm.max2));
+
+ bc_num_mul(&frac, &vm.max2, &temp, 0);
+
+ bc_num_truncate(&temp, temp.scale);
+ bc_num_copy(&frac, &temp);
+
+ memcpy(intn.num, n->num + nrdx, BC_NUM_SIZE(bc_num_int(n)));
+ intn.len = bc_num_int(n);
+
+ // This assert is here because it has to be true. It is also here to justify
+ // the use of BC_ERR_SIGNAL_ONLY() on each of the divmod's and mod's below.
+ assert(BC_NUM_NONZERO(&vm.max));
+
+ if (BC_NUM_NONZERO(&frac)) {
+
+ bc_num_divmod(&frac, &vm.max, &temp, &temp2, 0);
+
+ // frac is guaranteed to be smaller than vm.max * vm.max (pow).
+ // This means that when dividing frac by vm.max, as above, the
+ // quotient and remainder are both guaranteed to be less than vm.max,
+ // which means we can use bc_num_bigdig2() here and not worry about
+ // overflow.
+ bc_num_bigdig2(&temp2, (BcBigDig*) &state1);
+ bc_num_bigdig2(&temp, (BcBigDig*) &state2);
+ }
+ else state1 = state2 = 0;
+
+ if (BC_NUM_NONZERO(&intn)) {
+
+ bc_num_divmod(&intn, &vm.max, &temp, &temp2, 0);
+
+ // Because temp2 is the mod of vm.max, from above, it is guaranteed
+ // to be small enough to use bc_num_bigdig2().
+ bc_num_bigdig2(&temp2, (BcBigDig*) &inc1);
+
+ if (bc_num_cmp(&temp, &vm.max) >= 0) {
+ bc_num_copy(&temp2, &temp);
+ bc_num_mod(&temp2, &vm.max, &temp, 0);
+ }
+
+ // The if statement above ensures that temp is less than vm.max, which
+ // means that we can use bc_num_bigdig2() here.
+ bc_num_bigdig2(&temp, (BcBigDig*) &inc2);
+ }
+ else inc1 = inc2 = 0;
+
+ bc_rand_seed(rng, state1, state2, inc1, inc2);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&intn);
+ bc_num_free(&frac);
+ bc_num_free(&temp2);
+ bc_num_free(&temp);
+ BC_LONGJMP_CONT;
+}
+
+void bc_num_createFromRNG(BcNum *restrict n, BcRNG *rng) {
+
+ BcRand s1, s2, i1, i2;
+ BcNum conv, temp1, temp2, temp3;
+ BcDig temp1_num[BC_RAND_NUM_SIZE], temp2_num[BC_RAND_NUM_SIZE];
+ BcDig conv_num[BC_NUM_BIGDIG_LOG10];
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&temp3, 2 * BC_RAND_NUM_SIZE);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_setup(&temp1, temp1_num, sizeof(temp1_num) / sizeof(BcDig));
+ bc_num_setup(&temp2, temp2_num, sizeof(temp2_num) / sizeof(BcDig));
+ bc_num_setup(&conv, conv_num, sizeof(conv_num) / sizeof(BcDig));
+
+ // This assert is here because it has to be true. It is also here to justify
+ // the assumption that vm.max2 is not zero.
+ assert(BC_NUM_NONZERO(&vm.max));
+
+ // Because this is true, we can just use BC_ERR_SIGNAL_ONLY() below when
+ // dividing by vm.max2.
+ assert(BC_NUM_NONZERO(&vm.max2));
+
+ bc_rand_getRands(rng, &s1, &s2, &i1, &i2);
+
+ bc_num_bigdig2num(&conv, (BcBigDig) s2);
+
+ assert(BC_NUM_RDX_VALID_NP(conv));
+
+ bc_num_mul(&conv, &vm.max, &temp1, 0);
+
+ bc_num_bigdig2num(&conv, (BcBigDig) s1);
+
+ bc_num_add(&conv, &temp1, &temp2, 0);
+
+ bc_num_div(&temp2, &vm.max2, &temp3, BC_RAND_STATE_BITS);
+
+ bc_num_bigdig2num(&conv, (BcBigDig) i2);
+
+ assert(BC_NUM_RDX_VALID_NP(conv));
+
+ bc_num_mul(&conv, &vm.max, &temp1, 0);
+
+ bc_num_bigdig2num(&conv, (BcBigDig) i1);
+
+ bc_num_add(&conv, &temp1, &temp2, 0);
+
+ bc_num_add(&temp2, &temp3, n, 0);
+
+ assert(BC_NUM_RDX_VALID(n));
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&temp3);
+ BC_LONGJMP_CONT;
+}
+
+void bc_num_irand(const BcNum *restrict a, BcNum *restrict b,
+ BcRNG *restrict rng)
+{
+ BcRand r;
+ BcBigDig modl;
+ BcNum pow, pow2, cp, cp2, mod, temp1, temp2, rand;
+ BcNum *p1, *p2, *t1, *t2, *c1, *c2, *tmp;
+ BcDig rand_num[BC_NUM_BIGDIG_LOG10];
+ bool carry;
+ ssize_t cmp;
+
+ assert(a != b);
+
+ if (BC_ERR(BC_NUM_NEG(a))) bc_vm_err(BC_ERR_MATH_NEGATIVE);
+ if (BC_ERR(BC_NUM_RDX_VAL(a))) bc_vm_err(BC_ERR_MATH_NON_INTEGER);
+ if (BC_NUM_ZERO(a) || BC_NUM_ONE(a)) return;
+
+ cmp = bc_num_cmp(a, &vm.max);
+
+ if (cmp <= 0) {
+
+ BcRand bits = 0;
+
+ if (cmp < 0) bc_num_bigdig2(a, (BcBigDig*) &bits);
+
+ // This condition means that bits is a power of 2. In that case, we
+ // can just grab a full-size int and mask out the unneeded bits.
+ // Also, this condition says that 0 is a power of 2, which works for
+ // us, since a value of 0 means a == rng->max. The bitmask will mask
+ // nothing in that case as well.
+ if (!(bits & (bits - 1))) r = bc_rand_int(rng) & (bits - 1);
+ else r = bc_rand_bounded(rng, bits);
+
+ // We made sure that r is less than vm.max,
+ // so we can use bc_num_bigdig2() here.
+ bc_num_bigdig2num(b, r);
+
+ return;
+ }
+
+ // In the case where a is less than rng->max, we have to make sure we have
+ // an exclusive bound. This ensures that it happens. (See below.)
+ carry = (cmp < 0);
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&cp, a);
+
+ bc_num_init(&cp2, cp.len);
+ bc_num_init(&mod, BC_NUM_BIGDIG_LOG10);
+ bc_num_init(&temp1, BC_NUM_DEF_SIZE);
+ bc_num_init(&temp2, BC_NUM_DEF_SIZE);
+ bc_num_init(&pow2, BC_NUM_DEF_SIZE);
+ bc_num_init(&pow, BC_NUM_DEF_SIZE);
+ bc_num_one(&pow);
+ bc_num_setup(&rand, rand_num, sizeof(rand_num) / sizeof(BcDig));
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ p1 = &pow;
+ p2 = &pow2;
+ t1 = &temp1;
+ t2 = &temp2;
+ c1 = &cp;
+ c2 = &cp2;
+
+ // This assert is here because it has to be true. It is also here to justify
+ // the use of BC_ERR_SIGNAL_ONLY() on each of the divmod's and mod's below.
+ assert(BC_NUM_NONZERO(&vm.max));
+
+ while (BC_NUM_NONZERO(c1)) {
+
+ bc_num_divmod(c1, &vm.max, c2, &mod, 0);
+
+ // Because mod is the mod of vm.max, it is guaranteed to be smaller,
+ // which means we can use bc_num_bigdig2() here.
+ bc_num_bigdig(&mod, &modl);
+
+ if (bc_num_cmp(c1, &vm.max) < 0) {
+
+ // In this case, if there is no carry, then we know we can generate
+ // an integer *equal* to modl. Thus, we add one if there is no
+ // carry. Otherwise, we add zero, and we are still bounded properly.
+ // Since the last portion is guaranteed to be greater than 1, we
+ // know modl isn't 0 unless there is no carry.
+ modl += !carry;
+
+ if (modl == 1) r = 0;
+ else if (!modl) r = bc_rand_int(rng);
+ else r = bc_rand_bounded(rng, (BcRand) modl);
+ }
+ else {
+ if (modl) modl -= carry;
+ r = bc_rand_int(rng);
+ carry = (r >= (BcRand) modl);
+ }
+
+ bc_num_bigdig2num(&rand, r);
+
+ assert(BC_NUM_RDX_VALID_NP(rand));
+ assert(BC_NUM_RDX_VALID(p1));
+
+ bc_num_mul(&rand, p1, p2, 0);
+ bc_num_add(p2, t1, t2, 0);
+
+ if (BC_NUM_NONZERO(c2)) {
+
+ assert(BC_NUM_RDX_VALID_NP(vm.max));
+ assert(BC_NUM_RDX_VALID(p1));
+
+ bc_num_mul(&vm.max, p1, p2, 0);
+
+ tmp = p1;
+ p1 = p2;
+ p2 = tmp;
+
+ tmp = c1;
+ c1 = c2;
+ c2 = tmp;
+ }
+ else c1 = c2;
+
+ tmp = t1;
+ t1 = t2;
+ t2 = tmp;
+ }
+
+ bc_num_copy(b, t1);
+ bc_num_clean(b);
+
+ assert(BC_NUM_RDX_VALID(b));
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&pow);
+ bc_num_free(&pow2);
+ bc_num_free(&temp2);
+ bc_num_free(&temp1);
+ bc_num_free(&mod);
+ bc_num_free(&cp2);
+ bc_num_free(&cp);
+ BC_LONGJMP_CONT;
+}
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+size_t bc_num_addReq(const BcNum *a, const BcNum *b, size_t scale) {
+
+ size_t aint, bint, ardx, brdx;
+
+ BC_UNUSED(scale);
+
+ ardx = BC_NUM_RDX_VAL(a);
+ aint = bc_num_int(a);
+ assert(aint <= a->len && ardx <= a->len);
+
+ brdx = BC_NUM_RDX_VAL(b);
+ bint = bc_num_int(b);
+ assert(bint <= b->len && brdx <= b->len);
+
+ ardx = BC_MAX(ardx, brdx);
+ aint = BC_MAX(aint, bint);
+
+ return bc_vm_growSize(bc_vm_growSize(ardx, aint), 1);
+}
+
+size_t bc_num_mulReq(const BcNum *a, const BcNum *b, size_t scale) {
+ size_t max, rdx;
+ rdx = bc_vm_growSize(BC_NUM_RDX_VAL(a), BC_NUM_RDX_VAL(b));
+ max = BC_NUM_RDX(scale);
+ max = bc_vm_growSize(BC_MAX(max, rdx), 1);
+ rdx = bc_vm_growSize(bc_vm_growSize(bc_num_int(a), bc_num_int(b)), max);
+ return rdx;
+}
+
+size_t bc_num_divReq(const BcNum *a, const BcNum *b, size_t scale) {
+ size_t max, rdx;
+ rdx = bc_vm_growSize(BC_NUM_RDX_VAL(a), BC_NUM_RDX_VAL(b));
+ max = BC_NUM_RDX(scale);
+ max = bc_vm_growSize(BC_MAX(max, rdx), 1);
+ rdx = bc_vm_growSize(bc_num_int(a), max);
+ return rdx;
+}
+
+size_t bc_num_powReq(const BcNum *a, const BcNum *b, size_t scale) {
+ BC_UNUSED(scale);
+ return bc_vm_growSize(bc_vm_growSize(a->len, b->len), 1);
+}
+
+#if BC_ENABLE_EXTRA_MATH
+size_t bc_num_placesReq(const BcNum *a, const BcNum *b, size_t scale) {
+ BC_UNUSED(scale);
+ return a->len + b->len - BC_NUM_RDX_VAL(a) - BC_NUM_RDX_VAL(b);
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+void bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, false, bc_num_as, bc_num_addReq(a, b, scale));
+}
+
+void bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, true, bc_num_as, bc_num_addReq(a, b, scale));
+}
+
+void bc_num_mul(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, scale, bc_num_m, bc_num_mulReq(a, b, scale));
+}
+
+void bc_num_div(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, scale, bc_num_d, bc_num_divReq(a, b, scale));
+}
+
+void bc_num_mod(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, scale, bc_num_rem, bc_num_divReq(a, b, scale));
+}
+
+void bc_num_pow(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, scale, bc_num_p, bc_num_powReq(a, b, scale));
+}
+
+#if BC_ENABLE_EXTRA_MATH
+void bc_num_places(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, scale, bc_num_place, bc_num_placesReq(a, b, scale));
+}
+
+void bc_num_lshift(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, scale, bc_num_left, bc_num_placesReq(a, b, scale));
+}
+
+void bc_num_rshift(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
+ assert(BC_NUM_RDX_VALID(a));
+ assert(BC_NUM_RDX_VALID(b));
+ bc_num_binary(a, b, c, scale, bc_num_right, bc_num_placesReq(a, b, scale));
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+void bc_num_sqrt(BcNum *restrict a, BcNum *restrict b, size_t scale) {
+
+ BcNum num1, num2, half, f, fprime, *x0, *x1, *temp;
+ size_t pow, len, rdx, req, digs, digs1, digs2, resscale;
+ BcDig half_digs[1];
+
+ assert(a != NULL && b != NULL && a != b);
+
+ if (BC_ERR(BC_NUM_NEG(a))) bc_vm_err(BC_ERR_MATH_NEGATIVE);
+
+ if (a->scale > scale) scale = a->scale;
+
+ len = bc_vm_growSize(bc_num_intDigits(a), 1);
+ rdx = BC_NUM_RDX(scale);
+ req = bc_vm_growSize(BC_MAX(rdx, BC_NUM_RDX_VAL(a)), len >> 1);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(b, bc_vm_growSize(req, 1));
+
+ BC_SIG_UNLOCK;
+
+ assert(a != NULL && b != NULL && a != b);
+ assert(a->num != NULL && b->num != NULL);
+
+ if (BC_NUM_ZERO(a)) {
+ bc_num_setToZero(b, scale);
+ return;
+ }
+ if (BC_NUM_ONE(a)) {
+ bc_num_one(b);
+ bc_num_extend(b, scale);
+ return;
+ }
+
+ rdx = BC_NUM_RDX(scale);
+ rdx = BC_MAX(rdx, BC_NUM_RDX_VAL(a));
+ len = bc_vm_growSize(a->len, rdx);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&num1, len);
+ bc_num_init(&num2, len);
+ bc_num_setup(&half, half_digs, sizeof(half_digs) / sizeof(BcDig));
+
+ bc_num_one(&half);
+ half.num[0] = BC_BASE_POW / 2;
+ half.len = 1;
+ BC_NUM_RDX_SET_NP(half, 1);
+ half.scale = 1;
+
+ bc_num_init(&f, len);
+ bc_num_init(&fprime, len);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ x0 = &num1;
+ x1 = &num2;
+
+ bc_num_one(x0);
+ pow = bc_num_intDigits(a);
+
+ if (pow) {
+
+ if (pow & 1) x0->num[0] = 2;
+ else x0->num[0] = 6;
+
+ pow -= 2 - (pow & 1);
+ bc_num_shiftLeft(x0, pow / 2);
+ }
+
+ // I can set the rdx here directly because neg should be false.
+ x0->scale = x0->rdx = digs = digs1 = digs2 = 0;
+ resscale = (scale + BC_BASE_DIGS) + 2;
+
+ while (bc_num_cmp(x1, x0)) {
+
+ assert(BC_NUM_NONZERO(x0));
+
+ bc_num_div(a, x0, &f, resscale);
+ bc_num_add(x0, &f, &fprime, resscale);
+
+ assert(BC_NUM_RDX_VALID_NP(fprime));
+ assert(BC_NUM_RDX_VALID_NP(half));
+
+ bc_num_mul(&fprime, &half, x1, resscale);
+
+ temp = x0;
+ x0 = x1;
+ x1 = temp;
+ }
+
+ bc_num_copy(b, x0);
+ if (b->scale > scale) bc_num_truncate(b, b->scale - scale);
+
+ assert(!BC_NUM_NEG(b) || BC_NUM_NONZERO(b));
+ assert(BC_NUM_RDX_VALID(b));
+ assert(BC_NUM_RDX_VAL(b) <= b->len || !b->len);
+ assert(!b->len || b->num[b->len - 1] || BC_NUM_RDX_VAL(b) == b->len);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&fprime);
+ bc_num_free(&f);
+ bc_num_free(&num2);
+ bc_num_free(&num1);
+ BC_LONGJMP_CONT;
+}
+
+void bc_num_divmod(BcNum *a, BcNum *b, BcNum *c, BcNum *d, size_t scale) {
+
+ size_t ts, len;
+ BcNum *ptr_a, num2;
+ bool init = false;
+
+ ts = BC_MAX(scale + b->scale, a->scale);
+ len = bc_num_mulReq(a, b, ts);
+
+ assert(a != NULL && b != NULL && c != NULL && d != NULL);
+ assert(c != d && a != d && b != d && b != c);
+
+ if (c == a) {
+
+ memcpy(&num2, c, sizeof(BcNum));
+ ptr_a = &num2;
+
+ BC_SIG_LOCK;
+
+ bc_num_init(c, len);
+
+ init = true;
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+ }
+ else {
+ ptr_a = a;
+ bc_num_expand(c, len);
+ }
+
+ if (BC_NUM_NONZERO(a) && !BC_NUM_RDX_VAL(a) &&
+ !BC_NUM_RDX_VAL(b) && b->len == 1 && !scale)
+ {
+ BcBigDig rem;
+
+ bc_num_divArray(ptr_a, (BcBigDig) b->num[0], c, &rem);
+
+ assert(rem < BC_BASE_POW);
+
+ d->num[0] = (BcDig) rem;
+ d->len = (rem != 0);
+ }
+ else bc_num_r(ptr_a, b, c, d, scale, ts);
+
+ assert(!BC_NUM_NEG(c) || BC_NUM_NONZERO(c));
+ assert(BC_NUM_RDX_VALID(c));
+ assert(BC_NUM_RDX_VAL(c) <= c->len || !c->len);
+ assert(!c->len || c->num[c->len - 1] || BC_NUM_RDX_VAL(c) == c->len);
+ assert(!BC_NUM_NEG(d) || BC_NUM_NONZERO(d));
+ assert(BC_NUM_RDX_VALID(d));
+ assert(BC_NUM_RDX_VAL(d) <= d->len || !d->len);
+ assert(!d->len || d->num[d->len - 1] || BC_NUM_RDX_VAL(d) == d->len);
+
+err:
+ if (init) {
+ BC_SIG_MAYLOCK;
+ bc_num_free(&num2);
+ BC_LONGJMP_CONT;
+ }
+}
+
+#if DC_ENABLED
+void bc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d) {
+
+ BcNum base, exp, two, temp;
+ BcDig two_digs[2];
+
+ assert(a != NULL && b != NULL && c != NULL && d != NULL);
+ assert(a != d && b != d && c != d);
+
+ if (BC_ERR(BC_NUM_ZERO(c))) bc_vm_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
+ if (BC_ERR(BC_NUM_NEG(b))) bc_vm_err(BC_ERR_MATH_NEGATIVE);
+ if (BC_ERR(BC_NUM_RDX_VAL(a) || BC_NUM_RDX_VAL(b) || BC_NUM_RDX_VAL(c)))
+ bc_vm_err(BC_ERR_MATH_NON_INTEGER);
+
+ bc_num_expand(d, c->len);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&base, c->len);
+ bc_num_setup(&two, two_digs, sizeof(two_digs) / sizeof(BcDig));
+ bc_num_init(&temp, b->len + 1);
+ bc_num_createCopy(&exp, b);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_one(&two);
+ two.num[0] = 2;
+ bc_num_one(d);
+
+ // We already checked for 0.
+ bc_num_rem(a, c, &base, 0);
+
+ while (BC_NUM_NONZERO(&exp)) {
+
+ // Num two cannot be 0, so no errors.
+ bc_num_divmod(&exp, &two, &exp, &temp, 0);
+
+ if (BC_NUM_ONE(&temp) && !BC_NUM_NEG_NP(temp)) {
+
+ assert(BC_NUM_RDX_VALID(d));
+ assert(BC_NUM_RDX_VALID_NP(base));
+
+ bc_num_mul(d, &base, &temp, 0);
+
+ // We already checked for 0.
+ bc_num_rem(&temp, c, d, 0);
+ }
+
+ assert(BC_NUM_RDX_VALID_NP(base));
+
+ bc_num_mul(&base, &base, &temp, 0);
+
+ // We already checked for 0.
+ bc_num_rem(&temp, c, &base, 0);
+ }
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&exp);
+ bc_num_free(&temp);
+ bc_num_free(&base);
+ BC_LONGJMP_CONT;
+ assert(!BC_NUM_NEG(d) || d->len);
+ assert(BC_NUM_RDX_VALID(d));
+ assert(!d->len || d->num[d->len - 1] || BC_NUM_RDX_VAL(d) == d->len);
+}
+#endif // DC_ENABLED
+
+#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_num_printDecimal(n);
+ bc_file_putchar(&vm.fout, '\n');
+ if (emptyline) bc_file_putchar(&vm.fout, '\n');
+ vm.nchars = 0;
+}
+
+void bc_num_printDigs(const BcDig *n, size_t len, bool emptyline) {
+
+ size_t i;
+
+ 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');
+ vm.nchars = 0;
+}
+
+void bc_num_printWithDigs(const BcNum *n, const char *name, bool emptyline) {
+ bc_file_puts(&vm.fout, 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);
+}
+
+void bc_num_dump(const char *varname, const BcNum *n) {
+
+ ulong i, scale = n->scale;
+
+ bc_file_printf(&vm.ferr, "\n%s = %s", varname,
+ n->len ? (BC_NUM_NEG(n) ? "-" : "+") : "0 ");
+
+ for (i = n->len - 1; i < n->len; --i) {
+
+ if (i + 1 == BC_NUM_RDX_VAL(n)) bc_file_puts(&vm.ferr, ". ");
+
+ if (scale / BC_BASE_DIGS != BC_NUM_RDX_VAL(n) - i - 1)
+ bc_file_printf(&vm.ferr, "%lu ", (unsigned long) n->num[i]);
+ else {
+
+ int mod = scale % BC_BASE_DIGS;
+ int d = BC_BASE_DIGS - mod;
+ BcDig div;
+
+ if (mod != 0) {
+ div = n->num[i] / ((BcDig) bc_num_pow10[(ulong) d]);
+ bc_file_printf(&vm.ferr, "%lu", (unsigned long) div);
+ }
+
+ div = n->num[i] % ((BcDig) bc_num_pow10[(ulong) d]);
+ bc_file_printf(&vm.ferr, " ' %lu ", (unsigned long) div);
+ }
+ }
+
+ 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);
+}
+#endif // BC_DEBUG_CODE
diff --git a/contrib/bc/src/opt.c b/contrib/bc/src/opt.c
new file mode 100644
index 000000000000..57cee759af5e
--- /dev/null
+++ b/contrib/bc/src/opt.c
@@ -0,0 +1,252 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Adapted from https://github.com/skeeto/optparse
+ *
+ * *****************************************************************************
+ *
+ * Code for getopt_long() replacement. It turns out that getopt_long() has
+ * different behavior on different platforms.
+ *
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <status.h>
+#include <opt.h>
+#include <vm.h>
+
+static inline bool bc_opt_longoptsEnd(const BcOptLong *longopts, size_t i) {
+ return !longopts[i].name && !longopts[i].val;
+}
+
+static const char* bc_opt_longopt(const BcOptLong *longopts, int c) {
+
+ size_t i;
+
+ for (i = 0; !bc_opt_longoptsEnd(longopts, i); ++i) {
+ if (longopts[i].val == c) return longopts[i].name;
+ }
+
+ return "NULL";
+}
+
+static void bc_opt_error(BcErr err, int c, const char *str) {
+ if (err == BC_ERR_FATAL_OPTION) bc_vm_error(err, 0, str);
+ else bc_vm_error(err, 0, (int) c, str);
+}
+
+static int bc_opt_type(const BcOptLong *longopts, char c) {
+
+ size_t i;
+
+ if (c == ':') return -1;
+
+ for (i = 0; !bc_opt_longoptsEnd(longopts, i) && longopts[i].val != c; ++i);
+
+ if (bc_opt_longoptsEnd(longopts, i)) return -1;
+
+ return (int) longopts[i].type;
+}
+
+static int bc_opt_parseShort(BcOpt *o, const BcOptLong *longopts) {
+
+ int type;
+ char *next;
+ char *option = o->argv[o->optind];
+ int ret = -1;
+
+ o->optopt = 0;
+ o->optarg = NULL;
+
+ option += o->subopt + 1;
+ o->optopt = option[0];
+
+ type = bc_opt_type(longopts, option[0]);
+ next = o->argv[o->optind + 1];
+
+ switch (type) {
+
+ case -1:
+ case BC_OPT_BC_ONLY:
+ case BC_OPT_DC_ONLY:
+ {
+ if (type == -1 || (type == BC_OPT_BC_ONLY && BC_IS_DC) ||
+ (type == BC_OPT_DC_ONLY && BC_IS_BC))
+ {
+ char str[2] = {0, 0};
+
+ str[0] = option[0];
+ o->optind += 1;
+
+ bc_opt_error(BC_ERR_FATAL_OPTION, option[0], str);
+ }
+ }
+ // Fallthrough.
+ BC_FALLTHROUGH
+
+ case BC_OPT_NONE:
+ {
+ if (option[1]) o->subopt += 1;
+ else {
+ o->subopt = 0;
+ o->optind += 1;
+ }
+
+ ret = (int) option[0];
+ break;
+ }
+
+ case BC_OPT_REQUIRED:
+ {
+ o->subopt = 0;
+ o->optind += 1;
+
+ if (option[1]) o->optarg = option + 1;
+ else if (next != NULL) {
+ o->optarg = next;
+ o->optind += 1;
+ }
+ else bc_opt_error(BC_ERR_FATAL_OPTION_NO_ARG, option[0],
+ bc_opt_longopt(longopts, option[0]));
+
+
+ ret = (int) option[0];
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static bool bc_opt_longoptsMatch(const char *name, const char *option) {
+
+ const char *a = option, *n = name;
+
+ if (name == NULL) return false;
+
+ for (; *a && *n && *a != '='; ++a, ++n) {
+ if (*a != *n) return false;
+ }
+
+ return (*n == '\0' && (*a == '\0' || *a == '='));
+}
+
+static char* bc_opt_longoptsArg(char *option) {
+
+ for (; *option && *option != '='; ++option);
+
+ if (*option == '=') return option + 1;
+ else return NULL;
+}
+
+int bc_opt_parse(BcOpt *o, const BcOptLong *longopts) {
+
+ size_t i;
+ char *option;
+ bool empty;
+
+ do {
+
+ option = o->argv[o->optind];
+ if (option == NULL) return -1;
+
+ empty = !strcmp(option, "");
+ o->optind += empty;
+
+ } while (empty);
+
+ if (BC_OPT_ISDASHDASH(option)) {
+
+ // Consume "--".
+ o->optind += 1;
+ return -1;
+ }
+ else if (BC_OPT_ISSHORTOPT(option)) return bc_opt_parseShort(o, longopts);
+ else if (!BC_OPT_ISLONGOPT(option)) return -1;
+
+ o->optopt = 0;
+ o->optarg = NULL;
+
+ // Skip "--" at beginning of the option.
+ option += 2;
+ o->optind += 1;
+
+ for (i = 0; !bc_opt_longoptsEnd(longopts, i); i++) {
+
+ const char *name = longopts[i].name;
+
+ if (bc_opt_longoptsMatch(name, option)) {
+
+ char *arg;
+
+ o->optopt = longopts[i].val;
+ arg = bc_opt_longoptsArg(option);
+
+ if ((longopts[i].type == BC_OPT_BC_ONLY && BC_IS_DC) ||
+ (longopts[i].type == BC_OPT_DC_ONLY && BC_IS_BC))
+ {
+ bc_opt_error(BC_ERR_FATAL_OPTION, o->optopt, name);
+ }
+
+ if (longopts[i].type == BC_OPT_NONE && arg != NULL)
+ {
+ bc_opt_error(BC_ERR_FATAL_OPTION_ARG, o->optopt, name);
+ }
+
+ if (arg != NULL) o->optarg = arg;
+ else if (longopts[i].type == BC_OPT_REQUIRED) {
+
+ o->optarg = o->argv[o->optind];
+
+ if (o->optarg != NULL) o->optind += 1;
+ else bc_opt_error(BC_ERR_FATAL_OPTION_NO_ARG,
+ o->optopt, name);
+ }
+
+ return o->optopt;
+ }
+ }
+
+ bc_opt_error(BC_ERR_FATAL_OPTION, 0, option);
+
+ return -1;
+}
+
+void bc_opt_init(BcOpt *o, char *argv[]) {
+ o->argv = argv;
+ o->optind = 1;
+ o->subopt = 0;
+ o->optarg = NULL;
+}
diff --git a/contrib/bc/src/parse.c b/contrib/bc/src/parse.c
new file mode 100644
index 000000000000..39b79efdd02f
--- /dev/null
+++ b/contrib/bc/src/parse.c
@@ -0,0 +1,218 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code common to the parsers.
+ *
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <limits.h>
+
+#include <parse.h>
+#include <program.h>
+#include <vm.h>
+
+void bc_parse_updateFunc(BcParse *p, size_t fidx) {
+ p->fidx = fidx;
+ p->func = bc_vec_item(&p->prog->fns, fidx);
+}
+
+inline void bc_parse_pushName(const BcParse *p, char *name, bool var) {
+ bc_parse_pushIndex(p, bc_program_search(p->prog, name, var));
+}
+
+static void bc_parse_update(BcParse *p, uchar inst, size_t idx) {
+ bc_parse_updateFunc(p, p->fidx);
+ bc_parse_push(p, inst);
+ bc_parse_pushIndex(p, idx);
+}
+
+void bc_parse_addString(BcParse *p) {
+
+ BcVec *strs = BC_IS_BC ? &p->func->strs : p->prog->strs;
+ size_t idx;
+
+ BC_SIG_LOCK;
+
+ if (BC_IS_BC) {
+ const char *str = bc_vm_strdup(p->l.str.v);
+ idx = strs->len;
+ bc_vec_push(strs, &str);
+ }
+#if DC_ENABLED
+ else idx = bc_program_insertFunc(p->prog, p->l.str.v) - BC_PROG_REQ_FUNCS;
+#endif // DC_ENABLED
+
+ bc_parse_update(p, BC_INST_STR, idx);
+
+ BC_SIG_UNLOCK;
+}
+
+static void bc_parse_addNum(BcParse *p, const char *string) {
+
+ BcVec *consts = &p->func->consts;
+ size_t idx;
+ BcConst c;
+
+ if (bc_parse_zero[0] == string[0] && bc_parse_zero[1] == string[1]) {
+ bc_parse_push(p, BC_INST_ZERO);
+ return;
+ }
+ if (bc_parse_one[0] == string[0] && bc_parse_one[1] == string[1]) {
+ bc_parse_push(p, BC_INST_ONE);
+ return;
+ }
+
+ idx = consts->len;
+
+ BC_SIG_LOCK;
+
+ c.val = bc_vm_strdup(string);
+ c.base = BC_NUM_BIGDIG_MAX;
+
+ bc_num_clear(&c.num);
+ bc_vec_push(consts, &c);
+
+ bc_parse_update(p, BC_INST_NUM, idx);
+
+ BC_SIG_UNLOCK;
+}
+
+void bc_parse_number(BcParse *p) {
+
+#if BC_ENABLE_EXTRA_MATH
+ char *exp = strchr(p->l.str.v, 'e');
+ size_t idx = SIZE_MAX;
+
+ if (exp != NULL) {
+ idx = ((size_t) (exp - p->l.str.v));
+ *exp = 0;
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+
+ bc_parse_addNum(p, p->l.str.v);
+
+#if BC_ENABLE_EXTRA_MATH
+ if (exp != NULL) {
+
+ bool neg;
+
+ neg = (*((char*) bc_vec_item(&p->l.str, idx + 1)) == BC_LEX_NEG_CHAR);
+
+ bc_parse_addNum(p, bc_vec_item(&p->l.str, idx + 1 + neg));
+ bc_parse_push(p, BC_INST_LSHIFT + neg);
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+}
+
+void bc_parse_text(BcParse *p, const char *text) {
+ // Make sure the pointer isn't invalidated.
+ p->func = bc_vec_item(&p->prog->fns, p->fidx);
+ bc_lex_text(&p->l, text);
+}
+
+void bc_parse_reset(BcParse *p) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ if (p->fidx != BC_PROG_MAIN) {
+ bc_func_reset(p->func);
+ bc_parse_updateFunc(p, BC_PROG_MAIN);
+ }
+
+ p->l.i = p->l.len;
+ p->l.t = BC_LEX_EOF;
+ p->auto_part = false;
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+ bc_vec_npop(&p->flags, p->flags.len - 1);
+ bc_vec_npop(&p->exits, p->exits.len);
+ bc_vec_npop(&p->conds, p->conds.len);
+ bc_vec_npop(&p->ops, p->ops.len);
+ }
+#endif // BC_ENABLED
+
+ bc_program_reset(p->prog);
+
+ if (BC_ERR(vm.status)) BC_VM_JMP;
+}
+
+void bc_parse_free(BcParse *p) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL);
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+ bc_vec_free(&p->flags);
+ bc_vec_free(&p->exits);
+ bc_vec_free(&p->conds);
+ bc_vec_free(&p->ops);
+ bc_vec_free(&p->buf);
+ }
+#endif // BC_ENABLED
+
+ bc_lex_free(&p->l);
+}
+
+void bc_parse_init(BcParse *p, BcProgram *prog, size_t func) {
+
+#if BC_ENABLED
+ uint16_t flag = 0;
+#endif // BC_ENABLED
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL && prog != NULL);
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+ bc_vec_init(&p->flags, sizeof(uint16_t), NULL);
+ bc_vec_push(&p->flags, &flag);
+ bc_vec_init(&p->exits, sizeof(BcInstPtr), NULL);
+ bc_vec_init(&p->conds, sizeof(size_t), NULL);
+ bc_vec_init(&p->ops, sizeof(BcLexType), NULL);
+ bc_vec_init(&p->buf, sizeof(char), NULL);
+ }
+#endif // BC_ENABLED
+
+ bc_lex_init(&p->l);
+
+ p->prog = prog;
+ p->auto_part = false;
+ bc_parse_updateFunc(p, func);
+}
diff --git a/contrib/bc/src/program.c b/contrib/bc/src/program.c
new file mode 100644
index 000000000000..f0a67ee194c1
--- /dev/null
+++ b/contrib/bc/src/program.c
@@ -0,0 +1,2336 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code to execute bc programs.
+ *
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <setjmp.h>
+
+#include <signal.h>
+
+#include <time.h>
+
+#include <read.h>
+#include <parse.h>
+#include <program.h>
+#include <vm.h>
+
+static void bc_program_addFunc(BcProgram *p, BcFunc *f, BcId *id_ptr);
+
+static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) {
+ p->consts = &f->consts;
+ if (BC_IS_BC) p->strs = &f->strs;
+}
+
+static inline void bc_program_type_num(BcResult *r, BcNum *n) {
+
+#if BC_ENABLED
+ assert(r->t != BC_RESULT_VOID);
+#endif // BC_ENABLED
+
+ if (BC_ERR(!BC_PROG_NUM(r, n))) bc_vm_err(BC_ERR_EXEC_TYPE);
+}
+
+#if BC_ENABLED
+static void bc_program_type_match(BcResult *r, BcType t) {
+
+#if DC_ENABLED
+ assert(BC_IS_DC || BC_NO_ERR(r->t != BC_RESULT_STR));
+#endif // DC_ENABLED
+
+ if (BC_ERR((r->t != BC_RESULT_ARRAY) != (!t)))
+ bc_vm_err(BC_ERR_EXEC_TYPE);
+}
+#endif // BC_ENABLED
+
+static size_t bc_program_index(const char *restrict code, size_t *restrict bgn)
+{
+ uchar amt = (uchar) code[(*bgn)++], i = 0;
+ size_t res = 0;
+
+ for (; i < amt; ++i, ++(*bgn)) {
+ size_t temp = ((size_t) ((int) (uchar) code[*bgn]) & UCHAR_MAX);
+ res |= (temp << (i * CHAR_BIT));
+ }
+
+ return res;
+}
+
+#if BC_ENABLED
+static void bc_program_prepGlobals(BcProgram *p) {
+
+ size_t i;
+
+ for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i)
+ bc_vec_push(p->globals_v + i, p->globals + i);
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ bc_rand_push(&p->rng);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+}
+
+static void bc_program_popGlobals(BcProgram *p, bool reset) {
+
+ size_t i;
+
+ for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) {
+ BcVec *v = p->globals_v + i;
+ bc_vec_npop(v, reset ? v->len - 1 : 1);
+ p->globals[i] = BC_PROG_GLOBAL(v);
+ }
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ bc_rand_pop(&p->rng, reset);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+}
+#endif // BC_ENABLED
+
+static void bc_program_pushBigdig(BcProgram *p, BcBigDig dig, BcResultType type)
+{
+ BcResult res;
+
+ res.t = type;
+
+ BC_SIG_LOCK;
+
+ bc_num_createFromBigdig(&res.d.n, dig);
+ bc_vec_push(&p->results, &res);
+
+ BC_SIG_UNLOCK;
+}
+
+#if BC_ENABLED
+static BcVec* bc_program_dereference(const BcProgram *p, BcVec *vec) {
+
+ BcVec *v;
+ size_t vidx, nidx, i = 0;
+
+ assert(vec->size == sizeof(uchar));
+
+ vidx = bc_program_index(vec->v, &i);
+ nidx = bc_program_index(vec->v, &i);
+
+ v = bc_vec_item(bc_vec_item(&p->arrs, vidx), nidx);
+
+ assert(v->size != sizeof(uchar));
+
+ return v;
+}
+#endif // BC_ENABLED
+
+size_t bc_program_search(BcProgram *p, const char *id, bool var) {
+
+ BcVec *v, *map;
+ size_t i;
+ BcResultData data;
+
+ v = var ? &p->vars : &p->arrs;
+ map = var ? &p->var_map : &p->arr_map;
+
+ BC_SIG_LOCK;
+
+ if (bc_map_insert(map, id, v->len, &i)) {
+ bc_array_init(&data.v, var);
+ bc_vec_push(v, &data.v);
+ }
+
+ BC_SIG_UNLOCK;
+
+ return ((BcId*) bc_vec_item(map, i))->idx;
+}
+
+static inline BcVec* bc_program_vec(const BcProgram *p, size_t idx, BcType type)
+{
+ const BcVec *v = (type == BC_TYPE_VAR) ? &p->vars : &p->arrs;
+ return bc_vec_item(v, idx);
+}
+
+static BcNum* bc_program_num(BcProgram *p, BcResult *r) {
+
+ BcNum *n;
+
+ switch (r->t) {
+
+ case BC_RESULT_STR:
+ case BC_RESULT_TEMP:
+ case BC_RESULT_IBASE:
+ case BC_RESULT_SCALE:
+ case BC_RESULT_OBASE:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_RESULT_SEED:
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ n = &r->d.n;
+ break;
+ }
+
+ case BC_RESULT_VAR:
+#if BC_ENABLED
+ case BC_RESULT_ARRAY:
+#endif // BC_ENABLED
+ case BC_RESULT_ARRAY_ELEM:
+ {
+ BcVec *v;
+ BcType type = (r->t == BC_RESULT_VAR) ? BC_TYPE_VAR : BC_TYPE_ARRAY;
+
+ v = bc_program_vec(p, r->d.loc.loc, type);
+
+ if (r->t == BC_RESULT_ARRAY_ELEM) {
+
+ size_t idx = r->d.loc.idx;
+
+ v = bc_vec_top(v);
+
+#if BC_ENABLED
+ if (v->size == sizeof(uchar)) v = bc_program_dereference(p, v);
+#endif // BC_ENABLED
+
+ assert(v->size == sizeof(BcNum));
+
+ if (v->len <= idx) {
+ BC_SIG_LOCK;
+ bc_array_expand(v, bc_vm_growSize(idx, 1));
+ BC_SIG_UNLOCK;
+ }
+
+ n = bc_vec_item(v, idx);
+ }
+ else n = bc_vec_top(v);
+
+ break;
+ }
+
+ case BC_RESULT_ZERO:
+ {
+ n = &p->zero;
+ break;
+ }
+
+ case BC_RESULT_ONE:
+ {
+ n = &p->one;
+ break;
+ }
+
+#if BC_ENABLED
+ case BC_RESULT_VOID:
+#ifndef NDEBUG
+ {
+ abort();
+ }
+#endif // NDEBUG
+ // Fallthrough
+ case BC_RESULT_LAST:
+ {
+ n = &p->last;
+ break;
+ }
+#endif // BC_ENABLED
+ }
+
+ return n;
+}
+
+static void bc_program_operand(BcProgram *p, BcResult **r,
+ BcNum **n, size_t idx)
+{
+ *r = bc_vec_item_rev(&p->results, idx);
+
+#if BC_ENABLED
+ if (BC_ERR((*r)->t == BC_RESULT_VOID)) bc_vm_err(BC_ERR_EXEC_VOID_VAL);
+#endif // BC_ENABLED
+
+ *n = bc_program_num(p, *r);
+}
+
+static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln,
+ BcResult **r, BcNum **rn, size_t idx)
+{
+ BcResultType lt;
+
+ assert(p != NULL && l != NULL && ln != NULL && r != NULL && rn != NULL);
+
+#ifndef BC_PROG_NO_STACK_CHECK
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 2)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+ }
+#endif // BC_PROG_NO_STACK_CHECK
+
+ assert(BC_PROG_STACK(&p->results, idx + 2));
+
+ bc_program_operand(p, l, ln, idx + 1);
+ bc_program_operand(p, r, rn, idx);
+
+ lt = (*l)->t;
+
+#if BC_ENABLED
+ assert(lt != BC_RESULT_VOID && (*r)->t != BC_RESULT_VOID);
+#endif // BC_ENABLED
+
+ // We run this again under these conditions in case any vector has been
+ // reallocated out from under the BcNums or arrays we had.
+ if (lt == (*r)->t && (lt == BC_RESULT_VAR || lt == BC_RESULT_ARRAY_ELEM))
+ *ln = bc_program_num(p, *l);
+
+ if (BC_ERR(lt == BC_RESULT_STR)) bc_vm_err(BC_ERR_EXEC_TYPE);
+}
+
+static void bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln,
+ BcResult **r, BcNum **rn, size_t idx)
+{
+ bc_program_binPrep(p, l, ln, r, rn, idx);
+ bc_program_type_num(*l, *ln);
+ bc_program_type_num(*r, *rn);
+}
+
+static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln,
+ BcResult **r, BcNum **rn)
+{
+ BcResultType lt, min;
+
+ min = BC_RESULT_TEMP - ((unsigned int) (BC_IS_BC));
+
+ bc_program_binPrep(p, l, ln, r, rn, 0);
+
+ lt = (*l)->t;
+
+ if (BC_ERR(lt >= min && lt <= BC_RESULT_ONE))
+ bc_vm_err(BC_ERR_EXEC_TYPE);
+
+#if DC_ENABLED
+ if(BC_IS_DC) {
+
+ bool good = (((*r)->t == BC_RESULT_STR || BC_PROG_STR(*rn)) &&
+ lt <= BC_RESULT_ARRAY_ELEM);
+
+ if (!good) bc_program_type_num(*r, *rn);
+ }
+#else
+ assert((*r)->t != BC_RESULT_STR);
+#endif // DC_ENABLED
+}
+
+static void bc_program_prep(BcProgram *p, BcResult **r, BcNum **n, size_t idx) {
+
+ assert(p != NULL && r != NULL && n != NULL);
+
+#ifndef BC_PROG_NO_STACK_CHECK
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+ }
+#endif // BC_PROG_NO_STACK_CHECK
+
+ assert(BC_PROG_STACK(&p->results, idx + 1));
+
+ bc_program_operand(p, r, n, idx);
+
+#if DC_ENABLED
+ assert((*r)->t != BC_RESULT_VAR || !BC_PROG_STR(*n));
+#endif // DC_ENABLED
+
+ bc_program_type_num(*r, *n);
+}
+
+static BcResult* bc_program_prepResult(BcProgram *p) {
+
+ BcResult res;
+
+ bc_result_clear(&res);
+ bc_vec_push(&p->results, &res);
+
+ return bc_vec_top(&p->results);
+}
+
+static void bc_program_const(BcProgram *p, const char *code, size_t *bgn) {
+
+ BcResult *r = bc_program_prepResult(p);
+ BcConst *c = bc_vec_item(p->consts, bc_program_index(code, bgn));
+ BcBigDig base = BC_PROG_IBASE(p);
+
+ if (c->base != base) {
+
+ if (c->num.num == NULL) {
+ BC_SIG_LOCK;
+ bc_num_init(&c->num, BC_NUM_RDX(strlen(c->val)));
+ BC_SIG_UNLOCK;
+ }
+
+ // bc_num_parse() should only do operations that cannot fail.
+ bc_num_parse(&c->num, c->val, base);
+
+ c->base = base;
+ }
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&r->d.n, &c->num);
+
+ BC_SIG_UNLOCK;
+}
+
+static void bc_program_op(BcProgram *p, uchar inst) {
+
+ BcResult *opd1, *opd2, *res;
+ BcNum *n1, *n2;
+ size_t idx = inst - BC_INST_POWER;
+
+ res = bc_program_prepResult(p);
+
+ bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 1);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, bc_program_opReqs[idx](n1, n2, BC_PROG_SCALE(p)));
+
+ BC_SIG_UNLOCK;
+
+ assert(BC_NUM_RDX_VALID(n1));
+ assert(BC_NUM_RDX_VALID(n2));
+
+ bc_program_ops[idx](n1, n2, &res->d.n, BC_PROG_SCALE(p));
+
+ bc_program_retire(p, 1, 2);
+}
+
+static void bc_program_read(BcProgram *p) {
+
+ BcStatus s;
+ BcParse parse;
+ BcVec buf;
+ BcInstPtr ip;
+ size_t i;
+ const char* file;
+ BcFunc *f = bc_vec_item(&p->fns, BC_PROG_READ);
+
+ for (i = 0; i < p->stack.len; ++i) {
+ BcInstPtr *ip_ptr = bc_vec_item(&p->stack, i);
+ if (ip_ptr->func == BC_PROG_READ)
+ bc_vm_err(BC_ERR_EXEC_REC_READ);
+ }
+
+ BC_SIG_LOCK;
+
+ file = vm.file;
+ bc_parse_init(&parse, p, BC_PROG_READ);
+ bc_vec_init(&buf, sizeof(char), NULL);
+
+ BC_SETJMP_LOCKED(exec_err);
+
+ BC_SIG_UNLOCK;
+
+ bc_lex_file(&parse.l, bc_program_stdin_name);
+ bc_vec_npop(&f->code, f->code.len);
+
+ s = bc_read_line(&buf, BC_IS_BC ? "read> " : "?> ");
+ if (s == BC_STATUS_EOF) bc_vm_err(BC_ERR_EXEC_READ_EXPR);
+
+ bc_parse_text(&parse, buf.v);
+ vm.expr(&parse, BC_PARSE_NOREAD | BC_PARSE_NEEDVAL);
+
+ if (BC_ERR(parse.l.t != BC_LEX_NLINE && parse.l.t != BC_LEX_EOF))
+ bc_vm_err(BC_ERR_EXEC_READ_EXPR);
+
+#if BC_ENABLED
+ if (BC_G) bc_program_prepGlobals(p);
+#endif // BC_ENABLED
+
+ ip.func = BC_PROG_READ;
+ ip.idx = 0;
+ ip.len = p->results.len;
+
+ // Update this pointer, just in case.
+ f = bc_vec_item(&p->fns, BC_PROG_READ);
+
+ bc_vec_pushByte(&f->code, vm.read_ret);
+ bc_vec_push(&p->stack, &ip);
+
+#if DC_ENABLED
+ if (BC_IS_DC) {
+ size_t temp = 0;
+ bc_vec_push(&p->tail_calls, &temp);
+ }
+#endif // DC_ENABLED
+
+exec_err:
+ BC_SIG_MAYLOCK;
+ bc_parse_free(&parse);
+ bc_vec_free(&buf);
+ vm.file = file;
+ BC_LONGJMP_CONT;
+}
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+static void bc_program_rand(BcProgram *p) {
+ BcRand rand = bc_rand_int(&p->rng);
+ bc_program_pushBigdig(p, (BcBigDig) rand, BC_RESULT_TEMP);
+#ifndef NDEBUG
+ {
+ BcResult *r = bc_vec_top(&p->results);
+ assert(BC_NUM_RDX_VALID_NP(r->d.n));
+ }
+#endif // NDEBUG
+}
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+static void bc_program_printChars(const char *str) {
+
+ const char *nl;
+ size_t len = vm.nchars + strlen(str);
+
+ bc_file_puts(&vm.fout, str);
+ nl = strrchr(str, '\n');
+
+ if (nl != NULL) len = strlen(nl + 1);
+
+ vm.nchars = len > UINT16_MAX ? UINT16_MAX : (uint16_t) len;
+}
+
+static void bc_program_printString(const char *restrict str) {
+
+ size_t i, len = strlen(str);
+
+#if DC_ENABLED
+ if (!len && BC_IS_DC) {
+ bc_vm_putchar('\0');
+ return;
+ }
+#endif // DC_ENABLED
+
+ for (i = 0; i < len; ++i) {
+
+ int c = str[i];
+
+ if (c == '\\' && i != len - 1) {
+
+ const char *ptr;
+
+ c = str[++i];
+ ptr = strchr(bc_program_esc_chars, c);
+
+ if (ptr != NULL) {
+ if (c == 'n') vm.nchars = UINT16_MAX;
+ c = bc_program_esc_seqs[(size_t) (ptr - bc_program_esc_chars)];
+ }
+ else {
+ // Just print the backslash. The following
+ // character will be printed later.
+ bc_vm_putchar('\\');
+ }
+ }
+
+ bc_vm_putchar(c);
+ }
+}
+
+static void bc_program_print(BcProgram *p, uchar inst, size_t idx) {
+
+ BcResult *r;
+ char *str;
+ BcNum *n;
+ bool pop = (inst != BC_INST_PRINT);
+
+ assert(p != NULL);
+
+#ifndef BC_PROG_NO_STACK_CHECK
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+ }
+#endif // BC_PROG_NO_STACK_CHECK
+
+ assert(BC_PROG_STACK(&p->results, idx + 1));
+
+ r = bc_vec_item_rev(&p->results, idx);
+
+#if BC_ENABLED
+ if (r->t == BC_RESULT_VOID) {
+ if (BC_ERR(pop)) bc_vm_err(BC_ERR_EXEC_VOID_VAL);
+ bc_vec_pop(&p->results);
+ return;
+ }
+#endif // BC_ENABLED
+
+ n = bc_program_num(p, r);
+
+ if (BC_PROG_NUM(r, n)) {
+ assert(inst != BC_INST_PRINT_STR);
+ bc_num_print(n, BC_PROG_OBASE(p), !pop);
+#if BC_ENABLED
+ if (BC_IS_BC) bc_num_copy(&p->last, n);
+#endif // BC_ENABLED
+ }
+ else {
+
+ size_t i = (r->t == BC_RESULT_STR) ? r->d.loc.loc : n->scale;
+
+ bc_file_flush(&vm.fout);
+ 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 (BC_IS_BC || pop) bc_vec_pop(&p->results);
+}
+
+void bc_program_negate(BcResult *r, BcNum *n) {
+ bc_num_copy(&r->d.n, n);
+ if (BC_NUM_NONZERO(&r->d.n)) BC_NUM_NEG_TGL_NP(r->d.n);
+}
+
+void bc_program_not(BcResult *r, BcNum *n) {
+ if (!bc_num_cmpZero(n)) bc_num_one(&r->d.n);
+}
+
+#if BC_ENABLE_EXTRA_MATH
+void bc_program_trunc(BcResult *r, BcNum *n) {
+ bc_num_copy(&r->d.n, n);
+ bc_num_truncate(&r->d.n, n->scale);
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+static void bc_program_unary(BcProgram *p, uchar inst) {
+
+ BcResult *res, *ptr;
+ BcNum *num;
+
+ res = bc_program_prepResult(p);
+
+ bc_program_prep(p, &ptr, &num, 1);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, num->len);
+
+ BC_SIG_UNLOCK;
+
+ bc_program_unarys[inst - BC_INST_NEG](res, num);
+ bc_program_retire(p, 1, 1);
+}
+
+static void bc_program_logical(BcProgram *p, uchar inst) {
+
+ BcResult *opd1, *opd2, *res;
+ BcNum *n1, *n2;
+ bool cond = 0;
+ ssize_t cmp;
+
+ res = bc_program_prepResult(p);
+
+ bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 1);
+
+ if (inst == BC_INST_BOOL_AND)
+ cond = (bc_num_cmpZero(n1) && bc_num_cmpZero(n2));
+ else if (inst == BC_INST_BOOL_OR)
+ cond = (bc_num_cmpZero(n1) || bc_num_cmpZero(n2));
+ else {
+
+ cmp = bc_num_cmp(n1, n2);
+
+ switch (inst) {
+
+ case BC_INST_REL_EQ:
+ {
+ cond = (cmp == 0);
+ break;
+ }
+
+ case BC_INST_REL_LE:
+ {
+ cond = (cmp <= 0);
+ break;
+ }
+
+ case BC_INST_REL_GE:
+ {
+ cond = (cmp >= 0);
+ break;
+ }
+
+ case BC_INST_REL_NE:
+ {
+ cond = (cmp != 0);
+ break;
+ }
+
+ case BC_INST_REL_LT:
+ {
+ cond = (cmp < 0);
+ break;
+ }
+
+ case BC_INST_REL_GT:
+ {
+ cond = (cmp > 0);
+ break;
+ }
+#ifndef NDEBUG
+ default:
+ {
+ abort();
+ }
+#endif // NDEBUG
+ }
+ }
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ if (cond) bc_num_one(&res->d.n);
+
+ bc_program_retire(p, 1, 2);
+}
+
+#if DC_ENABLED
+static void bc_program_assignStr(BcProgram *p, BcResult *r,
+ BcVec *v, bool push)
+{
+ BcNum n2;
+
+ bc_num_clear(&n2);
+ n2.scale = r->d.loc.loc;
+
+ assert(BC_PROG_STACK(&p->results, 1 + !push));
+
+ if (!push) bc_vec_pop(v);
+
+ bc_vec_npop(&p->results, 1 + !push);
+ bc_vec_push(v, &n2);
+}
+#endif // DC_ENABLED
+
+static void bc_program_copyToVar(BcProgram *p, size_t idx,
+ BcType t, bool last)
+{
+ BcResult *ptr = NULL, r;
+ BcVec *vec;
+ BcNum *n = NULL;
+ bool var = (t == BC_TYPE_VAR);
+
+#if DC_ENABLED
+ if (BC_IS_DC) {
+
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ bc_program_operand(p, &ptr, &n, 0);
+ }
+#endif
+
+#if BC_ENABLED
+ if (BC_IS_BC)
+ {
+ ptr = bc_vec_top(&p->results);
+
+ bc_program_type_match(ptr, t);
+
+ if (last) n = bc_program_num(p, ptr);
+ else if (var)
+ n = bc_vec_item_rev(bc_program_vec(p, ptr->d.loc.loc, t), 1);
+ }
+#endif // BC_ENABLED
+
+ vec = bc_program_vec(p, idx, t);
+
+#if DC_ENABLED
+ if (BC_IS_DC && (ptr->t == BC_RESULT_STR || BC_PROG_STR(n))) {
+ if (BC_ERR(!var)) bc_vm_err(BC_ERR_EXEC_TYPE);
+ bc_program_assignStr(p, ptr, vec, true);
+ return;
+ }
+#endif // DC_ENABLED
+
+ BC_SIG_LOCK;
+
+ if (var) bc_num_createCopy(&r.d.n, n);
+ else {
+
+ BcVec *v = (BcVec*) n, *rv = &r.d.v;
+#if BC_ENABLED
+ BcVec *parent;
+ bool ref, ref_size;
+
+ parent = bc_program_vec(p, ptr->d.loc.loc, t);
+ assert(parent != NULL);
+
+ if (!last) v = bc_vec_item_rev(parent, !last);
+ assert(v != NULL);
+
+ ref = (v->size == sizeof(BcNum) && t == BC_TYPE_REF);
+ ref_size = (v->size == sizeof(uchar));
+
+ if (ref || (ref_size && t == BC_TYPE_REF)) {
+
+ bc_vec_init(rv, sizeof(uchar), NULL);
+
+ if (ref) {
+
+ assert(parent->len >= (size_t) (!last + 1));
+
+ // Make sure the pointer was not invalidated.
+ vec = bc_program_vec(p, idx, t);
+
+ bc_vec_pushIndex(rv, ptr->d.loc.loc);
+ bc_vec_pushIndex(rv, parent->len - !last - 1);
+ }
+ // If we get here, we are copying a ref to a ref.
+ else bc_vec_npush(rv, v->len * sizeof(uchar), v->v);
+
+ // We need to return early.
+ bc_vec_push(vec, &r.d);
+ bc_vec_pop(&p->results);
+
+ BC_SIG_UNLOCK;
+ return;
+ }
+ else if (ref_size && t != BC_TYPE_REF) v = bc_program_dereference(p, v);
+#endif // BC_ENABLED
+
+ bc_array_init(rv, true);
+ bc_array_copy(rv, v);
+ }
+
+ bc_vec_push(vec, &r.d);
+ bc_vec_pop(&p->results);
+
+ BC_SIG_UNLOCK;
+}
+
+static void bc_program_assign(BcProgram *p, uchar inst) {
+
+ BcResult *left, *right, res;
+ BcNum *l, *r;
+ bool ob, sc, use_val = BC_INST_USE_VAL(inst);
+
+ bc_program_assignPrep(p, &left, &l, &right, &r);
+
+#if DC_ENABLED
+ assert(left->t != BC_RESULT_STR);
+
+ if (right->t == BC_RESULT_STR || BC_PROG_STR(r)) {
+
+ size_t idx = right->t == BC_RESULT_STR ? right->d.loc.loc : r->scale;
+
+ if (left->t == BC_RESULT_ARRAY_ELEM) {
+ BC_SIG_LOCK;
+ bc_num_free(l);
+ bc_num_clear(l);
+ l->scale = idx;
+ bc_vec_npop(&p->results, 2);
+ BC_SIG_UNLOCK;
+ }
+ else {
+ BcVec *v = bc_program_vec(p, left->d.loc.loc, BC_TYPE_VAR);
+ bc_program_assignStr(p, right, v, false);
+ }
+
+ return;
+ }
+#endif // DC_ENABLED
+
+ if (BC_INST_IS_ASSIGN(inst)) bc_num_copy(l, r);
+#if BC_ENABLED
+ else {
+
+ BcBigDig scale = BC_PROG_SCALE(p);
+
+ if (!use_val)
+ inst -= (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER);
+
+ assert(BC_NUM_RDX_VALID(l));
+ assert(BC_NUM_RDX_VALID(r));
+
+ bc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, scale);
+ }
+#endif // BC_ENABLED
+
+ ob = (left->t == BC_RESULT_OBASE);
+ sc = (left->t == BC_RESULT_SCALE);
+
+ if (ob || sc || left->t == BC_RESULT_IBASE) {
+
+ BcVec *v;
+ BcBigDig *ptr, *ptr_t, val, max, min;
+ BcErr e;
+
+ bc_num_bigdig(l, &val);
+ e = left->t - BC_RESULT_IBASE + BC_ERR_EXEC_IBASE;
+
+ if (sc) {
+ min = 0;
+ max = vm.maxes[BC_PROG_GLOBALS_SCALE];
+ v = p->globals_v + BC_PROG_GLOBALS_SCALE;
+ ptr_t = p->globals + BC_PROG_GLOBALS_SCALE;
+ }
+ else {
+ min = BC_NUM_MIN_BASE;
+ if (BC_ENABLE_EXTRA_MATH && ob && (BC_IS_DC || !BC_IS_POSIX))
+ min = 0;
+ max = vm.maxes[ob + BC_PROG_GLOBALS_IBASE];
+ v = p->globals_v + BC_PROG_GLOBALS_IBASE + ob;
+ ptr_t = p->globals + BC_PROG_GLOBALS_IBASE + ob;
+ }
+
+ if (BC_ERR(val > max || val < min)) bc_vm_verr(e, min, max);
+
+ ptr = bc_vec_top(v);
+ *ptr = val;
+ *ptr_t = val;
+ }
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ else if (left->t == BC_RESULT_SEED) bc_num_rng(l, &p->rng);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+ BC_SIG_LOCK;
+
+ if (use_val) {
+ bc_num_createCopy(&res.d.n, l);
+ res.t = BC_RESULT_TEMP;
+ bc_vec_npop(&p->results, 2);
+ bc_vec_push(&p->results, &res);
+ }
+ else bc_vec_npop(&p->results, 2);
+
+ BC_SIG_UNLOCK;
+}
+
+static void bc_program_pushVar(BcProgram *p, const char *restrict code,
+ size_t *restrict bgn, bool pop, bool copy)
+{
+ BcResult r;
+ size_t idx = bc_program_index(code, bgn);
+
+ r.t = BC_RESULT_VAR;
+ r.d.loc.loc = idx;
+
+#if DC_ENABLED
+ if (BC_IS_DC && (pop || copy)) {
+
+ BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR);
+ BcNum *num = bc_vec_top(v);
+
+ if (BC_ERR(!BC_PROG_STACK(v, 2 - copy))) bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(v, 2 - copy));
+
+ if (!BC_PROG_STR(num)) {
+
+ BC_SIG_LOCK;
+
+ r.t = BC_RESULT_TEMP;
+ bc_num_createCopy(&r.d.n, num);
+
+ if (!copy) bc_vec_pop(v);
+
+ bc_vec_push(&p->results, &r);
+
+ BC_SIG_UNLOCK;
+
+ return;
+ }
+ else {
+ r.d.loc.loc = num->scale;
+ r.t = BC_RESULT_STR;
+ }
+
+ if (!copy) bc_vec_pop(v);
+ }
+#endif // DC_ENABLED
+
+ bc_vec_push(&p->results, &r);
+}
+
+static void bc_program_pushArray(BcProgram *p, const char *restrict code,
+ size_t *restrict bgn, uchar inst)
+{
+ BcResult r, *operand;
+ BcNum *num;
+ BcBigDig temp;
+
+ r.d.loc.loc = bc_program_index(code, bgn);
+
+#if BC_ENABLED
+ if (inst == BC_INST_ARRAY) {
+ r.t = BC_RESULT_ARRAY;
+ bc_vec_push(&p->results, &r);
+ return;
+ }
+#endif // BC_ENABLED
+
+ bc_program_prep(p, &operand, &num, 0);
+ bc_num_bigdig(num, &temp);
+
+ r.t = BC_RESULT_ARRAY_ELEM;
+ r.d.loc.idx = (size_t) temp;
+
+ BC_SIG_LOCK;
+
+ bc_vec_pop(&p->results);
+ bc_vec_push(&p->results, &r);
+
+ BC_SIG_UNLOCK;
+}
+
+#if BC_ENABLED
+static void bc_program_incdec(BcProgram *p, uchar inst) {
+
+ BcResult *ptr, res, copy;
+ BcNum *num;
+ uchar inst2;
+
+ bc_program_prep(p, &ptr, &num, 0);
+
+ BC_SIG_LOCK;
+
+ copy.t = BC_RESULT_TEMP;
+ bc_num_createCopy(&copy.d.n, num);
+
+ BC_SETJMP_LOCKED(exit);
+
+ BC_SIG_UNLOCK;
+
+ res.t = BC_RESULT_ONE;
+ inst2 = BC_INST_ASSIGN_PLUS + (inst & 0x01);
+
+ bc_vec_push(&p->results, &res);
+ bc_program_assign(p, inst2);
+
+ BC_SIG_LOCK;
+
+ bc_vec_pop(&p->results);
+ bc_vec_push(&p->results, &copy);
+
+ BC_UNSETJMP;
+
+ BC_SIG_UNLOCK;
+
+ return;
+
+exit:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&copy.d.n);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_program_call(BcProgram *p, const char *restrict code,
+ size_t *restrict idx)
+{
+ BcInstPtr ip;
+ size_t i, nparams = bc_program_index(code, idx);
+ BcFunc *f;
+ BcVec *v;
+ BcLoc *a;
+ BcResultData param;
+ BcResult *arg;
+
+ ip.idx = 0;
+ ip.func = bc_program_index(code, idx);
+ f = bc_vec_item(&p->fns, ip.func);
+
+ if (BC_ERR(!f->code.len)) bc_vm_verr(BC_ERR_EXEC_UNDEF_FUNC, f->name);
+ if (BC_ERR(nparams != f->nparams))
+ bc_vm_verr(BC_ERR_EXEC_PARAMS, f->nparams, nparams);
+ ip.len = p->results.len - nparams;
+
+ assert(BC_PROG_STACK(&p->results, nparams));
+
+ if (BC_G) bc_program_prepGlobals(p);
+
+ for (i = 0; i < nparams; ++i) {
+
+ size_t j;
+ bool last = true;
+
+ arg = bc_vec_top(&p->results);
+ if (BC_ERR(arg->t == BC_RESULT_VOID)) bc_vm_err(BC_ERR_EXEC_VOID_VAL);
+
+ a = bc_vec_item(&f->autos, nparams - 1 - i);
+
+ // If I have already pushed to a var, I need to make sure I
+ // get the previous version, not the already pushed one.
+ if (arg->t == BC_RESULT_VAR || arg->t == BC_RESULT_ARRAY) {
+ for (j = 0; j < i && last; ++j) {
+ BcLoc *loc = bc_vec_item(&f->autos, nparams - 1 - j);
+ last = (arg->d.loc.loc != loc->loc ||
+ (!loc->idx) != (arg->t == BC_RESULT_VAR));
+ }
+ }
+
+ bc_program_copyToVar(p, a->loc, (BcType) a->idx, last);
+ }
+
+ BC_SIG_LOCK;
+
+ for (; i < f->autos.len; ++i) {
+
+ a = bc_vec_item(&f->autos, i);
+ v = bc_program_vec(p, a->loc, (BcType) a->idx);
+
+ if (a->idx == BC_TYPE_VAR) {
+ bc_num_init(&param.n, BC_NUM_DEF_SIZE);
+ bc_vec_push(v, &param.n);
+ }
+ else {
+ assert(a->idx == BC_TYPE_ARRAY);
+ bc_array_init(&param.v, true);
+ bc_vec_push(v, &param.v);
+ }
+ }
+
+ bc_vec_push(&p->stack, &ip);
+
+ BC_SIG_UNLOCK;
+}
+
+static void bc_program_return(BcProgram *p, uchar inst) {
+
+ BcResult *res;
+ BcFunc *f;
+ BcInstPtr *ip = bc_vec_top(&p->stack);
+ size_t i, nops = p->results.len - ip->len;
+
+ assert(BC_PROG_STACK(&p->stack, 2));
+ assert(BC_PROG_STACK(&p->results, ip->len + (inst == BC_INST_RET)));
+
+ f = bc_vec_item(&p->fns, ip->func);
+ res = bc_program_prepResult(p);
+
+ if (inst == BC_INST_RET) {
+
+ BcNum *num;
+ BcResult *operand;
+
+ bc_program_operand(p, &operand, &num, 1);
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&res->d.n, num);
+ }
+ else if (inst == BC_INST_RET_VOID) res->t = BC_RESULT_VOID;
+ else {
+ BC_SIG_LOCK;
+ bc_num_init(&res->d.n, BC_NUM_DEF_SIZE);
+ }
+
+ BC_SIG_MAYUNLOCK;
+
+ // We need to pop arguments as well, so this takes that into account.
+ for (i = 0; i < f->autos.len; ++i) {
+
+ BcLoc *a = bc_vec_item(&f->autos, i);
+ BcVec *v = bc_program_vec(p, a->loc, (BcType) a->idx);
+
+ bc_vec_pop(v);
+ }
+
+ bc_program_retire(p, 1, nops);
+
+ if (BC_G) bc_program_popGlobals(p, false);
+
+ bc_vec_pop(&p->stack);
+}
+#endif // BC_ENABLED
+
+static void bc_program_builtin(BcProgram *p, uchar inst) {
+
+ BcResult *opd, *res;
+ BcNum *num;
+ bool len = (inst == BC_INST_LENGTH);
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ assert(inst >= BC_INST_LENGTH && inst <= BC_INST_IRAND);
+#else // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ assert(inst >= BC_INST_LENGTH && inst <= BC_INST_ABS);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+#ifndef BC_PROG_NO_STACK_CHECK
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+ }
+#endif // BC_PROG_NO_STACK_CHECK
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ res = bc_program_prepResult(p);
+
+ bc_program_operand(p, &opd, &num, 1);
+
+ assert(num != NULL);
+
+#if DC_ENABLED
+ if (!len && inst != BC_INST_SCALE_FUNC) bc_program_type_num(opd, num);
+#endif // DC_ENABLED
+
+ if (inst == BC_INST_SQRT) bc_num_sqrt(num, &res->d.n, BC_PROG_SCALE(p));
+ else if (inst == BC_INST_ABS) {
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&res->d.n, num);
+
+ BC_SIG_UNLOCK;
+
+ BC_NUM_NEG_CLR_NP(res->d.n);
+ }
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ else if (inst == BC_INST_IRAND) {
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, num->len - num->rdx);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_irand(num, &res->d.n, &p->rng);
+ }
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ else {
+
+ BcBigDig val = 0;
+
+ if (len) {
+#if BC_ENABLED
+ if (BC_IS_BC && opd->t == BC_RESULT_ARRAY) {
+
+ BcVec *v = (BcVec*) num;
+
+ if (v->size == sizeof(uchar)) v = bc_program_dereference(p, v);
+
+ assert(v->size == sizeof(BcNum));
+
+ val = (BcBigDig) v->len;
+ }
+ else
+#endif // BC_ENABLED
+ {
+#if DC_ENABLED
+ if (!BC_PROG_NUM(opd, num)) {
+ size_t idx;
+ char *str;
+ idx = opd->t == BC_RESULT_STR ? opd->d.loc.loc : num->scale;
+ str = *((char**) bc_vec_item(p->strs, idx));
+ val = (BcBigDig) strlen(str);
+ }
+ else
+#endif // DC_ENABLED
+ {
+ val = (BcBigDig) bc_num_len(num);
+ }
+ }
+ }
+ else if (BC_IS_BC || BC_PROG_NUM(opd, num))
+ val = (BcBigDig) bc_num_scale(num);
+
+ BC_SIG_LOCK;
+
+ bc_num_createFromBigdig(&res->d.n, val);
+
+ BC_SIG_UNLOCK;
+ }
+
+ bc_program_retire(p, 1, 1);
+}
+
+#if DC_ENABLED
+static void bc_program_divmod(BcProgram *p) {
+
+ BcResult *opd1, *opd2, *res, *res2;
+ BcNum *n1, *n2;
+ size_t req;
+
+ bc_vec_grow(&p->results, 2);
+
+ // We don't need to update the pointer because
+ // the capacity is enough due to the line above.
+ res2 = bc_program_prepResult(p);
+ res = bc_program_prepResult(p);
+
+ bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 2);
+
+ req = bc_num_mulReq(n1, n2, BC_PROG_SCALE(p));
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, req);
+ bc_num_init(&res2->d.n, req);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_divmod(n1, n2, &res2->d.n, &res->d.n, BC_PROG_SCALE(p));
+
+ bc_program_retire(p, 2, 2);
+}
+
+static void bc_program_modexp(BcProgram *p) {
+
+ BcResult *r1, *r2, *r3, *res;
+ BcNum *n1, *n2, *n3;
+
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 3))) bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 3));
+
+ res = bc_program_prepResult(p);
+
+ bc_program_operand(p, &r1, &n1, 3);
+ bc_program_type_num(r1, n1);
+
+ bc_program_binOpPrep(p, &r2, &n2, &r3, &n3, 1);
+
+ // Make sure that the values have their pointers updated, if necessary.
+ // Only array elements are possible.
+ if (r1->t == BC_RESULT_ARRAY_ELEM && (r1->t == r2->t || r1->t == r3->t))
+ n1 = bc_program_num(p, r1);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, n3->len);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_modexp(n1, n2, n3, &res->d.n);
+
+ bc_program_retire(p, 1, 3);
+}
+
+static void bc_program_stackLen(BcProgram *p) {
+ bc_program_pushBigdig(p, (BcBigDig) p->results.len, BC_RESULT_TEMP);
+}
+
+static uchar bc_program_asciifyNum(BcProgram *p, BcNum *n) {
+
+ BcNum num;
+ BcBigDig val = 0;
+
+ bc_num_clear(&num);
+
+ BC_SETJMP(num_err);
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&num, n);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_truncate(&num, num.scale);
+ BC_NUM_NEG_CLR_NP(num);
+
+ // This is guaranteed to not have a divide by 0
+ // because strmb is equal to UCHAR_MAX + 1.
+ bc_num_mod(&num, &p->strmb, &num, 0);
+
+ // This is also guaranteed to not error because num is in the range
+ // [0, UCHAR_MAX], which is definitely in range for a BcBigDig. And
+ // it is not negative.
+ bc_num_bigdig2(&num, &val);
+
+num_err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&num);
+ BC_LONGJMP_CONT;
+ return (uchar) val;
+}
+
+static void bc_program_asciify(BcProgram *p) {
+
+ BcResult *r, res;
+ BcNum *n;
+ char str[2], *str2;
+ uchar c;
+ size_t idx;
+
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ bc_program_operand(p, &r, &n, 0);
+
+ assert(n != NULL);
+
+ assert(p->strs->len + BC_PROG_REQ_FUNCS == p->fns.len);
+
+ if (BC_PROG_NUM(r, n)) c = bc_program_asciifyNum(p, n);
+ else {
+ size_t index = r->t == BC_RESULT_STR ? r->d.loc.loc : n->scale;
+ str2 = *((char**) bc_vec_item(p->strs, index));
+ c = (uchar) str2[0];
+ }
+
+ str[0] = (char) c;
+ str[1] = '\0';
+
+ BC_SIG_LOCK;
+
+ idx = bc_program_insertFunc(p, str) - BC_PROG_REQ_FUNCS;
+
+ BC_SIG_UNLOCK;
+
+ res.t = BC_RESULT_STR;
+ res.d.loc.loc = idx;
+ bc_vec_pop(&p->results);
+ bc_vec_push(&p->results, &res);
+}
+
+static void bc_program_printStream(BcProgram *p) {
+
+ BcResult *r;
+ BcNum *n;
+
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ bc_program_operand(p, &r, &n, 0);
+
+ assert(n != NULL);
+
+ if (BC_PROG_NUM(r, n)) bc_num_stream(n, p->strm);
+ else {
+ size_t idx = (r->t == BC_RESULT_STR) ? r->d.loc.loc : n->scale;
+ bc_program_printChars(*((char**) bc_vec_item(p->strs, idx)));
+ }
+}
+
+static void bc_program_nquit(BcProgram *p, uchar inst) {
+
+ BcResult *opnd;
+ BcNum *num;
+ BcBigDig val;
+ size_t i;
+
+ assert(p->stack.len == p->tail_calls.len);
+
+ if (inst == BC_INST_QUIT) val = 2;
+ else {
+
+ bc_program_prep(p, &opnd, &num, 0);
+ bc_num_bigdig(num, &val);
+
+ bc_vec_pop(&p->results);
+ }
+
+ 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;
+ }
+
+ if (i == p->stack.len) {
+ vm.status = BC_STATUS_QUIT;
+ BC_VM_JMP;
+ }
+ else {
+ bc_vec_npop(&p->stack, i);
+ bc_vec_npop(&p->tail_calls, i);
+ }
+}
+
+static void bc_program_execStr(BcProgram *p, const char *restrict code,
+ size_t *restrict bgn, bool cond, size_t len)
+{
+ BcResult *r;
+ char *str;
+ BcFunc *f;
+ BcParse prs;
+ BcInstPtr ip;
+ size_t fidx, sidx;
+ BcNum *n;
+
+ assert(p->stack.len == p->tail_calls.len);
+
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ bc_program_operand(p, &r, &n, 0);
+
+ if (cond) {
+
+ bool exec;
+ size_t idx, then_idx, else_idx;
+
+ then_idx = bc_program_index(code, bgn);
+ else_idx = bc_program_index(code, bgn);
+
+ exec = (r->d.n.len != 0);
+
+ idx = exec ? then_idx : else_idx;
+
+ BC_SIG_LOCK;
+ BC_SETJMP_LOCKED(exit);
+
+ if (exec || (else_idx != SIZE_MAX))
+ n = bc_vec_top(bc_program_vec(p, idx, BC_TYPE_VAR));
+ else goto exit;
+
+ if (BC_ERR(!BC_PROG_STR(n))) bc_vm_err(BC_ERR_EXEC_TYPE);
+
+ BC_UNSETJMP;
+ BC_SIG_UNLOCK;
+
+ sidx = n->scale;
+ }
+ else {
+
+ // In non-conditional situations, only the top of stack can be executed,
+ // and in those cases, variables are not allowed to be "on the stack";
+ // they are only put on the stack to be assigned to.
+ assert(r->t != BC_RESULT_VAR);
+
+ if (r->t == BC_RESULT_STR) sidx = r->d.loc.loc;
+ else return;
+ }
+
+ fidx = sidx + BC_PROG_REQ_FUNCS;
+ str = *((char**) bc_vec_item(p->strs, sidx));
+ f = bc_vec_item(&p->fns, fidx);
+
+ if (!f->code.len) {
+
+ BC_SIG_LOCK;
+
+ bc_parse_init(&prs, p, fidx);
+ bc_lex_file(&prs.l, vm.file);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_parse_text(&prs, str);
+ vm.expr(&prs, BC_PARSE_NOCALL);
+
+ BC_SIG_LOCK;
+
+ BC_UNSETJMP;
+
+ // We can just assert this here because
+ // dc should parse everything until EOF.
+ assert(prs.l.t == BC_LEX_EOF);
+
+ bc_parse_free(&prs);
+
+ BC_SIG_UNLOCK;
+ }
+
+ ip.idx = 0;
+ ip.len = p->results.len;
+ ip.func = fidx;
+
+ bc_vec_pop(&p->results);
+
+ // Tail call.
+ if (p->stack.len > 1 && *bgn == len - 1 && code[*bgn] == BC_INST_POP_EXEC) {
+ size_t *call_ptr = bc_vec_top(&p->tail_calls);
+ *call_ptr += 1;
+ bc_vec_pop(&p->stack);
+ }
+ else bc_vec_push(&p->tail_calls, &ip.idx);
+
+ bc_vec_push(&p->stack, &ip);
+
+ return;
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_parse_free(&prs);
+ f = bc_vec_item(&p->fns, fidx);
+ bc_vec_npop(&f->code, f->code.len);
+exit:
+ bc_vec_pop(&p->results);
+ BC_LONGJMP_CONT;
+}
+
+static void bc_program_printStack(BcProgram *p) {
+
+ size_t idx;
+
+ for (idx = 0; idx < p->results.len; ++idx)
+ bc_program_print(p, BC_INST_PRINT, idx);
+}
+#endif // DC_ENABLED
+
+static void bc_program_pushGlobal(BcProgram *p, uchar inst) {
+
+ BcResultType t;
+
+ assert(inst >= BC_INST_IBASE && inst <= BC_INST_SCALE);
+
+ t = inst - BC_INST_IBASE + BC_RESULT_IBASE;
+ bc_program_pushBigdig(p, p->globals[inst - BC_INST_IBASE], t);
+}
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+static void bc_program_pushSeed(BcProgram *p) {
+
+ BcResult *res;
+
+ res = bc_program_prepResult(p);
+ res->t = BC_RESULT_SEED;
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, 2 * BC_RAND_NUM_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_createFromRNG(&res->d.n, &p->rng);
+}
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+static void bc_program_addFunc(BcProgram *p, BcFunc *f, BcId *id_ptr) {
+
+ BcInstPtr *ip;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ bc_func_init(f, id_ptr->name);
+ bc_vec_push(&p->fns, f);
+
+ // This is to make sure pointers are updated if the array was moved.
+ if (p->stack.len) {
+ ip = bc_vec_top(&p->stack);
+ bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, ip->func));
+ }
+}
+
+size_t bc_program_insertFunc(BcProgram *p, const char *name) {
+
+ BcId *id_ptr;
+ BcFunc f;
+ bool new;
+ size_t idx;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL && name != NULL);
+
+ new = bc_map_insert(&p->fn_map, name, p->fns.len, &idx);
+ id_ptr = (BcId*) bc_vec_item(&p->fn_map, idx);
+ idx = id_ptr->idx;
+
+ if (!new) {
+ if (BC_IS_BC) {
+ BcFunc *func = bc_vec_item(&p->fns, idx);
+ bc_func_reset(func);
+ }
+ }
+ else {
+
+ bc_program_addFunc(p, &f, id_ptr);
+
+#if DC_ENABLED
+ if (BC_IS_DC && idx >= BC_PROG_REQ_FUNCS) {
+ bc_vec_push(p->strs, &id_ptr->name);
+ assert(p->strs->len == p->fns.len - BC_PROG_REQ_FUNCS);
+ }
+#endif // DC_ENABLED
+ }
+
+ return idx;
+}
+
+#ifndef NDEBUG
+void bc_program_free(BcProgram *p) {
+
+ size_t i;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL);
+
+ for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) bc_vec_free(p->globals_v + i);
+
+ bc_vec_free(&p->fns);
+ bc_vec_free(&p->fn_map);
+ bc_vec_free(&p->vars);
+ bc_vec_free(&p->var_map);
+ bc_vec_free(&p->arrs);
+ bc_vec_free(&p->arr_map);
+ bc_vec_free(&p->results);
+ bc_vec_free(&p->stack);
+
+#if BC_ENABLED
+ if (BC_IS_BC) bc_num_free(&p->last);
+#endif // BC_ENABLED
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ bc_rand_free(&p->rng);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+#if DC_ENABLED
+ if (BC_IS_DC) {
+ bc_vec_free(&p->tail_calls);
+ bc_vec_free(&p->strs_v);
+ }
+#endif // DC_ENABLED
+}
+#endif // NDEBUG
+
+void bc_program_init(BcProgram *p) {
+
+ BcInstPtr ip;
+ size_t i;
+ BcBigDig val = BC_BASE;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL);
+
+ memset(p, 0, sizeof(BcProgram));
+ memset(&ip, 0, sizeof(BcInstPtr));
+
+ for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) {
+ bc_vec_init(p->globals_v + i, sizeof(BcBigDig), NULL);
+ val = i == BC_PROG_GLOBALS_SCALE ? 0 : val;
+ bc_vec_push(p->globals_v + i, &val);
+ p->globals[i] = val;
+ }
+
+#if DC_ENABLED
+ if (BC_IS_DC) {
+
+ bc_vec_init(&p->strs_v, sizeof(char*), bc_string_free);
+ p->strs = &p->strs_v;
+
+ bc_vec_init(&p->tail_calls, sizeof(size_t), NULL);
+ i = 0;
+ bc_vec_push(&p->tail_calls, &i);
+
+ p->strm = UCHAR_MAX + 1;
+ bc_num_setup(&p->strmb, p->strmb_num, BC_NUM_BIGDIG_LOG10);
+ bc_num_bigdig2num(&p->strmb, p->strm);
+ }
+#endif // DC_ENABLED
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ srand((unsigned int) time(NULL));
+ bc_rand_init(&p->rng);
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+ bc_num_setup(&p->zero, p->zero_num, BC_PROG_ONE_CAP);
+
+ bc_num_setup(&p->one, p->one_num, BC_PROG_ONE_CAP);
+ bc_num_one(&p->one);
+
+#if BC_ENABLED
+ if (BC_IS_BC) bc_num_init(&p->last, BC_NUM_DEF_SIZE);
+#endif // BC_ENABLED
+
+ bc_vec_init(&p->fns, sizeof(BcFunc), bc_func_free);
+ bc_map_init(&p->fn_map);
+ bc_program_insertFunc(p, bc_func_main);
+ bc_program_insertFunc(p, bc_func_read);
+
+ bc_vec_init(&p->vars, sizeof(BcVec), bc_vec_free);
+ bc_map_init(&p->var_map);
+
+ bc_vec_init(&p->arrs, sizeof(BcVec), bc_vec_free);
+ bc_map_init(&p->arr_map);
+
+ bc_vec_init(&p->results, sizeof(BcResult), bc_result_free);
+ bc_vec_init(&p->stack, sizeof(BcInstPtr), NULL);
+ bc_vec_push(&p->stack, &ip);
+
+ bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN));
+
+ assert(p->consts != NULL && p->strs != NULL);
+}
+
+void bc_program_reset(BcProgram *p) {
+
+ BcFunc *f;
+ BcInstPtr *ip;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ bc_vec_npop(&p->stack, p->stack.len - 1);
+ bc_vec_npop(&p->results, p->results.len);
+
+#if BC_ENABLED
+ if (BC_G) bc_program_popGlobals(p, true);
+#endif // BC_ENABLED
+
+ f = bc_vec_item(&p->fns, BC_PROG_MAIN);
+ ip = bc_vec_top(&p->stack);
+ bc_program_setVecs(p, f);
+ ip->idx = f->code.len;
+
+ if (vm.sig) {
+ bc_file_write(&vm.fout, bc_program_ready_msg, bc_program_ready_msg_len);
+ bc_file_flush(&vm.fout);
+ vm.sig = 0;
+ }
+}
+
+void bc_program_exec(BcProgram *p) {
+
+ size_t idx;
+ BcResult r, *ptr;
+ BcInstPtr *ip = bc_vec_top(&p->stack);
+ BcFunc *func = (BcFunc*) bc_vec_item(&p->fns, ip->func);
+ char *code = func->code.v;
+ bool cond = false;
+#if BC_ENABLED
+ BcNum *num;
+#endif // BC_ENABLED
+#ifndef NDEBUG
+ size_t jmp_bufs_len;
+#endif // NDEBUG
+
+#ifndef NDEBUG
+ jmp_bufs_len = vm.jmp_bufs.len;
+#endif // NDEBUG
+
+ bc_program_setVecs(p, func);
+
+ while (ip->idx < func->code.len) {
+
+ BC_SIG_ASSERT_NOT_LOCKED;
+
+ uchar inst = (uchar) code[(ip->idx)++];
+
+ switch (inst) {
+
+#if BC_ENABLED
+ case BC_INST_JUMP_ZERO:
+ {
+ bc_program_prep(p, &ptr, &num, 0);
+ cond = !bc_num_cmpZero(num);
+ bc_vec_pop(&p->results);
+ }
+ // Fallthrough.
+ BC_FALLTHROUGH
+
+ case BC_INST_JUMP:
+ {
+ idx = bc_program_index(code, &ip->idx);
+
+ if (inst == BC_INST_JUMP || cond) {
+
+ size_t *addr = bc_vec_item(&func->labels, idx);
+
+ assert(*addr != SIZE_MAX);
+
+ ip->idx = *addr;
+ }
+
+ break;
+ }
+
+ case BC_INST_CALL:
+ {
+ assert(BC_IS_BC);
+
+ bc_program_call(p, code, &ip->idx);
+
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+
+ bc_program_setVecs(p, func);
+
+ break;
+ }
+
+ case BC_INST_INC:
+ case BC_INST_DEC:
+ {
+ bc_program_incdec(p, inst);
+ break;
+ }
+
+ case BC_INST_HALT:
+ {
+ vm.status = BC_STATUS_QUIT;
+ BC_VM_JMP;
+ break;
+ }
+
+ case BC_INST_RET:
+ case BC_INST_RET0:
+ case BC_INST_RET_VOID:
+ {
+ bc_program_return(p, inst);
+
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+
+ bc_program_setVecs(p, func);
+
+ break;
+ }
+#endif // BC_ENABLED
+
+ case BC_INST_BOOL_OR:
+ case BC_INST_BOOL_AND:
+ case BC_INST_REL_EQ:
+ case BC_INST_REL_LE:
+ case BC_INST_REL_GE:
+ case BC_INST_REL_NE:
+ case BC_INST_REL_LT:
+ case BC_INST_REL_GT:
+ {
+ bc_program_logical(p, inst);
+ break;
+ }
+
+ case BC_INST_READ:
+ {
+ bc_program_read(p);
+
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+
+ bc_program_setVecs(p, func);
+
+ break;
+ }
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_INST_RAND:
+ {
+ bc_program_rand(p);
+ break;
+ }
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+ case BC_INST_MAXIBASE:
+ case BC_INST_MAXOBASE:
+ case BC_INST_MAXSCALE:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_INST_MAXRAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ {
+ BcBigDig dig = vm.maxes[inst - BC_INST_MAXIBASE];
+ bc_program_pushBigdig(p, dig, BC_RESULT_TEMP);
+ break;
+ }
+
+ case BC_INST_VAR:
+ {
+ bc_program_pushVar(p, code, &ip->idx, false, false);
+ break;
+ }
+
+ case BC_INST_ARRAY_ELEM:
+#if BC_ENABLED
+ case BC_INST_ARRAY:
+#endif // BC_ENABLED
+ {
+ bc_program_pushArray(p, code, &ip->idx, inst);
+ break;
+ }
+
+ case BC_INST_IBASE:
+ case BC_INST_SCALE:
+ case BC_INST_OBASE:
+ {
+ bc_program_pushGlobal(p, inst);
+ break;
+ }
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_INST_SEED:
+ {
+ bc_program_pushSeed(p);
+ break;
+ }
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+ case BC_INST_LENGTH:
+ case BC_INST_SCALE_FUNC:
+ case BC_INST_SQRT:
+ case BC_INST_ABS:
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ case BC_INST_IRAND:
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ {
+ bc_program_builtin(p, inst);
+ break;
+ }
+
+ case BC_INST_NUM:
+ {
+ bc_program_const(p, code, &ip->idx);
+ break;
+ }
+
+ case BC_INST_ZERO:
+ case BC_INST_ONE:
+#if BC_ENABLED
+ case BC_INST_LAST:
+#endif // BC_ENABLED
+ {
+ r.t = BC_RESULT_ZERO + (inst - BC_INST_ZERO);
+ bc_vec_push(&p->results, &r);
+ break;
+ }
+
+ case BC_INST_PRINT:
+ case BC_INST_PRINT_POP:
+ case BC_INST_PRINT_STR:
+ {
+ bc_program_print(p, inst, 0);
+ break;
+ }
+
+ case BC_INST_STR:
+ {
+ r.t = BC_RESULT_STR;
+ r.d.loc.loc = bc_program_index(code, &ip->idx);
+ bc_vec_push(&p->results, &r);
+ break;
+ }
+
+ case BC_INST_POWER:
+ case BC_INST_MULTIPLY:
+ case BC_INST_DIVIDE:
+ case BC_INST_MODULUS:
+ case BC_INST_PLUS:
+ case BC_INST_MINUS:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_INST_PLACES:
+ case BC_INST_LSHIFT:
+ case BC_INST_RSHIFT:
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ bc_program_op(p, inst);
+ break;
+ }
+
+ case BC_INST_NEG:
+ case BC_INST_BOOL_NOT:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_INST_TRUNC:
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ bc_program_unary(p, inst);
+ break;
+ }
+
+#if BC_ENABLED
+ case BC_INST_ASSIGN_POWER:
+ case BC_INST_ASSIGN_MULTIPLY:
+ case BC_INST_ASSIGN_DIVIDE:
+ case BC_INST_ASSIGN_MODULUS:
+ case BC_INST_ASSIGN_PLUS:
+ case BC_INST_ASSIGN_MINUS:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_INST_ASSIGN_PLACES:
+ case BC_INST_ASSIGN_LSHIFT:
+ case BC_INST_ASSIGN_RSHIFT:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_INST_ASSIGN:
+ case BC_INST_ASSIGN_POWER_NO_VAL:
+ case BC_INST_ASSIGN_MULTIPLY_NO_VAL:
+ case BC_INST_ASSIGN_DIVIDE_NO_VAL:
+ case BC_INST_ASSIGN_MODULUS_NO_VAL:
+ case BC_INST_ASSIGN_PLUS_NO_VAL:
+ case BC_INST_ASSIGN_MINUS_NO_VAL:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_INST_ASSIGN_PLACES_NO_VAL:
+ case BC_INST_ASSIGN_LSHIFT_NO_VAL:
+ case BC_INST_ASSIGN_RSHIFT_NO_VAL:
+#endif // BC_ENABLE_EXTRA_MATH
+#endif // BC_ENABLED
+ case BC_INST_ASSIGN_NO_VAL:
+ {
+ bc_program_assign(p, inst);
+ break;
+ }
+
+ case BC_INST_POP:
+ {
+#ifndef BC_PROG_NO_STACK_CHECK
+ if (!BC_IS_BC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+ }
+#endif // BC_PROG_NO_STACK_CHECK
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ bc_vec_pop(&p->results);
+ break;
+ }
+
+#if DC_ENABLED
+ case BC_INST_POP_EXEC:
+ {
+ assert(BC_PROG_STACK(&p->stack, 2));
+ bc_vec_pop(&p->stack);
+ bc_vec_pop(&p->tail_calls);
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+ break;
+ }
+
+ case BC_INST_MODEXP:
+ {
+ bc_program_modexp(p);
+ break;
+ }
+
+ case BC_INST_DIVMOD:
+ {
+ bc_program_divmod(p);
+ break;
+ }
+
+ case BC_INST_EXECUTE:
+ case BC_INST_EXEC_COND:
+ {
+ cond = (inst == BC_INST_EXEC_COND);
+ bc_program_execStr(p, code, &ip->idx, cond, func->code.len);
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+ break;
+ }
+
+ case BC_INST_PRINT_STACK:
+ {
+ bc_program_printStack(p);
+ break;
+ }
+
+ case BC_INST_CLEAR_STACK:
+ {
+ bc_vec_npop(&p->results, p->results.len);
+ break;
+ }
+
+ case BC_INST_STACK_LEN:
+ {
+ bc_program_stackLen(p);
+ break;
+ }
+
+ case BC_INST_DUPLICATE:
+ {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ ptr = bc_vec_top(&p->results);
+
+ BC_SIG_LOCK;
+
+ bc_result_copy(&r, ptr);
+ bc_vec_push(&p->results, &r);
+
+ BC_SIG_UNLOCK;
+
+ break;
+ }
+
+ case BC_INST_SWAP:
+ {
+ BcResult *ptr2;
+
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 2)))
+ bc_vm_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 2));
+
+ ptr = bc_vec_item_rev(&p->results, 0);
+ ptr2 = bc_vec_item_rev(&p->results, 1);
+ memcpy(&r, ptr, sizeof(BcResult));
+ memcpy(ptr, ptr2, sizeof(BcResult));
+ memcpy(ptr2, &r, sizeof(BcResult));
+
+ break;
+ }
+
+ case BC_INST_ASCIIFY:
+ {
+ bc_program_asciify(p);
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+ break;
+ }
+
+ case BC_INST_PRINT_STREAM:
+ {
+ bc_program_printStream(p);
+ break;
+ }
+
+ case BC_INST_LOAD:
+ case BC_INST_PUSH_VAR:
+ {
+ bool copy = (inst == BC_INST_LOAD);
+ bc_program_pushVar(p, code, &ip->idx, true, copy);
+ break;
+ }
+
+ case BC_INST_PUSH_TO_VAR:
+ {
+ idx = bc_program_index(code, &ip->idx);
+ bc_program_copyToVar(p, idx, BC_TYPE_VAR, true);
+ break;
+ }
+
+ case BC_INST_QUIT:
+ case BC_INST_NQUIT:
+ {
+ bc_program_nquit(p, inst);
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+ break;
+ }
+#endif // DC_ENABLED
+#ifndef NDEBUG
+ default:
+ {
+ abort();
+ }
+#endif // NDEBUG
+ }
+
+#ifndef NDEBUG
+ // This is to allow me to use a debugger to see the last instruction,
+ // which will point to which function was the problem.
+ assert(jmp_bufs_len == vm.jmp_bufs.len);
+#endif // NDEBUG
+ }
+}
+
+#if BC_DEBUG_CODE
+#if BC_ENABLED && DC_ENABLED
+void bc_program_printStackDebug(BcProgram *p) {
+ bc_file_puts(&vm.fout, "-------------- Stack ----------\n");
+ bc_program_printStack(p);
+ bc_file_puts(&vm.fout, "-------------- Stack End ------\n");
+}
+
+static void bc_program_printIndex(const char *restrict code,
+ size_t *restrict bgn)
+{
+ uchar byte, i, bytes = (uchar) code[(*bgn)++];
+ ulong val = 0;
+
+ for (byte = 1, i = 0; byte && i < bytes; ++i) {
+ byte = (uchar) code[(*bgn)++];
+ if (byte) val |= ((ulong) byte) << (CHAR_BIT * i);
+ }
+
+ bc_vm_printf(" (%lu) ", val);
+}
+
+static void bc_program_printStr(const BcProgram *p, const char *restrict code,
+ size_t *restrict bgn)
+{
+ size_t idx = bc_program_index(code, bgn);
+ char *s;
+
+ s = *((char**) bc_vec_item(p->strs, idx));
+
+ bc_vm_printf(" (\"%s\") ", s);
+}
+
+void bc_program_printInst(const BcProgram *p, const char *restrict code,
+ size_t *restrict bgn)
+{
+ uchar inst = (uchar) code[(*bgn)++];
+
+ bc_vm_printf("Inst[%zu]: %s [%lu]; ", *bgn - 1,
+ bc_inst_names[inst], (unsigned long) inst);
+
+ if (inst == BC_INST_VAR || inst == BC_INST_ARRAY_ELEM ||
+ inst == BC_INST_ARRAY)
+ {
+ bc_program_printIndex(code, bgn);
+ }
+ else if (inst == BC_INST_STR) bc_program_printStr(p, code, bgn);
+ else if (inst == BC_INST_NUM) {
+ size_t idx = bc_program_index(code, bgn);
+ BcConst *c = bc_vec_item(p->consts, idx);
+ bc_vm_printf("(%s)", c->val);
+ }
+ else if (inst == BC_INST_CALL ||
+ (inst > BC_INST_STR && inst <= BC_INST_JUMP_ZERO))
+ {
+ bc_program_printIndex(code, bgn);
+ if (inst == BC_INST_CALL) bc_program_printIndex(code, bgn);
+ }
+
+ bc_vm_putchar('\n');
+}
+
+void bc_program_code(const BcProgram* p) {
+
+ BcFunc *f;
+ char *code;
+ BcInstPtr ip;
+ size_t i;
+
+ for (i = 0; i < p->fns.len; ++i) {
+
+ ip.idx = ip.len = 0;
+ ip.func = i;
+
+ f = bc_vec_item(&p->fns, ip.func);
+ code = f->code.v;
+
+ 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");
+ }
+}
+#endif // BC_ENABLED && DC_ENABLED
+#endif // BC_DEBUG_CODE
diff --git a/contrib/bc/src/rand.c b/contrib/bc/src/rand.c
new file mode 100644
index 000000000000..a66728246fbc
--- /dev/null
+++ b/contrib/bc/src/rand.c
@@ -0,0 +1,414 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2019 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.
+ *
+ * *****************************************************************************
+ *
+ * Parts of this code are adapted from the following:
+ *
+ * PCG, A Family of Better Random Number Generators.
+ *
+ * You can find the original source code at:
+ * https://github.com/imneme/pcg-c
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Parts of this code are also under the following license:
+ *
+ * Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * *****************************************************************************
+ *
+ * Code for the RNG.
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <status.h>
+#include <rand.h>
+#include <vm.h>
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+#if !BC_RAND_BUILTIN
+
+static BcRandState bc_rand_addition(uint_fast64_t a, uint_fast64_t b) {
+
+ BcRandState res;
+
+ res.lo = a + b;
+ res.hi = (res.lo < a);
+
+ return res;
+}
+
+static BcRandState bc_rand_addition2(BcRandState a, BcRandState b) {
+
+ BcRandState temp, res;
+
+ res = bc_rand_addition(a.lo, b.lo);
+ temp = bc_rand_addition(a.hi, b.hi);
+ res.hi += temp.lo;
+
+ return res;
+}
+
+static BcRandState bc_rand_multiply(uint_fast64_t a, uint_fast64_t b) {
+
+ uint_fast64_t al, ah, bl, bh, c0, c1, c2, c3;
+ BcRandState carry, res;
+
+ al = BC_RAND_TRUNC32(a);
+ ah = BC_RAND_CHOP32(a);
+ bl = BC_RAND_TRUNC32(b);
+ bh = BC_RAND_CHOP32(b);
+
+ c0 = al * bl;
+ c1 = al * bh;
+ c2 = ah * bl;
+ c3 = ah * bh;
+
+ carry = bc_rand_addition(c1, c2);
+
+ res = bc_rand_addition(c0, (BC_RAND_TRUNC32(carry.lo)) << 32);
+ res.hi += BC_RAND_CHOP32(carry.lo) + c3 + (carry.hi << 32);
+
+ return res;
+}
+
+static BcRandState bc_rand_multiply2(BcRandState a, BcRandState b) {
+
+ BcRandState c0, c1, c2, carry;
+
+ c0 = bc_rand_multiply(a.lo, b.lo);
+ c1 = bc_rand_multiply(a.lo, b.hi);
+ c2 = bc_rand_multiply(a.hi, b.lo);
+
+ carry = bc_rand_addition2(c1, c2);
+ carry.hi = carry.lo;
+ carry.lo = 0;
+
+ return bc_rand_addition2(c0, carry);
+}
+
+#endif // BC_RAND_BUILTIN
+
+static void bc_rand_setModified(BcRNGData *r) {
+
+#if BC_RAND_BUILTIN
+ r->inc |= (BcRandState) 1UL;
+#else // BC_RAND_BUILTIN
+ r->inc.lo |= (uint_fast64_t) 1UL;
+#endif // BC_RAND_BUILTIN
+}
+
+static void bc_rand_clearModified(BcRNGData *r) {
+
+#if BC_RAND_BUILTIN
+ r->inc &= ~((BcRandState) 1UL);
+#else // BC_RAND_BUILTIN
+ r->inc.lo &= ~(1UL);
+#endif // BC_RAND_BUILTIN
+}
+
+static void bc_rand_copy(BcRNGData *d, BcRNGData *s) {
+ bool unmod = BC_RAND_NOTMODIFIED(d);
+ memcpy(d, s, sizeof(BcRNGData));
+ if (!unmod) bc_rand_setModified(d);
+ else if (!BC_RAND_NOTMODIFIED(s)) bc_rand_clearModified(d);
+}
+
+static ulong bc_rand_frand(void *ptr) {
+
+ ulong buf[1];
+ int fd;
+ ssize_t nread;
+
+ assert(ptr != NULL);
+
+ fd = *((int*) ptr);
+
+ nread = read(fd, buf, sizeof(ulong));
+
+ if (BC_ERR(nread != sizeof(ulong))) bc_vm_err(BC_ERR_FATAL_IO_ERR);
+
+ return *((ulong*) buf);
+}
+
+static ulong bc_rand_rand(void *ptr) {
+
+ size_t i;
+ ulong res = 0;
+
+ BC_UNUSED(ptr);
+
+ for (i = 0; i < sizeof(ulong); ++i)
+ res |= ((ulong) (rand() & BC_RAND_SRAND_BITS)) << (i * CHAR_BIT);
+
+ return res;
+}
+
+static BcRandState bc_rand_inc(BcRNGData *r) {
+
+ BcRandState inc;
+
+#if BC_RAND_BUILTIN
+ inc = r->inc | 1;
+#else // BC_RAND_BUILTIN
+ inc.lo = r->inc.lo | 1;
+ inc.hi = r->inc.hi;
+#endif // BC_RAND_BUILTIN
+
+ return inc;
+}
+
+static void bc_rand_setInc(BcRNGData *r) {
+
+#if BC_RAND_BUILTIN
+ r->inc <<= 1UL;
+#else // BC_RAND_BUILTIN
+ r->inc.hi <<= 1UL;
+ r->inc.hi |= (r->inc.lo & (1UL << (BC_LONG_BIT - 1))) >> (BC_LONG_BIT - 1);
+ r->inc.lo <<= 1UL;
+#endif // BC_RAND_BUILTIN
+}
+
+static void bc_rand_seedState(BcRandState *state, ulong val1, ulong val2) {
+
+#if BC_RAND_BUILTIN
+ *state = ((BcRandState) val1) | ((BcRandState) val2) << (BC_LONG_BIT);
+#else // BC_RAND_BUILTIN
+ state->lo = val1;
+ state->hi = val2;
+#endif // BC_RAND_BUILTIN
+}
+
+static void bc_rand_seedRNG(BcRNGData *r, ulong state1, ulong state2,
+ ulong inc1, ulong inc2)
+{
+ bc_rand_seedState(&r->state, state1, state2);
+ bc_rand_seedState(&r->inc, inc1, inc2);
+ bc_rand_setInc(r);
+}
+
+static void bc_rand_fill(BcRNGData *r, BcRandUlong fulong, void *ptr) {
+
+ ulong state1, state2, inc1, inc2;
+
+ state1 = fulong(ptr);
+ state2 = fulong(ptr);
+
+ inc1 = fulong(ptr);
+ inc2 = fulong(ptr);
+
+ bc_rand_seedRNG(r, state1, state2, inc1, inc2);
+}
+
+static void bc_rand_step(BcRNGData *r) {
+ BcRandState temp = bc_rand_mul2(r->state, bc_rand_multiplier);
+ r->state = bc_rand_add2(temp, bc_rand_inc(r));
+}
+
+static BcRand bc_rand_output(BcRNGData *r) {
+ return BC_RAND_ROT(BC_RAND_FOLD(r->state), BC_RAND_ROTAMT(r->state));
+}
+
+static void bc_rand_seedZeroes(BcRNG *r, BcRNGData *rng, size_t idx) {
+
+ BcRNGData *rng2;
+
+ if (r->v.len <= idx) return;
+
+ rng2 = bc_vec_item_rev(&r->v, idx);
+
+ if (BC_RAND_ZERO(rng2)) {
+ size_t i;
+ for (i = 1; i < r->v.len; ++i)
+ bc_rand_copy(bc_vec_item_rev(&r->v, i), rng);
+ }
+}
+
+void bc_rand_srand(BcRNGData *rng) {
+
+ int fd;
+
+ BC_SIG_LOCK;
+
+ fd = open("/dev/urandom", O_RDONLY);
+
+ if (BC_NO_ERR(fd >= 0)) {
+ bc_rand_fill(rng, bc_rand_frand, &fd);
+ close(fd);
+ }
+
+ while (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_fill(rng, bc_rand_rand, NULL);
+
+ BC_SIG_UNLOCK;
+}
+
+static void bc_rand_propagate(BcRNG *r, BcRNGData *rng) {
+
+ if (r->v.len <= 1) return;
+
+ if (BC_RAND_NOTMODIFIED(rng)) {
+
+ size_t i;
+ bool go = true;
+
+ for (i = 1; go && i < r->v.len; ++i) {
+ BcRNGData *rng2 = bc_vec_item_rev(&r->v, i);
+ go = BC_RAND_NOTMODIFIED(rng2);
+ bc_rand_copy(rng2, rng);
+ }
+
+ bc_rand_seedZeroes(r, rng, i);
+ }
+ else bc_rand_seedZeroes(r, rng, 1);
+}
+
+BcRand bc_rand_int(BcRNG *r) {
+
+ BcRNGData *rng = bc_vec_top(&r->v);
+
+ if (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_srand(rng);
+
+ bc_rand_step(rng);
+ bc_rand_propagate(r, rng);
+
+ return bc_rand_output(rng);
+}
+
+BcRand bc_rand_bounded(BcRNG *r, BcRand bound) {
+
+ BcRand rand, threshold = (0 - bound) % bound;
+
+ do {
+ rand = bc_rand_int(r);
+ } while (rand < threshold);
+
+ return rand % bound;
+}
+
+void bc_rand_seed(BcRNG *r, ulong state1, ulong state2, ulong inc1, ulong inc2)
+{
+ BcRNGData *rng = bc_vec_top(&r->v);
+
+ bc_rand_seedState(&rng->inc, inc1, inc2);
+ bc_rand_setInc(rng);
+ bc_rand_setModified(rng);
+
+ if (!state1 && !state2) {
+ memcpy(&rng->state, &rng->inc, sizeof(BcRandState));
+ bc_rand_step(rng);
+ }
+ else bc_rand_seedState(&rng->state, state1, state2);
+
+ bc_rand_propagate(r, rng);
+}
+
+static BcRandState bc_rand_getInc(BcRNGData *r) {
+
+ BcRandState res;
+
+#if BC_RAND_BUILTIN
+ res = r->inc >> 1;
+#else // BC_RAND_BUILTIN
+ res = r->inc;
+ res.lo >>= 1;
+ res.lo |= (res.hi & 1) << (BC_LONG_BIT - 1);
+ res.hi >>= 1;
+#endif // BC_RAND_BUILTIN
+
+ return res;
+}
+
+void bc_rand_getRands(BcRNG *r, BcRand *s1, BcRand *s2, BcRand *i1, BcRand *i2)
+{
+ BcRandState inc;
+ BcRNGData *rng = bc_vec_top(&r->v);
+
+ if (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_srand(rng);
+
+ inc = bc_rand_getInc(rng);
+
+ *s1 = BC_RAND_TRUNC(rng->state);
+ *s2 = BC_RAND_CHOP(rng->state);
+
+ *i1 = BC_RAND_TRUNC(inc);
+ *i2 = BC_RAND_CHOP(inc);
+}
+
+void bc_rand_push(BcRNG *r) {
+ BcRNGData rng;
+ memset(&rng, 0, sizeof(BcRNGData));
+ if (r->v.len > 0) bc_rand_copy(&rng, bc_vec_top(&r->v));
+ bc_vec_push(&r->v, &rng);
+}
+
+void bc_rand_pop(BcRNG *r, bool reset) {
+ bc_vec_npop(&r->v, reset ? r->v.len - 1 : 1);
+}
+
+void bc_rand_init(BcRNG *r) {
+ BC_SIG_ASSERT_LOCKED;
+ bc_vec_init(&r->v, sizeof(BcRNGData), NULL);
+ bc_rand_push(r);
+}
+
+#ifndef NDEBUG
+void bc_rand_free(BcRNG *r) {
+ BC_SIG_ASSERT_LOCKED;
+ bc_vec_free(&r->v);
+}
+#endif // NDEBUG
+
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
diff --git a/contrib/bc/src/read.c b/contrib/bc/src/read.c
new file mode 100644
index 000000000000..45e868c927da
--- /dev/null
+++ b/contrib/bc/src/read.c
@@ -0,0 +1,227 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code to handle special I/O for bc.
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <signal.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <read.h>
+#include <history.h>
+#include <program.h>
+#include <vm.h>
+
+static bool bc_read_binary(const char *buf, size_t size) {
+
+ size_t i;
+
+ for (i = 0; i < size; ++i) {
+ if (BC_ERR(BC_READ_BIN_CHAR(buf[i]))) return true;
+ }
+
+ return false;
+}
+
+bool bc_read_buf(BcVec *vec, char *buf, size_t *buf_len) {
+
+ char *nl;
+
+ if (!*buf_len) return false;
+
+ nl = strchr(buf, '\n');
+
+ if (nl != NULL) {
+
+ size_t nllen = (size_t) ((nl + 1) - buf);
+
+ nllen = *buf_len >= nllen ? nllen : *buf_len;
+
+ bc_vec_npush(vec, nllen, buf);
+ *buf_len -= nllen;
+ memmove(buf, nl + 1, *buf_len + 1);
+
+ return true;
+ }
+
+ bc_vec_npush(vec, *buf_len, buf);
+ *buf_len = 0;
+
+ return false;
+}
+
+BcStatus bc_read_chars(BcVec *vec, const char *prompt) {
+
+ bool done = false;
+
+ assert(vec != NULL && vec->size == sizeof(char));
+
+ BC_SIG_ASSERT_NOT_LOCKED;
+
+ bc_vec_npop(vec, vec->len);
+
+#if BC_ENABLE_PROMPT
+ if (BC_USE_PROMPT) {
+ bc_file_puts(&vm.fout, prompt);
+ bc_file_flush(&vm.fout);
+ }
+#endif // BC_ENABLE_PROMPT
+
+ if (bc_read_buf(vec, vm.buf, &vm.buf_len)) {
+ bc_vec_pushByte(vec, '\0');
+ return BC_STATUS_SUCCESS;
+ }
+
+ while (!done) {
+
+ ssize_t r;
+
+ BC_SIG_LOCK;
+
+ r = read(STDIN_FILENO, vm.buf + vm.buf_len,
+ BC_VM_STDIN_BUF_SIZE - vm.buf_len);
+
+ if (BC_UNLIKELY(r < 0)) {
+
+ if (errno == EINTR) {
+
+ if (vm.status == (sig_atomic_t) BC_STATUS_QUIT) {
+ BC_SIG_UNLOCK;
+ return BC_STATUS_QUIT;
+ }
+
+ assert(vm.sig);
+
+ vm.status = (sig_atomic_t) BC_STATUS_SUCCESS;
+#if BC_ENABLE_PROMPT
+ if (BC_USE_PROMPT) bc_file_puts(&vm.fout, prompt);
+#endif // BC_ENABLE_PROMPT
+ bc_file_flush(&vm.fout);
+
+ BC_SIG_UNLOCK;
+
+ continue;
+ }
+
+ BC_SIG_UNLOCK;
+
+ bc_vm_err(BC_ERR_FATAL_IO_ERR);
+ }
+
+ BC_SIG_UNLOCK;
+
+ if (r == 0) {
+ bc_vec_pushByte(vec, '\0');
+ return BC_STATUS_EOF;
+ }
+
+ vm.buf_len += (size_t) r;
+ vm.buf[vm.buf_len] = '\0';
+
+ done = bc_read_buf(vec, vm.buf, &vm.buf_len);
+ }
+
+ bc_vec_pushByte(vec, '\0');
+
+ return BC_STATUS_SUCCESS;
+}
+
+BcStatus bc_read_line(BcVec *vec, const char *prompt) {
+
+ BcStatus s;
+
+#if BC_ENABLE_HISTORY
+ if (BC_TTY && !vm.history.badTerm)
+ s = bc_history_line(&vm.history, vec, prompt);
+ else s = bc_read_chars(vec, prompt);
+#else // BC_ENABLE_HISTORY
+ s = bc_read_chars(vec, prompt);
+#endif // BC_ENABLE_HISTORY
+
+ if (BC_ERR(bc_read_binary(vec->v, vec->len - 1)))
+ bc_vm_verr(BC_ERR_FATAL_BIN_FILE, bc_program_stdin_name);
+
+ return s;
+}
+
+void bc_read_file(const char *path, char **buf) {
+
+ BcErr e = BC_ERR_FATAL_IO_ERR;
+ size_t size, r;
+ struct stat pstat;
+ int fd;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(path != NULL);
+
+ fd = 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;
+
+ if (BC_ERR(S_ISDIR(pstat.st_mode))) {
+ e = BC_ERR_FATAL_PATH_DIR;
+ goto malloc_err;
+ }
+
+ size = (size_t) pstat.st_size;
+ *buf = bc_vm_malloc(size + 1);
+
+ r = (size_t) read(fd, *buf, size);
+ if (BC_ERR(r != size)) goto read_err;
+
+ (*buf)[size] = '\0';
+
+ if (BC_ERR(bc_read_binary(*buf, size))) {
+ e = BC_ERR_FATAL_BIN_FILE;
+ goto read_err;
+ }
+
+ close(fd);
+
+ return;
+
+read_err:
+ free(*buf);
+malloc_err:
+ close(fd);
+ bc_vm_verr(e, path);
+}
diff --git a/contrib/bc/src/vector.c b/contrib/bc/src/vector.c
new file mode 100644
index 000000000000..df6936aaeb76
--- /dev/null
+++ b/contrib/bc/src/vector.c
@@ -0,0 +1,344 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code to manipulate vectors (resizable arrays).
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vector.h>
+#include <lang.h>
+#include <vm.h>
+
+void bc_vec_grow(BcVec *restrict v, size_t n) {
+
+ size_t len, cap = v->cap;
+ sig_atomic_t lock;
+
+ len = bc_vm_growSize(v->len, n);
+
+ while (cap < len) cap = bc_vm_growSize(cap, cap);
+
+ BC_SIG_TRYLOCK(lock);
+ v->v = bc_vm_realloc(v->v, bc_vm_arraySize(cap, v->size));
+ v->cap = cap;
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+void bc_vec_init(BcVec *restrict v, size_t esize, BcVecFree dtor) {
+ BC_SIG_ASSERT_LOCKED;
+ assert(v != NULL && esize);
+ v->size = esize;
+ v->cap = BC_VEC_START_CAP;
+ v->len = 0;
+ v->dtor = dtor;
+ v->v = bc_vm_malloc(bc_vm_arraySize(BC_VEC_START_CAP, esize));
+}
+
+void bc_vec_expand(BcVec *restrict v, size_t req) {
+
+ assert(v != NULL);
+
+ if (v->cap < req) {
+
+ sig_atomic_t lock;
+
+ BC_SIG_TRYLOCK(lock);
+
+ v->v = bc_vm_realloc(v->v, bc_vm_arraySize(req, v->size));
+ v->cap = req;
+
+ BC_SIG_TRYUNLOCK(lock);
+ }
+}
+
+void bc_vec_npop(BcVec *restrict v, size_t n) {
+
+ sig_atomic_t lock;
+
+ assert(v != NULL && n <= v->len);
+
+ BC_SIG_TRYLOCK(lock);
+
+ if (v->dtor == NULL) v->len -= n;
+ else {
+ size_t len = v->len - n;
+ while (v->len > len) v->dtor(v->v + (v->size * --v->len));
+ }
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx) {
+
+ char* ptr, *data;
+
+ assert(v != NULL);
+ assert(idx + n < v->len);
+
+ ptr = bc_vec_item(v, idx);
+ data = bc_vec_item(v, idx + n);
+
+ BC_SIG_LOCK;
+
+ if (v->dtor != NULL) {
+
+ size_t i;
+
+ for (i = 0; i < n; ++i) v->dtor(bc_vec_item(v, idx + i));
+ }
+
+ v->len -= n;
+ memmove(ptr, data, (v->len - idx) * v->size);
+
+ BC_SIG_UNLOCK;
+}
+
+void bc_vec_npush(BcVec *restrict v, size_t n, const void *data) {
+
+ sig_atomic_t lock;
+
+ assert(v != NULL && data != NULL);
+
+ BC_SIG_TRYLOCK(lock);
+
+ if (v->len + n > v->cap) bc_vec_grow(v, n);
+
+ memcpy(v->v + (v->size * v->len), data, v->size * n);
+ v->len += n;
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+inline void bc_vec_push(BcVec *restrict v, const void *data) {
+ bc_vec_npush(v, 1, data);
+}
+
+void bc_vec_pushByte(BcVec *restrict v, uchar data) {
+ assert(v != NULL && v->size == sizeof(uchar));
+ bc_vec_npush(v, 1, &data);
+}
+
+void bc_vec_pushIndex(BcVec *restrict v, size_t idx) {
+
+ uchar amt, nums[sizeof(size_t) + 1];
+
+ assert(v != NULL);
+ assert(v->size == sizeof(uchar));
+
+ for (amt = 0; idx; ++amt) {
+ nums[amt + 1] = (uchar) idx;
+ idx &= ((size_t) ~(UCHAR_MAX));
+ idx >>= sizeof(uchar) * CHAR_BIT;
+ }
+
+ nums[0] = amt;
+
+ bc_vec_npush(v, amt + 1, nums);
+}
+
+static void bc_vec_pushAt(BcVec *restrict v, const void *data, size_t idx) {
+
+ sig_atomic_t lock;
+
+ assert(v != NULL && data != NULL && idx <= v->len);
+
+ BC_SIG_TRYLOCK(lock);
+
+ if (idx == v->len) bc_vec_push(v, data);
+ else {
+
+ char *ptr;
+
+ if (v->len == v->cap) bc_vec_grow(v, 1);
+
+ ptr = v->v + v->size * idx;
+
+ memmove(ptr + v->size, ptr, v->size * (v->len++ - idx));
+ memmove(ptr, data, v->size);
+ }
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+void bc_vec_string(BcVec *restrict v, size_t len, const char *restrict str) {
+
+ sig_atomic_t lock;
+
+ assert(v != NULL && v->size == sizeof(char));
+ assert(v->dtor == NULL);
+ assert(!v->len || !v->v[v->len - 1]);
+ assert(v->v != str);
+
+ BC_SIG_TRYLOCK(lock);
+
+ bc_vec_npop(v, v->len);
+ bc_vec_expand(v, bc_vm_growSize(len, 1));
+ memcpy(v->v, str, len);
+ v->len = len;
+
+ bc_vec_pushByte(v, '\0');
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+void bc_vec_concat(BcVec *restrict v, const char *restrict str) {
+
+ sig_atomic_t lock;
+
+ assert(v != NULL && v->size == sizeof(char));
+ assert(v->dtor == NULL);
+ assert(!v->len || !v->v[v->len - 1]);
+ assert(v->v != str);
+
+ BC_SIG_TRYLOCK(lock);
+
+ if (v->len) v->len -= 1;
+
+ bc_vec_npush(v, strlen(str) + 1, str);
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+void bc_vec_empty(BcVec *restrict v) {
+
+ sig_atomic_t lock;
+
+ assert(v != NULL && v->size == sizeof(char));
+ assert(v->dtor == NULL);
+
+ BC_SIG_TRYLOCK(lock);
+
+ bc_vec_npop(v, v->len);
+ bc_vec_pushByte(v, '\0');
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+#if BC_ENABLE_HISTORY
+void bc_vec_replaceAt(BcVec *restrict v, size_t idx, const void *data) {
+
+ char *ptr;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(v != NULL);
+
+ ptr = bc_vec_item(v, idx);
+
+ if (v->dtor != NULL) v->dtor(ptr);
+
+ memcpy(ptr, data, v->size);
+}
+#endif // BC_ENABLE_HISTORY
+
+inline void* bc_vec_item(const BcVec *restrict v, size_t idx) {
+ assert(v != NULL && v->len && idx < v->len);
+ return v->v + v->size * idx;
+}
+
+inline void* bc_vec_item_rev(const BcVec *restrict v, size_t idx) {
+ assert(v != NULL && v->len && idx < v->len);
+ return v->v + v->size * (v->len - idx - 1);
+}
+
+inline void bc_vec_clear(BcVec *restrict v) {
+ BC_SIG_ASSERT_LOCKED;
+ v->v = NULL;
+ v->len = 0;
+ v->dtor = NULL;
+}
+
+void bc_vec_free(void *vec) {
+ BcVec *v = (BcVec*) vec;
+ BC_SIG_ASSERT_LOCKED;
+ bc_vec_npop(v, v->len);
+ free(v->v);
+}
+
+static size_t bc_map_find(const BcVec *restrict v, const char *name) {
+
+ size_t low = 0, high = v->len;
+
+ while (low < high) {
+
+ size_t mid = (low + high) / 2;
+ const BcId *id = bc_vec_item(v, mid);
+ int result = strcmp(name, id->name);
+
+ if (!result) return mid;
+ else if (result < 0) high = mid;
+ else low = mid + 1;
+ }
+
+ return low;
+}
+
+bool bc_map_insert(BcVec *restrict v, const char *name,
+ size_t idx, size_t *restrict i)
+{
+ BcId id;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(v != NULL && name != NULL && i != NULL);
+
+ *i = bc_map_find(v, name);
+
+ assert(*i <= v->len);
+
+ if (*i != v->len && !strcmp(name, ((BcId*) bc_vec_item(v, *i))->name))
+ return false;
+
+ id.name = bc_vm_strdup(name);
+ id.idx = idx;
+
+ bc_vec_pushAt(v, &id, *i);
+
+ return true;
+}
+
+size_t bc_map_index(const BcVec *restrict v, const char *name) {
+
+ size_t i;
+
+ assert(v != NULL && name != NULL);
+
+ i = bc_map_find(v, name);
+
+ if (i >= v->len) return BC_VEC_INVALID_IDX;
+
+ return strcmp(name, ((BcId*) bc_vec_item(v, i))->name) ?
+ BC_VEC_INVALID_IDX : i;
+}
diff --git a/contrib/bc/src/vm.c b/contrib/bc/src/vm.c
new file mode 100644
index 000000000000..3922b088414f
--- /dev/null
+++ b/contrib/bc/src/vm.c
@@ -0,0 +1,919 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Code common to all of bc and dc.
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <signal.h>
+
+#include <setjmp.h>
+
+#ifndef _WIN32
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#else // _WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <io.h>
+
+#endif // _WIN32
+
+#include <vector.h>
+#include <args.h>
+#include <vm.h>
+#include <read.h>
+#include <bc.h>
+
+char output_bufs[BC_VM_BUF_SIZE];
+BcVm vm;
+
+#if BC_DEBUG_CODE
+BC_NORETURN void bc_vm_jmp(const char* f) {
+#else // BC_DEBUG_CODE
+BC_NORETURN void bc_vm_jmp(void) {
+#endif
+
+ assert(BC_SIG_EXC);
+
+ 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);
+#endif // BC_DEBUG_CODE
+
+#ifndef NDEBUG
+ assert(vm.jmp_bufs.len - (size_t) vm.sig_pop);
+#endif // NDEBUG
+
+ if (vm.jmp_bufs.len == 0) abort();
+ if (vm.sig_pop) bc_vec_pop(&vm.jmp_bufs);
+ else vm.sig_pop = 1;
+
+ siglongjmp(*((sigjmp_buf*) bc_vec_top(&vm.jmp_bufs)), 1);
+}
+
+#if !BC_ENABLE_LIBRARY
+static void bc_vm_sig(int sig) {
+
+ // There is already a signal in flight.
+ if (vm.status == (sig_atomic_t) BC_STATUS_QUIT || vm.sig) {
+ if (!BC_TTY || sig != SIGINT) vm.status = BC_STATUS_QUIT;
+ return;
+ }
+
+ if (BC_TTY && sig == SIGINT) {
+
+ int err = errno;
+
+ if (write(STDOUT_FILENO, vm.sigmsg, vm.siglen) != (ssize_t) vm.siglen)
+ vm.status = BC_STATUS_ERROR_FATAL;
+ else vm.sig = 1;
+
+ errno = err;
+ }
+ else vm.status = BC_STATUS_QUIT;
+
+ assert(vm.jmp_bufs.len);
+
+ if (!vm.sig_lock) BC_VM_JMP;
+}
+
+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);
+
+ if (help) {
+ bc_file_putchar(&vm.fout, '\n');
+ bc_file_printf(&vm.fout, help, vm.name, vm.name);
+ }
+
+ bc_file_flush(&vm.fout);
+}
+#endif // !BC_ENABLE_LIBRARY
+
+#if BC_ENABLE_LIBRARY
+void bc_vm_handleError(BcErr e) {
+
+ assert(e < BC_ERR_NELEMS);
+ assert(!vm.sig_pop);
+
+ BC_SIG_LOCK;
+
+ if (e <= BC_ERR_MATH_DIVIDE_BY_ZERO) {
+ vm.err = (BclError) (e - BC_ERR_MATH_NEGATIVE +
+ BCL_ERROR_MATH_NEGATIVE);
+ }
+ else if (vm.abrt) abort();
+ else if (e == BC_ERR_FATAL_ALLOC_ERR) vm.err = BCL_ERROR_FATAL_ALLOC_ERR;
+ else vm.err = BCL_ERROR_FATAL_UNKNOWN_ERR;
+
+ BC_VM_JMP;
+}
+#else // BC_ENABLE_LIBRARY
+void bc_vm_handleError(BcErr e, size_t line, ...) {
+
+ BcStatus s;
+ va_list args;
+ uchar id = bc_err_ids[e];
+ const char* err_type = vm.err_ids[id];
+ sig_atomic_t lock;
+
+ assert(e < BC_ERR_NELEMS);
+ assert(!vm.sig_pop);
+
+#if BC_ENABLED
+ if (!BC_S && e >= BC_ERR_POSIX_START) {
+ if (BC_W) {
+ // Make sure to not return an error.
+ id = UCHAR_MAX;
+ err_type = vm.err_ids[BC_ERR_IDX_WARN];
+ }
+ else return;
+ }
+#endif // BC_ENABLED
+
+ BC_SIG_TRYLOCK(lock);
+
+ // Make sure all of stdout is written first.
+ s = bc_file_flushErr(&vm.fout);
+
+ if (BC_ERR(s == BC_STATUS_ERROR_FATAL)) {
+ vm.status = (sig_atomic_t) s;
+ BC_VM_JMP;
+ }
+
+ va_start(args, line);
+ bc_file_putchar(&vm.ferr, '\n');
+ bc_file_puts(&vm.ferr, err_type);
+ bc_file_putchar(&vm.ferr, ' ');
+ bc_file_vprintf(&vm.ferr, vm.err_msgs[e], args);
+ va_end(args);
+
+ if (BC_NO_ERR(vm.file)) {
+
+ // 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_printf(&vm.ferr, bc_err_line, line);
+ }
+ else {
+
+ 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);
+
+#if BC_ENABLED
+ if (BC_IS_BC && ip->func != BC_PROG_MAIN &&
+ ip->func != BC_PROG_READ)
+ {
+ bc_file_puts(&vm.ferr, "()");
+ }
+#endif // BC_ENABLED
+ }
+ }
+
+ bc_file_puts(&vm.ferr, "\n\n");
+
+ s = bc_file_flushErr(&vm.ferr);
+
+ vm.status = s == BC_STATUS_ERROR_FATAL ?
+ (sig_atomic_t) s : (sig_atomic_t) (uchar) (id + 1);
+
+ if (BC_ERR(vm.status)) BC_VM_JMP;
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+static void bc_vm_envArgs(const char* const env_args_name) {
+
+ char *env_args = getenv(env_args_name), *buf, *start;
+ char instr = '\0';
+
+ BC_SIG_ASSERT_LOCKED;
+
+ if (env_args == NULL) return;
+
+ start = buf = vm.env_args_buffer = bc_vm_strdup(env_args);
+
+ assert(buf != NULL);
+
+ bc_vec_init(&vm.env_args, sizeof(char*), NULL);
+ bc_vec_push(&vm.env_args, &env_args_name);
+
+ while (*buf) {
+
+ if (!isspace(*buf)) {
+
+ if (*buf == '"' || *buf == '\'') {
+
+ instr = *buf;
+ buf += 1;
+
+ if (*buf == instr) {
+ instr = '\0';
+ buf += 1;
+ continue;
+ }
+ }
+
+ bc_vec_push(&vm.env_args, &buf);
+
+ while (*buf && ((!instr && !isspace(*buf)) ||
+ (instr && *buf != instr)))
+ {
+ buf += 1;
+ }
+
+ if (*buf) {
+
+ if (instr) instr = '\0';
+
+ *buf = '\0';
+ buf += 1;
+ start = buf;
+ }
+ else if (instr) bc_vm_error(BC_ERR_FATAL_OPTION, 0, start);
+ }
+ else buf += 1;
+ }
+
+ // Make sure to push a NULL pointer at the end.
+ buf = NULL;
+ bc_vec_push(&vm.env_args, &buf);
+
+ bc_args((int) vm.env_args.len - 1, bc_vec_item(&vm.env_args, 0));
+}
+
+static size_t bc_vm_envLen(const char *var) {
+
+ char *lenv = getenv(var);
+ size_t i, len = BC_NUM_PRINT_WIDTH;
+ int num;
+
+ if (lenv == NULL) return len;
+
+ len = strlen(lenv);
+
+ for (num = 1, i = 0; num && i < len; ++i) num = isdigit(lenv[i]);
+
+ if (num) {
+ len = (size_t) atoi(lenv) - 1;
+ if (len < 2 || len >= UINT16_MAX) len = BC_NUM_PRINT_WIDTH;
+ }
+ else len = BC_NUM_PRINT_WIDTH;
+
+ return len;
+}
+#endif // BC_ENABLE_LIBRARY
+
+void bc_vm_shutdown(void) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+#if BC_ENABLE_NLS
+ if (vm.catalog != BC_VM_INVALID_CATALOG) catclose(vm.catalog);
+#endif // BC_ENABLE_NLS
+
+#if BC_ENABLE_HISTORY
+ // This must always run to ensure that the terminal is back to normal.
+ if (BC_TTY) bc_history_free(&vm.history);
+#endif // BC_ENABLE_HISTORY
+
+#ifndef NDEBUG
+#if !BC_ENABLE_LIBRARY
+ bc_vec_free(&vm.env_args);
+ free(vm.env_args_buffer);
+ bc_vec_free(&vm.files);
+ bc_vec_free(&vm.exprs);
+
+ bc_program_free(&vm.prog);
+ bc_parse_free(&vm.prs);
+#endif // !BC_ENABLE_LIBRARY
+
+ bc_vm_freeTemps();
+ bc_vec_free(&vm.temps);
+#endif // NDEBUG
+
+#if !BC_ENABLE_LIBRARY
+ bc_file_free(&vm.fout);
+ bc_file_free(&vm.ferr);
+#endif // !BC_ENABLE_LIBRARY
+}
+
+#if !defined(NDEBUG) || BC_ENABLE_LIBRARY
+void bc_vm_freeTemps(void) {
+
+ size_t i;
+
+ for (i = 0; i < vm.temps.len; ++i) {
+ free(((BcNum*) bc_vec_item(&vm.temps, i))->num);
+ }
+}
+#endif // !defined(NDEBUG) || BC_ENABLE_LIBRARY
+
+inline size_t bc_vm_arraySize(size_t n, size_t size) {
+ size_t res = n * size;
+ if (BC_ERR(res >= SIZE_MAX || (n != 0 && res / n != size)))
+ bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
+ return res;
+}
+
+inline size_t bc_vm_growSize(size_t a, size_t b) {
+ size_t res = a + b;
+ if (BC_ERR(res >= SIZE_MAX || res < a || res < b))
+ bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
+ return res;
+}
+
+void* bc_vm_malloc(size_t n) {
+
+ void* ptr;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ ptr = malloc(n);
+
+ if (BC_ERR(ptr == NULL)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
+
+ return ptr;
+}
+
+void* bc_vm_realloc(void *ptr, size_t n) {
+
+ void* temp;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ temp = realloc(ptr, n);
+
+ if (BC_ERR(temp == NULL)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
+
+ return temp;
+}
+
+char* bc_vm_strdup(const char *str) {
+
+ char *s;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ s = strdup(str);
+
+ if (BC_ERR(!s)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
+
+ return s;
+}
+
+#if !BC_ENABLE_LIBRARY
+void bc_vm_printf(const char *fmt, ...) {
+
+ va_list args;
+
+ BC_SIG_LOCK;
+
+ va_start(args, fmt);
+ bc_file_vprintf(&vm.fout, fmt, args);
+ va_end(args);
+
+ vm.nchars = 0;
+
+ BC_SIG_UNLOCK;
+}
+#endif // !BC_ENABLE_LIBRARY
+
+void bc_vm_putchar(int c) {
+#if BC_ENABLE_LIBRARY
+ bc_vec_pushByte(&vm.out, (uchar) c);
+#else // BC_ENABLE_LIBRARY
+ bc_file_putchar(&vm.fout, (uchar) c);
+ vm.nchars = (c == '\n' ? 0 : vm.nchars + 1);
+#endif // BC_ENABLE_LIBRARY
+}
+
+#if !BC_ENABLE_LIBRARY
+static void bc_vm_clean(void) {
+
+ BcVec *fns = &vm.prog.fns;
+ BcFunc *f = bc_vec_item(fns, BC_PROG_MAIN);
+ BcInstPtr *ip = bc_vec_item(&vm.prog.stack, 0);
+ bool good = ((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig);
+
+ if (good) bc_program_reset(&vm.prog);
+
+#if BC_ENABLED
+ if (good && BC_IS_BC) good = !BC_PARSE_NO_EXEC(&vm.prs);
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+ if (BC_IS_DC) {
+
+ size_t i;
+
+ good = true;
+
+ for (i = 0; good && i < vm.prog.results.len; ++i) {
+ BcResult *r = (BcResult*) bc_vec_item(&vm.prog.results, i);
+ good = BC_VM_SAFE_RESULT(r);
+ }
+ }
+#endif // DC_ENABLED
+
+ // If this condition is true, we can get rid of strings,
+ // constants, and code. This is an idea from busybox.
+ if (good && vm.prog.stack.len == 1 && ip->idx == f->code.len) {
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+ bc_vec_npop(&f->labels, f->labels.len);
+ bc_vec_npop(&f->strs, f->strs.len);
+ bc_vec_npop(&f->consts, f->consts.len);
+ }
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+ // Note to self: you cannot delete strings and functions. Deal with it.
+ if (BC_IS_DC) bc_vec_npop(vm.prog.consts, vm.prog.consts->len);
+#endif // DC_ENABLED
+
+ bc_vec_npop(&f->code, f->code.len);
+
+ ip->idx = 0;
+ }
+}
+
+static void bc_vm_process(const char *text) {
+
+ bc_parse_text(&vm.prs, text);
+
+ do {
+
+#if BC_ENABLED
+ if (vm.prs.l.t == BC_LEX_KW_DEFINE) vm.parse(&vm.prs);
+#endif // BC_ENABLED
+
+ while (BC_PARSE_CAN_PARSE(vm.prs)) vm.parse(&vm.prs);
+
+ if(BC_IS_DC || !BC_PARSE_NO_EXEC(&vm.prs)) bc_program_exec(&vm.prog);
+
+ assert(BC_IS_DC || vm.prog.results.len == 0);
+
+ if (BC_I) bc_file_flush(&vm.fout);
+
+ } while (vm.prs.l.t != BC_LEX_EOF);
+}
+
+#if BC_ENABLED
+static void bc_vm_endif(void) {
+
+ size_t i;
+ bool good;
+
+ if (BC_NO_ERR(!BC_PARSE_NO_EXEC(&vm.prs))) return;
+
+ good = true;
+
+ for (i = 0; good && i < vm.prs.flags.len; ++i) {
+ uint16_t flag = *((uint16_t*) bc_vec_item(&vm.prs.flags, i));
+ good = ((flag & BC_PARSE_FLAG_BRACE) != BC_PARSE_FLAG_BRACE);
+ }
+
+ if (good) {
+ while (BC_PARSE_IF_END(&vm.prs)) bc_vm_process("else {}");
+ }
+ else bc_parse_err(&vm.prs, BC_ERR_PARSE_BLOCK);
+}
+#endif // BC_ENABLED
+
+static void bc_vm_file(const char *file) {
+
+ char *data = NULL;
+
+ assert(!vm.sig_pop);
+
+ bc_lex_file(&vm.prs.l, file);
+
+ BC_SIG_LOCK;
+
+ bc_read_file(file, &data);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ bc_vm_process(data);
+
+#if BC_ENABLED
+ if (BC_IS_BC) bc_vm_endif();
+#endif // BC_ENABLED
+
+err:
+ BC_SIG_MAYLOCK;
+
+ free(data);
+ bc_vm_clean();
+
+ // bc_program_reset(), called by bc_vm_clean(), resets the status.
+ // We want it to clear the sig_pop variable in case it was set.
+ if (vm.status == (sig_atomic_t) BC_STATUS_SUCCESS) BC_LONGJMP_STOP;
+
+ BC_LONGJMP_CONT;
+}
+
+static void bc_vm_stdin(void) {
+
+ BcStatus s;
+ BcVec buf, buffer;
+ size_t string = 0;
+ bool comment = false, hash = false;
+
+ bc_lex_file(&vm.prs.l, bc_program_stdin_name);
+
+ BC_SIG_LOCK;
+ bc_vec_init(&buffer, sizeof(uchar), NULL);
+ bc_vec_init(&buf, sizeof(uchar), NULL);
+ bc_vec_pushByte(&buffer, '\0');
+ BC_SETJMP_LOCKED(err);
+ BC_SIG_UNLOCK;
+
+restart:
+
+ // This loop is complex because the vm tries not to send any lines that end
+ // with a backslash to the parser. The reason for that is because the parser
+ // treats a backslash+newline combo as whitespace, per the bc spec. In that
+ // case, and for strings and comments, the parser will expect more stuff.
+ while ((!(s = bc_read_line(&buf, ">>> ")) ||
+ (vm.eof = (s == BC_STATUS_EOF))) && buf.len > 1)
+ {
+ char c2, *str = buf.v;
+ size_t i, len = buf.len - 1;
+
+ for (i = 0; i < len; ++i) {
+
+ bool notend = len > i + 1;
+ uchar c = (uchar) str[i];
+
+ hash = (!comment && !string && ((hash && c != '\n') ||
+ (!hash && c == '#')));
+
+ if (!hash && !comment && (i - 1 > len || str[i - 1] != '\\')) {
+ if (BC_IS_BC) string ^= (c == '"');
+ else if (c == ']') string -= 1;
+ else if (c == '[') string += 1;
+ }
+
+ if (BC_IS_BC && !hash && !string && notend) {
+
+ c2 = str[i + 1];
+
+ if (c == '/' && !comment && c2 == '*') {
+ comment = true;
+ i += 1;
+ }
+ else if (c == '*' && comment && c2 == '/') {
+ comment = false;
+ i += 1;
+ }
+ }
+ }
+
+ bc_vec_concat(&buffer, buf.v);
+
+ if (string || comment) continue;
+ if (len >= 2 && str[len - 2] == '\\' && str[len - 1] == '\n') continue;
+#if BC_ENABLE_HISTORY
+ if (vm.history.stdin_has_data) continue;
+#endif // BC_ENABLE_HISTORY
+
+ bc_vm_process(buffer.v);
+ bc_vec_empty(&buffer);
+
+ if (vm.eof) break;
+ else bc_vm_clean();
+ }
+
+ if (!BC_STATUS_IS_ERROR(s)) {
+ if (BC_ERR(comment))
+ bc_parse_err(&vm.prs, BC_ERR_PARSE_COMMENT);
+ else if (BC_ERR(string))
+ bc_parse_err(&vm.prs, BC_ERR_PARSE_STRING);
+#if BC_ENABLED
+ else if (BC_IS_BC) bc_vm_endif();
+#endif // BC_ENABLED
+ }
+
+err:
+ BC_SIG_MAYLOCK;
+
+ bc_vm_clean();
+
+ vm.status = vm.status == BC_STATUS_ERROR_FATAL ||
+ vm.status == BC_STATUS_QUIT || !BC_I ?
+ vm.status : BC_STATUS_SUCCESS;
+
+ if (!vm.status && !vm.eof) {
+ bc_vec_empty(&buffer);
+ BC_LONGJMP_STOP;
+ BC_SIG_UNLOCK;
+ goto restart;
+ }
+
+ bc_vec_free(&buf);
+ bc_vec_free(&buffer);
+
+ BC_LONGJMP_CONT;
+}
+
+#if BC_ENABLED
+static void bc_vm_load(const char *name, const char *text) {
+
+ bc_lex_file(&vm.prs.l, name);
+ bc_parse_text(&vm.prs, text);
+
+ while (vm.prs.l.t != BC_LEX_EOF) vm.parse(&vm.prs);
+}
+#endif // BC_ENABLED
+
+static void bc_vm_defaultMsgs(void) {
+
+ size_t i;
+
+ vm.func_header = bc_err_func_header;
+
+ for (i = 0; i < BC_ERR_IDX_NELEMS + BC_ENABLED; ++i)
+ vm.err_ids[i] = bc_errs[i];
+ for (i = 0; i < BC_ERR_NELEMS; ++i) vm.err_msgs[i] = bc_err_msgs[i];
+}
+
+static void bc_vm_gettext(void) {
+
+#if BC_ENABLE_NLS
+ uchar id = 0;
+ int set = 1, msg = 1;
+ size_t i;
+
+ if (vm.locale == NULL) {
+ vm.catalog = BC_VM_INVALID_CATALOG;
+ bc_vm_defaultMsgs();
+ return;
+ }
+
+ vm.catalog = catopen(BC_MAINEXEC, NL_CAT_LOCALE);
+
+ if (vm.catalog == BC_VM_INVALID_CATALOG) {
+ bc_vm_defaultMsgs();
+ return;
+ }
+
+ vm.func_header = catgets(vm.catalog, set, msg, bc_err_func_header);
+
+ for (set += 1; msg <= BC_ERR_IDX_NELEMS + BC_ENABLED; ++msg)
+ vm.err_ids[msg - 1] = catgets(vm.catalog, set, msg, bc_errs[msg - 1]);
+
+ i = 0;
+ id = bc_err_ids[i];
+
+ for (set = id + 3, msg = 1; i < BC_ERR_NELEMS; ++i, ++msg) {
+
+ if (id != bc_err_ids[i]) {
+ msg = 1;
+ id = bc_err_ids[i];
+ set = id + 3;
+ }
+
+ vm.err_msgs[i] = catgets(vm.catalog, set, msg, bc_err_msgs[i]);
+ }
+#else // BC_ENABLE_NLS
+ bc_vm_defaultMsgs();
+#endif // BC_ENABLE_NLS
+}
+
+static void bc_vm_exec(void) {
+
+ size_t i;
+ bool has_file = false;
+ BcVec buf;
+
+#if BC_ENABLED
+ if (BC_IS_BC && (vm.flags & BC_FLAG_L)) {
+
+ bc_vm_load(bc_lib_name, bc_lib);
+
+#if BC_ENABLE_EXTRA_MATH
+ if (!BC_IS_POSIX) bc_vm_load(bc_lib2_name, bc_lib2);
+#endif // BC_ENABLE_EXTRA_MATH
+ }
+#endif // BC_ENABLED
+
+ if (vm.exprs.len) {
+
+ size_t len = vm.exprs.len - 1;
+ bool more;
+
+ BC_SIG_LOCK;
+ bc_vec_init(&buf, sizeof(uchar), NULL);
+
+#ifndef NDEBUG
+ BC_SETJMP_LOCKED(err);
+#endif // NDEBUG
+
+ BC_SIG_UNLOCK;
+
+ bc_lex_file(&vm.prs.l, bc_program_exprs_name);
+
+ do {
+
+ more = bc_read_buf(&buf, vm.exprs.v, &len);
+ bc_vec_pushByte(&buf, '\0');
+ bc_vm_process(buf.v);
+
+ bc_vec_npop(&buf, buf.len);
+
+ } while (more);
+
+ BC_SIG_LOCK;
+ bc_vec_free(&buf);
+
+#ifndef NDEBUG
+ BC_UNSETJMP;
+#endif // NDEBUG
+
+ BC_SIG_UNLOCK;
+
+ if (!vm.no_exit_exprs) return;
+ }
+
+ for (i = 0; i < vm.files.len; ++i) {
+ char *path = *((char**) bc_vec_item(&vm.files, i));
+ if (!strcmp(path, "")) continue;
+ has_file = true;
+ bc_vm_file(path);
+ }
+
+ if (BC_IS_BC || !has_file) bc_vm_stdin();
+
+// These are all protected by ifndef NDEBUG because if these are needed, bc is
+// goingi to exit anyway, and I see no reason to include this code in a release
+// build when the OS is going to free all of the resources anyway.
+#ifndef NDEBUG
+ return;
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_vec_free(&buf);
+ BC_LONGJMP_CONT;
+#endif // NDEBUG
+}
+
+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;
+
+ ttyin = isatty(STDIN_FILENO);
+ ttyout = isatty(STDOUT_FILENO);
+ ttyerr = isatty(STDERR_FILENO);
+
+ vm.flags |= ttyin ? BC_FLAG_TTYIN : 0;
+ 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_init();
+
+ vm.file = NULL;
+
+ bc_vm_gettext();
+
+ bc_file_init(&vm.ferr, STDERR_FILENO, output_bufs + BC_VM_STDOUT_BUF_SIZE,
+ BC_VM_STDERR_BUF_SIZE);
+ bc_file_init(&vm.fout, STDOUT_FILENO, output_bufs, BC_VM_STDOUT_BUF_SIZE);
+ vm.buf = output_bufs + BC_VM_STDOUT_BUF_SIZE + BC_VM_STDERR_BUF_SIZE;
+
+ vm.line_len = (uint16_t) bc_vm_envLen(env_len);
+
+ bc_vec_clear(&vm.files);
+ bc_vec_clear(&vm.exprs);
+
+ bc_program_init(&vm.prog);
+ bc_parse_init(&vm.prs, &vm.prog, BC_PROG_MAIN);
+
+#if BC_ENABLE_HISTORY
+ if (BC_TTY) bc_history_init(&vm.history);
+#endif // BC_ENABLE_HISTORY
+
+#if BC_ENABLED
+ if (BC_IS_BC) vm.flags |= BC_FLAG_S * (getenv("POSIXLY_CORRECT") != NULL);
+#endif // BC_ENABLED
+
+ bc_vm_envArgs(env_args);
+ bc_args(argc, argv);
+
+#if BC_ENABLED
+ if (BC_IS_POSIX) vm.flags &= ~(BC_FLAG_G);
+#endif // BC_ENABLED
+
+ BC_SIG_UNLOCK;
+
+ bc_vm_exec();
+}
+#endif // !BC_ENABLE_LIBRARY
+
+void bc_vm_init(void) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ memcpy(vm.max_num, bc_num_bigdigMax,
+ bc_num_bigdigMax_size * sizeof(BcDig));
+ memcpy(vm.max2_num, bc_num_bigdigMax2,
+ bc_num_bigdigMax2_size * sizeof(BcDig));
+ bc_num_setup(&vm.max, vm.max_num, BC_NUM_BIGDIG_LOG10);
+ bc_num_setup(&vm.max2, vm.max2_num, BC_NUM_BIGDIG_LOG10);
+ vm.max.len = bc_num_bigdigMax_size;
+ vm.max2.len = bc_num_bigdigMax2_size;
+
+ bc_vec_init(&vm.temps, sizeof(BcNum), NULL);
+
+ vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_POSIX_IBASE;
+ vm.maxes[BC_PROG_GLOBALS_OBASE] = BC_MAX_OBASE;
+ vm.maxes[BC_PROG_GLOBALS_SCALE] = BC_MAX_SCALE;
+
+#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+ vm.maxes[BC_PROG_MAX_RAND] = ((BcRand) 0) - 1;
+#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
+
+#if BC_ENABLED
+#if !BC_ENABLE_LIBRARY
+ if (BC_IS_BC && !BC_IS_POSIX)
+#endif // !BC_ENABLE_LIBRARY
+ {
+ vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_IBASE;
+ }
+#endif // BC_ENABLED
+}
diff --git a/contrib/bc/tests/afl.py b/contrib/bc/tests/afl.py
new file mode 100755
index 000000000000..ff3b9229c1c2
--- /dev/null
+++ b/contrib/bc/tests/afl.py
@@ -0,0 +1,176 @@
+#! /usr/bin/python3 -B
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+import os
+import sys
+import shutil
+import subprocess
+
+def usage():
+ print("usage: {} [--asan] dir [results_dir [exe options...]]".format(script))
+ sys.exit(1)
+
+def check_crash(exebase, out, error, file, type, test):
+ if error < 0:
+ print("\n{} crashed ({}) on {}:\n".format(exebase, -error, type))
+ print(" {}".format(test))
+ print("\nCopying to \"{}\"".format(out))
+ shutil.copy2(file, out)
+ print("\nexiting...")
+ sys.exit(error)
+
+def run_test(cmd, exebase, tout, indata, out, file, type, test, environ=None):
+ try:
+ p = subprocess.run(cmd, timeout=tout, input=indata, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=environ)
+ check_crash(exebase, out, p.returncode, file, type, test)
+ except subprocess.TimeoutExpired:
+ print("\n {} timed out. Continuing...\n".format(exebase))
+
+def create_test(file, tout, environ=None):
+
+ print(" {}".format(file))
+
+ base = os.path.basename(file)
+
+ if base == "README.txt":
+ return
+
+ with open(file, "rb") as f:
+ lines = f.readlines()
+
+ print(" Running whole file...")
+
+ run_test(exe + [ file ], exebase, tout, halt.encode(), out, file, "file", file, environ)
+
+ print(" Running file through stdin...")
+
+ with open(file, "rb") as f:
+ content = f.read()
+
+ run_test(exe, exebase, tout, content, out, file,
+ "running {} through stdin".format(file), file, environ)
+
+
+def get_children(dir, get_files):
+ dirs = []
+ with os.scandir(dir) as it:
+ for entry in it:
+ if not entry.name.startswith('.') and \
+ ((entry.is_dir() and not get_files) or \
+ (entry.is_file() and get_files)):
+ dirs.append(entry.name)
+ dirs.sort()
+ return dirs
+
+script = sys.argv[0]
+testdir = os.path.dirname(script)
+
+if __name__ != "__main__":
+ usage()
+
+timeout = 2.5
+
+if len(sys.argv) < 2:
+ usage()
+
+idx = 1
+
+exedir = sys.argv[idx]
+
+asan = (exedir == "--asan")
+
+if asan:
+ idx += 1
+ if len(sys.argv) < idx + 1:
+ usage()
+ exedir = sys.argv[idx]
+
+if len(sys.argv) >= idx + 2:
+ resultsdir = sys.argv[idx + 1]
+else:
+ if exedir == "bc":
+ resultsdir = testdir + "/../../results"
+ else:
+ resultsdir = testdir + "/../../results_dc"
+
+if len(sys.argv) >= idx + 3:
+ exe = sys.argv[idx + 2]
+else:
+ exe = testdir + "/../bin/" + exedir
+
+exebase = os.path.basename(exe)
+
+if exebase == "bc":
+ halt = "halt\n"
+ options = "-lq"
+else:
+ halt = "q\n"
+ options = "-x"
+
+if len(sys.argv) >= idx + 4:
+ exe = [ exe, sys.argv[idx + 3:], options ]
+else:
+ exe = [ exe, options ]
+for i in range(4, len(sys.argv)):
+ exe.append(sys.argv[i])
+
+out = testdir + "/../.test.txt"
+
+print(os.path.realpath(os.getcwd()))
+
+dirs = get_children(resultsdir, False)
+
+if asan:
+ env = os.environ.copy()
+ env['ASAN_OPTIONS'] = 'abort_on_error=1:allocator_may_return_null=1'
+
+for d in dirs:
+
+ d = resultsdir + "/" + d
+
+ print(d)
+
+ files = get_children(d + "/crashes/", True)
+
+ for file in files:
+ file = d + "/crashes/" + file
+ create_test(file, timeout)
+
+ if not asan:
+ continue
+
+ files = get_children(d + "/queue/", True)
+
+ for file in files:
+ file = d + "/queue/" + file
+ create_test(file, timeout * 2, env)
+
+print("Done")
+
diff --git a/contrib/bc/tests/all.sh b/contrib/bc/tests/all.sh
new file mode 100755
index 000000000000..07fd346f04c5
--- /dev/null
+++ b/contrib/bc/tests/all.sh
@@ -0,0 +1,305 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+set -e
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../functions.sh"
+
+if [ "$#" -ge 1 ]; then
+ d="$1"
+ shift
+else
+ err_exit "usage: $script dir [run_extra_tests] [run_stack_tests] [gen_tests] [time_tests] [exec args...]" 1
+fi
+
+if [ "$#" -lt 1 ]; then
+ extra=1
+else
+ extra="$1"
+ shift
+fi
+
+if [ "$#" -lt 1 ]; then
+ run_stack_tests=1
+else
+ run_stack_tests="$1"
+ shift
+fi
+
+if [ "$#" -lt 1 ]; then
+ generate_tests=1
+else
+ generate_tests="$1"
+ shift
+fi
+
+if [ "$#" -lt 1 ]; then
+ time_tests=0
+else
+ time_tests="$1"
+ shift
+fi
+
+if [ "$#" -lt 1 ]; then
+ exe="$testdir/../bin/$d"
+else
+ exe="$1"
+ shift
+fi
+
+stars="***********************************************************************"
+printf '%s\n' "$stars"
+
+if [ "$d" = "bc" ]; then
+ halt="quit"
+else
+ halt="q"
+fi
+
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+printf '\nRunning %s tests...\n\n' "$d"
+
+while read t; do
+
+ if [ "$extra" -eq 0 ]; then
+ if [ "$t" = "trunc" ] || [ "$t" = "places" ] || [ "$t" = "shift" ] || \
+ [ "$t" = "lib2" ] || [ "$t" = "scientific" ] || [ "$t" = "rand" ] || \
+ [ "$t" = "engineering" ]
+ then
+ printf 'Skipping %s %s\n' "$d" "$t"
+ continue
+ fi
+ fi
+
+ sh "$testdir/test.sh" "$d" "$t" "$generate_tests" "$time_tests" "$exe" "$@"
+
+done < "$testdir/$d/all.txt"
+
+sh "$testdir/stdin.sh" "$d" "$exe" "$@"
+
+sh "$testdir/scripts.sh" "$d" "$extra" "$run_stack_tests" "$generate_tests" "$time_tests" "$exe" "$@"
+sh "$testdir/read.sh" "$d" "$exe" "$@"
+sh "$testdir/errors.sh" "$d" "$exe" "$@"
+
+num=100000000000000000000000000000000000000000000000000000000000000000000000000000
+numres="$num"
+num70="10000000000000000000000000000000000000000000000000000000000000000000\\
+0000000000"
+
+if [ "$d" = "bc" ]; then
+ halt="halt"
+ opt="x"
+ lopt="extended-register"
+ line_var="BC_LINE_LENGTH"
+else
+ halt="q"
+ opt="l"
+ lopt="mathlib"
+ line_var="DC_LINE_LENGTH"
+ num="$num pR"
+fi
+
+printf '\nRunning %s quit test...' "$d"
+
+printf '%s\n' "$halt" | "$exe" "$@" > /dev/null 2>&1
+
+if [ "$d" = bc ]; then
+ printf '%s\n' "quit" | "$exe" "$@" > /dev/null 2>&1
+ two=$("$exe" "$@" -e 1+1 -e quit)
+ if [ "$two" != "2" ]; then
+ err_exit "$d failed a quit test" 1
+ fi
+fi
+
+printf 'pass\n'
+
+base=$(basename "$exe")
+
+if [ "$base" != "bc" -a "$base" != "dc" ]; then
+ exit 0
+fi
+
+printf 'Running %s environment var tests...' "$d"
+
+if [ "$d" = "bc" ]; then
+ export BC_ENV_ARGS=" '-l' '' -q"
+ export BC_EXPR_EXIT="1"
+ printf 's(.02893)\n' | "$exe" "$@" > /dev/null
+ "$exe" -e 4 "$@" > /dev/null
+else
+ export DC_ENV_ARGS="'-x'"
+ export DC_EXPR_EXIT="1"
+ printf '4s stuff\n' | "$exe" "$@" > /dev/null
+ "$exe" -e 4pR "$@" > /dev/null
+fi
+
+printf 'pass\n'
+
+out1="$testdir/../.log_$d.txt"
+out2="$testdir/../.log_${d}_test.txt"
+
+printf 'Running %s line length tests...' "$d"
+
+printf '%s\n' "$numres" > "$out1"
+
+export "$line_var"=80
+printf '%s\n' "$num" | "$exe" "$@" > "$out2"
+
+diff "$out1" "$out2"
+
+printf '%s\n' "$num70" > "$out1"
+
+export "$line_var"=2147483647
+printf '%s\n' "$num" | "$exe" "$@" > "$out2"
+
+diff "$out1" "$out2"
+
+printf 'pass\n'
+
+printf 'Running %s arg tests...' "$d"
+
+f="$testdir/$d/add.txt"
+exprs=$(cat "$f")
+results=$(cat "$testdir/$d/add_results.txt")
+
+printf '%s\n%s\n%s\n%s\n' "$results" "$results" "$results" "$results" > "$out1"
+
+"$exe" "$@" -e "$exprs" -f "$f" --expression "$exprs" --file "$f" -e "$halt" > "$out2"
+
+diff "$out1" "$out2"
+
+printf '%s\n' "$halt" | "$exe" "$@" -- "$f" "$f" "$f" "$f" > "$out2"
+
+diff "$out1" "$out2"
+
+if [ "$d" = "bc" ]; then
+ printf '%s\n' "$halt" | "$exe" "$@" -i > /dev/null 2>&1
+fi
+
+printf '%s\n' "$halt" | "$exe" "$@" -h > /dev/null
+printf '%s\n' "$halt" | "$exe" "$@" -P > /dev/null
+printf '%s\n' "$halt" | "$exe" "$@" -v > /dev/null
+printf '%s\n' "$halt" | "$exe" "$@" -V > /dev/null
+
+set +e
+
+"$exe" "$@" -f "saotehasotnehasthistohntnsahxstnhalcrgxgrlpyasxtsaosysxsatnhoy.txt" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "invalid file argument" "$out2" "$d"
+
+"$exe" "$@" "-$opt" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "invalid option argument" "$out2" "$d"
+
+"$exe" "$@" "--$lopt" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "invalid long option argument" "$out2" "$d"
+
+"$exe" "$@" "-u" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "unrecognized option argument" "$out2" "$d"
+
+"$exe" "$@" "--uniform" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "unrecognized long option argument" "$out2" "$d"
+
+"$exe" "$@" -f > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "missing required argument to short option" "$out2" "$d"
+
+"$exe" "$@" --file > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "missing required argument to long option" "$out2" "$d"
+
+"$exe" "$@" --version=5 > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "given argument to long option with no argument" "$out2" "$d"
+
+printf 'pass\n'
+
+printf 'Running %s directory test...' "$d"
+
+"$exe" "$@" "$testdir" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "directory" "$out2" "$d"
+
+printf 'pass\n'
+
+printf 'Running %s binary file test...' "$d"
+
+bin="/bin/sh"
+
+"$exe" "$@" "$bin" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "binary file" "$out2" "$d"
+
+printf 'pass\n'
+
+printf 'Running %s binary stdin test...' "$d"
+
+cat "$bin" | "$exe" "$@" > /dev/null 2> "$out2"
+err="$?"
+
+checktest "$d" "$err" "binary stdin" "$out2" "$d"
+
+printf 'pass\n'
+
+if [ "$d" = "bc" ]; then
+
+ printf 'Running %s limits tests...' "$d"
+ printf 'limits\n' | "$exe" "$@" > "$out2" /dev/null 2>&1
+
+ if [ ! -s "$out2" ]; then
+ err_exit "$d did not produce output on the limits test" 1
+ fi
+
+ printf 'pass\n'
+
+fi
+
+printf '\nAll %s tests passed.\n' "$d"
+
+printf '\n%s\n' "$stars"
diff --git a/contrib/bc/tests/all.txt b/contrib/bc/tests/all.txt
new file mode 100644
index 000000000000..e3c025217c4b
--- /dev/null
+++ b/contrib/bc/tests/all.txt
@@ -0,0 +1,2 @@
+bc
+dc
diff --git a/contrib/bc/tests/bc/abs.txt b/contrib/bc/tests/bc/abs.txt
new file mode 100644
index 000000000000..ffb7aba65c3b
--- /dev/null
+++ b/contrib/bc/tests/bc/abs.txt
@@ -0,0 +1,7 @@
+abs(0)
+abs(1)
+abs(.289365)
+abs(289.82937658)
+abs(-19)
+abs(-.2098180)
+abs(-198289.1098376)
diff --git a/contrib/bc/tests/bc/abs_results.txt b/contrib/bc/tests/bc/abs_results.txt
new file mode 100644
index 000000000000..8d2658a2737e
--- /dev/null
+++ b/contrib/bc/tests/bc/abs_results.txt
@@ -0,0 +1,7 @@
+0
+1
+.289365
+289.82937658
+19
+.2098180
+198289.1098376
diff --git a/contrib/bc/tests/bc/add.txt b/contrib/bc/tests/bc/add.txt
new file mode 100644
index 000000000000..647781732c63
--- /dev/null
+++ b/contrib/bc/tests/bc/add.txt
@@ -0,0 +1,146 @@
+0 + 0
+0 + 1
+1 + 1
+1 + 0
+2 + 5
+237 + 483
+999 + 999
+2374623 + 324869356734856
+2378639084586723980562 + 23468729367839
+37298367203972395108367910823465293084561329084561390845613409516734503870691837451 + 785621394067928346918023476190834672198467134908618723249671349062187346898241093486139046139084613490817356023871869102746182749061872609129847
+1.1 + 0
+0 + 1.1
+457283.731284923576 + 37842934672834.3874629385672354
+1.0 + 0.1
+3746289134067138046 + 0.138375863945672398456712389456273486293
+-1 + -1
+-4 + -15
+-1346782 + -1287904651762468913476
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995 + 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999899999999999999999999999999999999999999999999999999999999999999 + 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+99999999999999999999999999999999999989999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+-1889985797 + 2012747315
+0 + -14338.391079082
+-2422297 + 1.3134942556
+182039471029834 + 282039471029834
+282039471029834 + 182039471029834
+182039471029834.2801722893 + 282039471029834
+282039471029834.2801722893 + 182039471029834
+182039471029834.2801722893 + 282039471029834.2838
+282039471029834.2801722893 + 182039471029834.2838
+182039471029834 + 282039471029834.2801722893
+282039471029834 + 182039471029834.2801722893
+182039471029834.8297282893 + 282039471029834.2801722893
+282039471029834.8297282893 + 182039471029834.2801722893
+471029834 + 282039471029834
+471029834 + 182039471029834
+471029834.2801722893 + 282039471029834
+471029834.2801722893 + 182039471029834
+471029834.2801722893 + 282039471029834.2838
+471029834.2801722893 + 182039471029834.2838
+471029834 + 282039471029834.2801722893
+471029834 + 182039471029834.2801722893
+471029834.8297282893 + 282039471029834.2801722893
+471029834.8297282893 + 182039471029834.2801722893
+182039471029834 + 471029834
+282039471029834 + 471029834
+182039471029834.2801722893 + 471029834
+282039471029834.2801722893 + 471029834
+182039471029834.2801722893 + 471029834.2838
+282039471029834.2801722893 + 471029834.2838
+182039471029834 + 471029834.2801722893
+282039471029834 + 471029834.2801722893
+182039471029834.8297282893 + 471029834.2801722893
+282039471029834.8297282893 + 471029834.2801722893
+-182039471029834 + 282039471029834
+-282039471029834 + 182039471029834
+-182039471029834.2801722893 + 282039471029834
+-282039471029834.2801722893 + 182039471029834
+-182039471029834.2801722893 + 282039471029834.2838
+-282039471029834.2801722893 + 182039471029834.2838
+-182039471029834 + 282039471029834.2801722893
+-282039471029834 + 182039471029834.2801722893
+-182039471029834.8297282893 + 282039471029834.2801722893
+-282039471029834.8297282893 + 182039471029834.2801722893
+-471029834 + 282039471029834
+-471029834 + 182039471029834
+-471029834.2801722893 + 282039471029834
+-471029834.2801722893 + 182039471029834
+-471029834.2801722893 + 282039471029834.2838
+-471029834.2801722893 + 182039471029834.2838
+-471029834 + 282039471029834.2801722893
+-471029834 + 182039471029834.2801722893
+-471029834.8297282893 + 282039471029834.2801722893
+-471029834.8297282893 + 182039471029834.2801722893
+-182039471029834 + 471029834
+-282039471029834 + 471029834
+-182039471029834.2801722893 + 471029834
+-282039471029834.2801722893 + 471029834
+-182039471029834.2801722893 + 471029834.2838
+-282039471029834.2801722893 + 471029834.2838
+-182039471029834 + 471029834.2801722893
+-282039471029834 + 471029834.2801722893
+-182039471029834.8297282893 + 471029834.2801722893
+-282039471029834.8297282893 + 471029834.2801722893
+182039471029834 + -282039471029834
+282039471029834 + -182039471029834
+182039471029834.2801722893 + -282039471029834
+282039471029834.2801722893 + -182039471029834
+182039471029834.2801722893 + -282039471029834.2838
+282039471029834.2801722893 + -182039471029834.2838
+182039471029834 + -282039471029834.2801722893
+282039471029834 + -182039471029834.2801722893
+182039471029834.8297282893 + -282039471029834.2801722893
+282039471029834.8297282893 + -182039471029834.2801722893
+471029834 + -282039471029834
+471029834 + -182039471029834
+471029834.2801722893 + -282039471029834
+471029834.2801722893 + -182039471029834
+471029834.2801722893 + -282039471029834.2838
+471029834.2801722893 + -182039471029834.2838
+471029834 + -282039471029834.2801722893
+471029834 + -182039471029834.2801722893
+471029834.8297282893 + -282039471029834.2801722893
+471029834.8297282893 + -182039471029834.2801722893
+182039471029834 + -471029834
+282039471029834 + -471029834
+182039471029834.2801722893 + -471029834
+282039471029834.2801722893 + -471029834
+182039471029834.2801722893 + -471029834.2838
+282039471029834.2801722893 + -471029834.2838
+182039471029834 + -471029834.2801722893
+282039471029834 + -471029834.2801722893
+182039471029834.8297282893 + -471029834.2801722893
+282039471029834.8297282893 + -471029834.2801722893
+-182039471029834 + -282039471029834
+-282039471029834 + -182039471029834
+-182039471029834.2801722893 + -282039471029834
+-282039471029834.2801722893 + -182039471029834
+-182039471029834.2801722893 + -282039471029834.2838
+-282039471029834.2801722893 + -182039471029834.2838
+-182039471029834 + -282039471029834.2801722893
+-282039471029834 + -182039471029834.2801722893
+-182039471029834.8297282893 + -282039471029834.2801722893
+-282039471029834.8297282893 + -182039471029834.2801722893
+-471029834 + -282039471029834
+-471029834 + -182039471029834
+-471029834.2801722893 + -282039471029834
+-471029834.2801722893 + -182039471029834
+-471029834.2801722893 + -282039471029834.2838
+-471029834.2801722893 + -182039471029834.2838
+-471029834 + -282039471029834.2801722893
+-471029834 + -182039471029834.2801722893
+-471029834.8297282893 + -282039471029834.2801722893
+-471029834.8297282893 + -182039471029834.2801722893
+-182039471029834 + -471029834
+-282039471029834 + -471029834
+-182039471029834.2801722893 + -471029834
+-282039471029834.2801722893 + -471029834
+-182039471029834.2801722893 + -471029834.2838
+-282039471029834.2801722893 + -471029834.2838
+-182039471029834 + -471029834.2801722893
+-282039471029834 + -471029834.2801722893
+-182039471029834.8297282893 + -471029834.2801722893
+-282039471029834.8297282893 + -471029834.2801722893
diff --git a/contrib/bc/tests/bc/add_results.txt b/contrib/bc/tests/bc/add_results.txt
new file mode 100644
index 000000000000..020969b4ea3d
--- /dev/null
+++ b/contrib/bc/tests/bc/add_results.txt
@@ -0,0 +1,158 @@
+0
+1
+2
+1
+7
+720
+1998
+324869359109479
+2378639108055453348401
+78562139406792834691802347619083467219846713490861872324967138636055\
+45508706362018540498696043776980521464405852627147161556994835657433\
+00967298
+1.1
+1.1
+37842935130118.1187478621432354
+1.1
+3746289134067138046.138375863945672398456712389456273486293
+-2
+-19
+-1287904651762470260258
+100000000000000000000000000000000000000000000000000000000000.0000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+000000000000000000000000000000000000000000000
+100000000000000000000000000000000000000000000000000000000000.0000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+000000000000000000000000000000000000000000000
+100000000000000000000000000000000000000000000000000000000000.0000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+000000000000000000000000000000000000000009999
+99999999999999999999999999999999999999999999999999999999999.99999999\
+99999999999999999999999999999999999999999999999999000000000000000000\
+00000000000000000000000000000000000000009999
+99999999999999999999999999999999999990000000000000000000000.00000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+00000000000000000000000000000000000000009999
+122761518
+-14338.391079082
+-2422295.6865057444
+464078942059668
+464078942059668
+464078942059668.2801722893
+464078942059668.2801722893
+464078942059668.5639722893
+464078942059668.5639722893
+464078942059668.2801722893
+464078942059668.2801722893
+464078942059669.1099005786
+464078942059669.1099005786
+282039942059668
+182039942059668
+282039942059668.2801722893
+182039942059668.2801722893
+282039942059668.5639722893
+182039942059668.5639722893
+282039942059668.2801722893
+182039942059668.2801722893
+282039942059669.1099005786
+182039942059669.1099005786
+182039942059668
+282039942059668
+182039942059668.2801722893
+282039942059668.2801722893
+182039942059668.5639722893
+282039942059668.5639722893
+182039942059668.2801722893
+282039942059668.2801722893
+182039942059669.1099005786
+282039942059669.1099005786
+100000000000000
+-100000000000000
+99999999999999.7198277107
+-100000000000000.2801722893
+100000000000000.0036277107
+-99999999999999.9963722893
+100000000000000.2801722893
+-99999999999999.7198277107
+99999999999999.4504440000
+-100000000000000.5495560000
+282039000000000
+182039000000000
+282038999999999.7198277107
+182038999999999.7198277107
+282039000000000.0036277107
+182039000000000.0036277107
+282039000000000.2801722893
+182039000000000.2801722893
+282038999999999.4504440000
+182038999999999.4504440000
+-182039000000000
+-282039000000000
+-182039000000000.2801722893
+-282039000000000.2801722893
+-182038999999999.9963722893
+-282038999999999.9963722893
+-182038999999999.7198277107
+-282038999999999.7198277107
+-182039000000000.5495560000
+-282039000000000.5495560000
+-100000000000000
+100000000000000
+-99999999999999.7198277107
+100000000000000.2801722893
+-100000000000000.0036277107
+99999999999999.9963722893
+-100000000000000.2801722893
+99999999999999.7198277107
+-99999999999999.4504440000
+100000000000000.5495560000
+-282039000000000
+-182039000000000
+-282038999999999.7198277107
+-182038999999999.7198277107
+-282039000000000.0036277107
+-182039000000000.0036277107
+-282039000000000.2801722893
+-182039000000000.2801722893
+-282038999999999.4504440000
+-182038999999999.4504440000
+182039000000000
+282039000000000
+182039000000000.2801722893
+282039000000000.2801722893
+182038999999999.9963722893
+282038999999999.9963722893
+182038999999999.7198277107
+282038999999999.7198277107
+182039000000000.5495560000
+282039000000000.5495560000
+-464078942059668
+-464078942059668
+-464078942059668.2801722893
+-464078942059668.2801722893
+-464078942059668.5639722893
+-464078942059668.5639722893
+-464078942059668.2801722893
+-464078942059668.2801722893
+-464078942059669.1099005786
+-464078942059669.1099005786
+-282039942059668
+-182039942059668
+-282039942059668.2801722893
+-182039942059668.2801722893
+-282039942059668.5639722893
+-182039942059668.5639722893
+-282039942059668.2801722893
+-182039942059668.2801722893
+-282039942059669.1099005786
+-182039942059669.1099005786
+-182039942059668
+-282039942059668
+-182039942059668.2801722893
+-282039942059668.2801722893
+-182039942059668.5639722893
+-282039942059668.5639722893
+-182039942059668.2801722893
+-282039942059668.2801722893
+-182039942059669.1099005786
+-282039942059669.1099005786
diff --git a/contrib/bc/tests/bc/all.txt b/contrib/bc/tests/bc/all.txt
new file mode 100644
index 000000000000..b623e8a11b71
--- /dev/null
+++ b/contrib/bc/tests/bc/all.txt
@@ -0,0 +1,46 @@
+decimal
+length
+scale
+shift
+add
+subtract
+multiply
+divide
+modulus
+power
+sqrt
+trunc
+places
+vars
+boolean
+comp
+abs
+assignments
+functions
+scientific
+engineering
+globals
+strings
+letters
+print
+print2
+parse
+exponent
+log
+pi
+arctangent
+sine
+cosine
+bessel
+arrays
+misc
+misc1
+misc2
+misc3
+misc4
+misc5
+misc6
+misc7
+void
+rand
+lib2
diff --git a/contrib/bc/tests/bc/arctangent.txt b/contrib/bc/tests/bc/arctangent.txt
new file mode 100644
index 000000000000..ebaa0e8c10a5
--- /dev/null
+++ b/contrib/bc/tests/bc/arctangent.txt
@@ -0,0 +1,27 @@
+a(.267)
+a(1)
+scale = 64
+a(.267)
+a(1)
+scale = 100
+a(.267)
+a(1)
+scale = 20
+a(0)
+a(.5)
+a(0.577350269189625764509148780501)
+a(1.5)
+a(1.7320508075688772935274463415)
+a(2)
+a(3)
+a(1000)
+a(-.5)
+a(-0.577350269189625764509148780501)
+a(-1.5)
+a(-1.7320508075688772935274463415)
+a(-2)
+a(-3)
+a(-1000)
+a(-3249917614.2821897119)
+a(-694706362.1974670468)
+scale = 22; a(-816494969)
diff --git a/contrib/bc/tests/bc/arctangent_results.txt b/contrib/bc/tests/bc/arctangent_results.txt
new file mode 100644
index 000000000000..31a6ba8cf27d
--- /dev/null
+++ b/contrib/bc/tests/bc/arctangent_results.txt
@@ -0,0 +1,26 @@
+.26091356923294057959
+.78539816339744830961
+.2609135692329405795967852677779865639774740239882445822329882917
+.7853981633974483096156608458198757210492923498437764552437361480
+.2609135692329405795967852677779865639774740239882445822329882917230\
+650591934644905491823044536954978
+.7853981633974483096156608458198757210492923498437764552437361480769\
+541015715522496570087063355292669
+0
+.46364760900080611621
+.52359877559829887307
+.98279372324732906798
+1.04719755119659774615
+1.10714871779409050301
+1.24904577239825442582
+1.56979632712822975256
+-.46364760900080611621
+-.52359877559829887307
+-.98279372324732906798
+-1.04719755119659774615
+-1.10714871779409050301
+-1.24904577239825442582
+-1.56979632712822975256
+-1.57079632648719651151
+-1.57079632535543952711
+-1.5707963255701493299433
diff --git a/contrib/bc/tests/bc/arrays.txt b/contrib/bc/tests/bc/arrays.txt
new file mode 100644
index 000000000000..26a284b8d814
--- /dev/null
+++ b/contrib/bc/tests/bc/arrays.txt
@@ -0,0 +1,10 @@
+a[0] = 1
+a[2-1] = 2
+
+a[0]+a[0]
+
+a[2-1]+a[2-1]
+
+a[5] = 2
+a[5.789]
+
diff --git a/contrib/bc/tests/bc/arrays_results.txt b/contrib/bc/tests/bc/arrays_results.txt
new file mode 100644
index 000000000000..200035ffa0a0
--- /dev/null
+++ b/contrib/bc/tests/bc/arrays_results.txt
@@ -0,0 +1,3 @@
+2
+4
+2
diff --git a/contrib/bc/tests/bc/assignments.txt b/contrib/bc/tests/bc/assignments.txt
new file mode 100644
index 000000000000..6a776e7840ec
--- /dev/null
+++ b/contrib/bc/tests/bc/assignments.txt
@@ -0,0 +1,122 @@
+define x(x) {
+ return (i++ + x)
+}
+define y(x) {
+ return (++i + x)
+}
+define z(x) {
+ return (i *= 2) + x
+}
+
+i++
+i--
+++i
+--i
+
+(i++)
+(i--)
+(++i)
+(--i)
+
+i += 1
+i
+i -= -4
+i
+i *= 5
+i
+i /= 12.5
+i
+
+i = 0
+
+(i += 1)
+(i -= -4)
+(i *= 5)
+(i /= 12.5)
+
+i = 0
+
+a[i++] += ++i
+i--
+i--
+i
+a[i]
+
+a[i]++
+a[i]--
+++a[i]
+--a[i]
+
+i += 4
+i
+
+sqrt(i *= 4)
+i
+length(i /= 2)
+i
+
+i = 4
+scale(i /= 2)
+i
+
+i = -1
+
+abs(i--)
+abs(--i)
+abs(++i)
+abs(i++)
+
+i = -i
+
+a = 4
+
+x(a)
+i
+
+x(a *= 5)
+a
+i
+
+a = 4
+
+y(a)
+i
+
+y(a -= 2)
+a
+i
+
+a = 4
+
+z(a)
+i
+
+z(a /= 0.5)
+a
+i
+
+i = 1
+
+if (i -= 1) print "true\n"
+else print "false\n"
+
+if (i += 1) print "true\n"
+else print "false\n"
+
+i = 3
+
+while (i -= 2) print "i: ", i += 1, "\n"
+
+a = 5
+
+for (i = 5; i-= 1; --a) print "i: ", i, "; a: ", a, "\n"
+
+define void t(x, y) {
+ print "x: ", x, "; y: ", y, "\n"
+}
+
+t(i++, i++)
+i
+
+t(++i, ++i)
+i
diff --git a/contrib/bc/tests/bc/assignments_results.txt b/contrib/bc/tests/bc/assignments_results.txt
new file mode 100644
index 000000000000..d9e4e5ea33c9
--- /dev/null
+++ b/contrib/bc/tests/bc/assignments_results.txt
@@ -0,0 +1,61 @@
+0
+1
+1
+0
+0
+1
+1
+0
+1
+5
+25
+2.00000000000000000000
+1
+5
+25
+2.00000000000000000000
+2
+1
+0
+2
+2
+3
+3
+2
+4
+4.00000000000000000000
+16
+21
+8.00000000000000000000
+20
+2.00000000000000000000
+1
+3
+2
+2
+5
+2
+22
+20
+3
+8
+4
+7
+2
+5
+14
+10
+28.00000000000000000000
+8.00000000000000000000
+20
+false
+true
+i: 2
+i: 4; a: 5
+i: 3; a: 4
+i: 2; a: 3
+i: 1; a: 2
+x: 0; y: 1
+2
+x: 3; y: 4
+4
diff --git a/contrib/bc/tests/bc/boolean.txt b/contrib/bc/tests/bc/boolean.txt
new file mode 100644
index 000000000000..e26ded34bd1d
--- /dev/null
+++ b/contrib/bc/tests/bc/boolean.txt
@@ -0,0 +1,184 @@
+!0
+!1
+!(-129)
+4 && 5
+4 && 0
+0 && 5
+4 && 5 && 7
+4 && 0 && 7
+0 && 5 && 7
+4 && 5 && 0
+0 && 0 && 7
+4 && 0 && 0
+0 && 5 && 0
+!4 && 5
+!4 && 0
+!0 && 5
+4 && !5
+4 && !0
+0 && !5
+!4 && 5 && 7
+!4 && 0 && 7
+!0 && 5 && 7
+!4 && 5 && 0
+!0 && 0 && 7
+!4 && 0 && 0
+!0 && 5 && 0
+4 && !5 && 7
+4 && !0 && 7
+0 && !5 && 7
+4 && !5 && 0
+0 && !0 && 7
+4 && !0 && 0
+0 && !5 && 0
+4 && 5 && !7
+4 && 0 && !7
+0 && 5 && !7
+4 && 5 && !0
+0 && 0 && !7
+4 && 0 && !0
+0 && 5 && !0
+!4 && !5 && 7
+!4 && !0 && 7
+!0 && !5 && 7
+!4 && !5 && 0
+!0 && !0 && 7
+!4 && !0 && 0
+!0 && !5 && 0
+!4 && 5 && !7
+!4 && 0 && !7
+!0 && 5 && !7
+!4 && 5 && !0
+!0 && 0 && !7
+!4 && 0 && !0
+!0 && 5 && !0
+4 && !5 && !7
+4 && !0 && !7
+0 && !5 && !7
+4 && !5 && !0
+0 && !0 && !7
+4 && !0 && !0
+0 && !5 && !0
+!4 && !5 && !7
+!4 && !0 && !7
+!0 && !5 && !7
+!4 && !5 && !0
+!0 && !0 && !7
+!4 && !0 && !0
+!0 && !5 && !0
+3 < 4 && 7
+3 && 4 >= 4
+3 > 4 && 7
+3 && 4 >= 5
+3 < 4 && 0
+0 && 4 >= 4
+3 > 4 && 0
+0 && 4 >= 5
+3 > 4 && 0
+0 && 4 < 4
+3 >= 4 && 0
+0 && 4 >= 5
+3 < 4 && 7
+3 && 4 >= 4
+3 > 4 && 7 > 4
+3 >= 2 && 4 >= 5
+3 < 4 && 0 > -1
+4 < 3 && 4 >= 4
+3 > 4 && 3 == 3
+3 != 3 && 4 >= 5
+3 > 4 && 0 > 1
+0 >= 0 && 4 < 4
+3 >= 4 && 0 >= 1
+0 <= -1 && 4 >= 5
+4 || 5
+4 || 0
+0 || 5
+4 || 5 || 7
+4 || 0 || 7
+0 || 5 || 7
+4 || 5 || 0
+0 || 0 || 7
+4 || 0 || 0
+0 || 5 || 0
+!4 || 5
+!4 || 0
+!0 || 5
+4 || !5
+4 || !0
+0 || !5
+!4 || 5 || 7
+!4 || 0 || 7
+!0 || 5 || 7
+!4 || 5 || 0
+!0 || 0 || 7
+!4 || 0 || 0
+!0 || 5 || 0
+4 || !5 || 7
+4 || !0 || 7
+0 || !5 || 7
+4 || !5 || 0
+0 || !0 || 7
+4 || !0 || 0
+0 || !5 || 0
+4 || 5 || !7
+4 || 0 || !7
+0 || 5 || !7
+4 || 5 || !0
+0 || 0 || !7
+4 || 0 || !0
+0 || 5 || !0
+!4 || !5 || 7
+!4 || !0 || 7
+!0 || !5 || 7
+!4 || !5 || 0
+!0 || !0 || 7
+!4 || !0 || 0
+!0 || !5 || 0
+!4 || 5 || !7
+!4 || 0 || !7
+!0 || 5 || !7
+!4 || 5 || !0
+!0 || 0 || !7
+!4 || 0 || !0
+!0 || 5 || !0
+4 || !5 || !7
+4 || !0 || !7
+0 || !5 || !7
+4 || !5 || !0
+0 || !0 || !7
+4 || !0 || !0
+0 || !5 || !0
+!4 || !5 || !7
+!4 || !0 || !7
+!0 || !5 || !7
+!4 || !5 || !0
+!0 || !0 || !7
+!4 || !0 || !0
+!0 || !5 || !0
+3 < 4 || 7
+3 || 4 >= 4
+3 > 4 || 7
+3 || 4 >= 5
+3 < 4 || 0
+0 || 4 >= 4
+3 > 4 || 0
+0 || 4 >= 5
+3 > 4 || 0
+0 || 4 < 4
+3 >= 4 || 0
+0 || 4 >= 5
+3 < 4 || 7
+3 || 4 >= 4
+3 > 4 || 7 > 4
+3 >= 2 || 4 >= 5
+3 < 4 || 0 > -1
+4 < 3 || 4 >= 4
+3 > 4 || 3 == 3
+3 != 3 || 4 >= 5
+3 > 4 || 0 > 1
+0 >= 0 || 4 < 4
+3 >= 4 || 0 >= 1
+0 <= -1 || 4 >= 5
+1 <= 0 && 1 <= 2 || 1 >= 0 && 1 == 2
+1 <= 0 && 1 <= 2 || 1 >= 0 && 1 != 2
+1 >= 0 && 1 <= 2 || 1 >= 0 && 1 == 2
diff --git a/contrib/bc/tests/bc/boolean_results.txt b/contrib/bc/tests/bc/boolean_results.txt
new file mode 100644
index 000000000000..1c15dc7029ca
--- /dev/null
+++ b/contrib/bc/tests/bc/boolean_results.txt
@@ -0,0 +1,184 @@
+1
+0
+0
+1
+0
+0
+1
+0
+0
+0
+0
+0
+0
+0
+0
+1
+0
+1
+0
+0
+0
+1
+0
+0
+0
+0
+0
+1
+0
+0
+0
+0
+0
+0
+0
+0
+1
+0
+0
+0
+0
+0
+0
+0
+1
+0
+0
+0
+0
+0
+0
+0
+0
+1
+0
+0
+0
+0
+0
+1
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+0
+0
+1
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+1
+1
+1
+0
+1
+1
+1
+1
+1
+0
+1
+1
+1
+1
+1
+1
+1
+0
+1
+1
+1
+1
+0
+1
+1
+1
+1
+1
+0
+1
+1
+1
+1
+0
+1
+1
+1
+1
+1
+1
+1
+0
+1
+1
+1
+1
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+0
+0
+1
+0
+0
+0
+1
+1
diff --git a/contrib/bc/tests/bc/comp.txt b/contrib/bc/tests/bc/comp.txt
new file mode 100644
index 000000000000..73aa4508f345
--- /dev/null
+++ b/contrib/bc/tests/bc/comp.txt
@@ -0,0 +1,132 @@
+-999999999 < -1
+-999999999 > -1
+-1000000000 < -1
+-1000000000 > -1
+-1 < -999999999
+-1 > -999999999
+-1 < -1000000000
+-1 > -1000000000
+-99999 < -1
+-99999 > -1
+-100000 < -1
+-100000 > -1
+-1 < -99999
+-1 > -99999
+-1 < -100000
+-1 > -100000
+-999999999 < -1000000000
+-999999999 > -1000000000
+-1000000000 < -999999999
+-1000000000 > -999999999
+-99999 < -100000
+-99999 > -100000
+-100000 < -99999
+-100000 > -99999
+999999999 < 1
+999999999 > 1
+1000000000 < 1
+1000000000 > 1
+1 < 999999999
+1 > 999999999
+1 < 1000000000
+1 > 1000000000
+99999 < 1
+99999 > 1
+100000 < 1
+100000 > 1
+1 < 99999
+1 > 99999
+1 < 100000
+1 > 100000
+999999999 < 1000000000
+999999999 > 1000000000
+1000000000 < 999999999
+1000000000 > 999999999
+99999 < 100000
+99999 > 100000
+100000 < 99999
+100000 > 99999
+-999999999 < 1
+-999999999 > 1
+-1000000000 < 1
+-1000000000 > 1
+-1 < 999999999
+-1 > 999999999
+-1 < 1000000000
+-1 > 1000000000
+-99999 < 1
+-99999 > 1
+-100000 < 1
+-100000 > 1
+-1 < 99999
+-1 > 99999
+-1 < 100000
+-1 > 100000
+-999999999 < 1000000000
+-999999999 > 1000000000
+-1000000000 < 999999999
+-1000000000 > 999999999
+-99999 < 100000
+-99999 > 100000
+-100000 < 99999
+-100000 > 99999
+999999999 < -1
+999999999 > -1
+1000000000 < -1
+1000000000 > -1
+1 < -999999999
+1 > -999999999
+1 < -1000000000
+1 > -1000000000
+99999 < -1
+99999 > -1
+100000 < -1
+100000 > -1
+1 < -99999
+1 > -99999
+1 < -100000
+1 > -100000
+999999999 < -1000000000
+999999999 > -1000000000
+1000000000 < -999999999
+1000000000 > -999999999
+99999 < -100000
+99999 > -100000
+100000 < -99999
+100000 > -99999
+v = 18237
+v == v
+v != v
+4 < 0
+-4 < 0
+4 > 0
+-4 > 0
+5 > 4
+-5 > 4
+5 > -4
+-5 > -4
+5 < 4
+-5 < 4
+5 < -4
+-5 < -4
+1000000000.000000001 == 999999999.000000001
+1000000000.000000001 > 999999999.000000001
+1000000000.000000001 < 999999999.000000001
+1000000000.000000001 == 1000000000.000000001
+1000000000.000000001 > 1000000000.000000001
+1000000000.000000001 < 1000000000.000000001
+1000000000.000000001 == 1000000000.00000000100000000
+1000000000.000000001 > 1000000000.00000000100000000
+1000000000.000000001 < 1000000000.00000000100000000
+1000000000.000000001 == 1000000000.000000001000000001
+1000000000.000000001 > 1000000000.000000001000000001
+1000000000.000000001 < 1000000000.000000001000000001
+999999999.000000001 == 1000000000.000000001
+999999999.000000001 > 1000000000.000000001
+999999999.000000001 < 1000000000.000000001
+1000000000.00000000100000000 == 1000000000.000000001
+1000000000.00000000100000000 > 1000000000.000000001
+1000000000.00000000100000000 < 1000000000.000000001
+1000000000.000000001000000001 == 1000000000.000000001
+1000000000.000000001000000001 > 1000000000.000000001
+1000000000.000000001000000001 < 1000000000.000000001
diff --git a/contrib/bc/tests/bc/comp_results.txt b/contrib/bc/tests/bc/comp_results.txt
new file mode 100644
index 000000000000..5aa90ebcdbeb
--- /dev/null
+++ b/contrib/bc/tests/bc/comp_results.txt
@@ -0,0 +1,131 @@
+1
+0
+1
+0
+0
+1
+0
+1
+1
+0
+1
+0
+0
+1
+0
+1
+0
+1
+1
+0
+0
+1
+1
+0
+0
+1
+0
+1
+1
+0
+1
+0
+0
+1
+0
+1
+1
+0
+1
+0
+1
+0
+0
+1
+1
+0
+0
+1
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+0
+1
+1
+0
+0
+1
+1
+0
+1
+0
+1
+0
+0
+1
+0
+1
+0
+1
+0
+1
+0
+0
+1
+0
+0
+0
+0
+1
+0
+0
+1
+1
+0
+0
+0
+1
+0
diff --git a/contrib/bc/tests/bc/cosine.txt b/contrib/bc/tests/bc/cosine.txt
new file mode 100644
index 000000000000..9e67df4c6f69
--- /dev/null
+++ b/contrib/bc/tests/bc/cosine.txt
@@ -0,0 +1,44 @@
+scale = 25
+p = 4 * a(1)
+scale = 20
+c(0)
+c(0.5)
+c(1)
+c(2)
+c(3)
+c(-0.5)
+c(-1)
+c(-2)
+c(-3)
+c(p / 7)
+c(-p / 7)
+c(p / 4)
+c(-p / 4)
+c(p / 3)
+c(-p / 3)
+c(p / 2)
+c(-p / 2)
+c(3 * p / 4)
+c(3 * -p / 4)
+c(p)
+c(-p)
+c(3 * p / 2)
+c(3 * -p / 2)
+c(7 * p / 4)
+c(7 * -p / 4)
+c(13 * p / 4)
+c(13 * -p / 4)
+c(2 * p)
+c(2 * -p)
+c(131231)
+c(-131231)
+c(859799894.3562378245)
+c(859799894.3562378245)
+c(4307371)
+c(3522556.3323810191)
+c(44961070)
+c(6918619.1574479809)
+c(190836996.2180244164)
+c(34934)
+c(2483599)
+c(13720376)
diff --git a/contrib/bc/tests/bc/cosine_results.txt b/contrib/bc/tests/bc/cosine_results.txt
new file mode 100644
index 000000000000..43d640f002df
--- /dev/null
+++ b/contrib/bc/tests/bc/cosine_results.txt
@@ -0,0 +1,41 @@
+1.00000000000000000000
+.87758256189037271611
+.54030230586813971740
+-.41614683654714238699
+-.98999249660044545727
+.87758256189037271611
+.54030230586813971740
+-.41614683654714238699
+-.98999249660044545727
+.90096886790241912623
+.90096886790241912623
+.70710678118654752440
+.70710678118654752440
+.50000000000000000000
+.50000000000000000000
+0
+0
+-.70710678118654752439
+-.70710678118654752439
+-1.00000000000000000000
+-1.00000000000000000000
+0
+0
+.70710678118654752439
+.70710678118654752439
+-.70710678118654752440
+-.70710678118654752440
+1.00000000000000000000
+1.00000000000000000000
+.92427123447397657316
+.92427123447397657316
+-.04198856352825241211
+-.04198856352825241211
+-.75581969921220636368
+-.01644924448939844182
+-.97280717522127222547
+-.92573947460230585966
+-.14343824233852988038
+.87259414746802343203
+.93542606623067050616
+-.52795540572178251550
diff --git a/contrib/bc/tests/bc/decimal.txt b/contrib/bc/tests/bc/decimal.txt
new file mode 100644
index 000000000000..b90bf9588a6e
--- /dev/null
+++ b/contrib/bc/tests/bc/decimal.txt
@@ -0,0 +1,61 @@
+0
+0.0
+.00000
+000000000000000000000000.00000000000000000000000
+000000000000000000000000000135482346782356
+000000000000000000000000002
+1
+11
+123
+7505
+1023468723275435238491972521917846
+4343472432431705867392073517038270398027352709027389273920739037937960379637893607893607893670530278200795207952702873892786172916728961783907893607418973587857386079679267926737520730925372983782793652793
+-1
+-203
+-57
+-18586
+-31378682943772818461924738352952347258
+-823945628745673589495067238723986520375698237620834674509627345273096287563846592384526349872634895763257893467523987578690283762897568459072348758071071087813501875908127359018715023841710239872301387278
+.123521346523546
+0.1245923756273856
+-.1024678456387
+-0.8735863475634587
+4.0
+-6.0
+234237468293576.000000000000000000000000000000
+23987623568943567.00000000000000000005677834650000000000000
+23856934568940675.000000000000000435676782300000000000000456784
+77567648698496.000000000000000000587674750000000000458563800000000000000
+2348672354968723.2374823546000000000003256987394502346892435623870000000034578
+-2354768.000000000000000000000000000000000000
+-96739874567.000000000347683456
+-3764568345.000000000004573845000000347683460
+-356784356.934568495770004586495678300000000
+74325437345273852773827101738273127312738521733017537073520735207307570358738257390761276072160719802671980267018728630178.7082681027680521760217867841276127681270867827821768173178207830710978017738178678012767377058785378278207385237085237803278203782037237582795870
+-756752732785273851273728537852738257837283678965738527385272983678372867327835672967385278372637862738627836279863782673862783670.71738178361738718367186378610738617836781603760178367018603760178107735278372832783728367826738627836278378260736270367362073867097307925
+9812734012837410982345719208345712908357412903587192048571920458712.23957182459817249058172945781
+1891702357\
+ 289370172037.90287102837
+011234567890
+01123456789.0
+0112345678.90
+011234567.890
+01123456.7890
+0112345.67890
+011234.567890
+01123.4567890
+0112.34567890
+011.234567890
+01.1234567890
+0.11234567890
+.011234567890
+.0011234567890
+.00011234567890
+.000011234567890
+.0000011234567890
+.00000011234567890
+.000000011234567890
+.0000000011234567890
+.00000000011234567890
+.000000000011234567890
+.0000000000011234567890
diff --git a/contrib/bc/tests/bc/decimal_results.txt b/contrib/bc/tests/bc/decimal_results.txt
new file mode 100644
index 000000000000..e0aac3cc8519
--- /dev/null
+++ b/contrib/bc/tests/bc/decimal_results.txt
@@ -0,0 +1,75 @@
+0
+0
+0
+0
+135482346782356
+2
+1
+11
+123
+7505
+1023468723275435238491972521917846
+43434724324317058673920735170382703980273527090273892739207390379379\
+60379637893607893607893670530278200795207952702873892786172916728961\
+78390789360741897358785738607967926792673752073092537298378279365279\
+3
+-1
+-203
+-57
+-18586
+-31378682943772818461924738352952347258
+-8239456287456735894950672387239865203756982376208346745096273452730\
+96287563846592384526349872634895763257893467523987578690283762897568\
+45907234875807107108781350187590812735901871502384171023987230138727\
+8
+.123521346523546
+.1245923756273856
+-.1024678456387
+-.8735863475634587
+4.0
+-6.0
+234237468293576.000000000000000000000000000000
+23987623568943567.00000000000000000005677834650000000000000
+23856934568940675.000000000000000435676782300000000000000456784
+77567648698496.00000000000000000058767475000000000045856380000000000\
+0000
+2348672354968723.237482354600000000000325698739450234689243562387000\
+0000034578
+-2354768.000000000000000000000000000000000000
+-96739874567.000000000347683456
+-3764568345.000000000004573845000000347683460
+-356784356.934568495770004586495678300000000
+74325437345273852773827101738273127312738521733017537073520735207307\
+570358738257390761276072160719802671980267018728630178.7082681027680\
+52176021786784127612768127086782782176817317820783071097801773817867\
+8012767377058785378278207385237085237803278203782037237582795870
+-7567527327852738512737285378527382578372836789657385273852729836783\
+72867327835672967385278372637862738627836279863782673862783670.71738\
+17836173871836718637861073861783678160376017836701860376017810773527\
+8372832783728367826738627836278378260736270367362073867097307925
+9812734012837410982345719208345712908357412903587192048571920458712.\
+23957182459817249058172945781
+1891702357289370172037.90287102837
+11234567890
+1123456789.0
+112345678.90
+11234567.890
+1123456.7890
+112345.67890
+11234.567890
+1123.4567890
+112.34567890
+11.234567890
+1.1234567890
+.11234567890
+.011234567890
+.0011234567890
+.00011234567890
+.000011234567890
+.0000011234567890
+.00000011234567890
+.000000011234567890
+.0000000011234567890
+.00000000011234567890
+.000000000011234567890
+.0000000000011234567890
diff --git a/contrib/bc/tests/bc/divide.txt b/contrib/bc/tests/bc/divide.txt
new file mode 100644
index 000000000000..cba4af9dc8ba
--- /dev/null
+++ b/contrib/bc/tests/bc/divide.txt
@@ -0,0 +1,62 @@
+0 / 1
+0 / 321566
+0 / 0.3984567238456
+1 / 1
+1 / 1287469297356
+1 / 0.2395672438567234
+1 / 237586239856.0293596728392360
+1249687284356 / 3027949207835207
+378617298617396719 / 35748521
+9348576237845624358 / 0.9857829375461
+35768293846193284 / 2374568947.045762839567823
+-78987234567812345 / 876542837618936
+-356789237555535468 / 0.3375273860984786903
+-5203475364850390 / 435742903748307.70869378534043296404530458
+-0.37861723347576903 / 7385770896
+-0.399454682043962 / 0.34824389304
+-0.6920414523873204 / 356489645223.76076045304879030
+-35872917389671.7573280963748 / 73924708
+-78375896314.4836709876983 / 0.78356798637817
+-2374123896417.143789621437581 / 347821469423789.1473856783960
+-896729350238549726 / -34976289345762
+-2374568293458762348596 / -0.8792370647234987679
+-237584692306721845726038 / -21783910782374529637.978102738746189024761
+-0.23457980123576298375682 / -1375486293874612
+-0.173897061862478951264 / -0.8179327486017634987516298745
+-0.9186739823576829347586 / -0.235678293458756239846
+-0.9375896183746982374568 / -13784962873546.0928729395476283745
+-2930754618923467.12323745862937465 / -734869238465
+-23745861923467.874675129834675 / -0.23542357869124756
+-3878923750692883.7238596702834756902 / -7384192674957215364986723.9738461923487621983
+1 / 0.00000000000000000000000000000000000000000002346728372937352457354204563027
+3496723859067234 / 298375462837546928347623059375486
+-47589634875689345 / 37869235
+-6324758963 / 237854962
+2 / -3
+89237423 / -237856923854
+123647238946 / -12467
+-2 / -3
+-13 / -7
+-15 / -7
+-12784956 / -32746
+-127849612 / -23712347682193
+1 / 0.2395672438567234
+scale = 0
+15 / 4
+17 / 4
+2389473 / 5
+346728934 / 23958
+-47589634875689345 / 37869235
+-6324758963 / 237854962
+2 / -3
+16 / 5
+14 / 5
+123647238946 / -12467
+-2 / -3
+-13 / -7
+-15 / -7
+-12784956 / -32746
+-3191280681 / 641165986
+scale = 0; -899510228 / -2448300078.40314
+scale = 0; -7424863 / -207.2609738667
+scale = 0; 3769798918 / 0.6
diff --git a/contrib/bc/tests/bc/divide_results.txt b/contrib/bc/tests/bc/divide_results.txt
new file mode 100644
index 000000000000..a095066e1ba2
--- /dev/null
+++ b/contrib/bc/tests/bc/divide_results.txt
@@ -0,0 +1,61 @@
+0
+0
+0
+1.00000000000000000000
+.00000000000077671755
+4.17419336592637110778
+.00000000000420899796
+.00041271738677857404
+10591131829.40901859967857131767
+9483402361494453751.52388015648196297248
+15063068.13735316451497043884
+-90.11223545260531110575
+-1057067521778623447.45138528213564485251
+-11.94161814246320631346
+-.00000000005126306228
+-1.14705437777218917343
+-.00000000000194126663
+-485262.88923145638029569727
+-100024372711.74763635544535424582
+-.00682569681609989277
+25638.20711150436682153521
+2700714504347599627864.24626421085374010264
+10906.42973524078145692731
+.00000000000000017054
+.21260557443109085166
+3.89799997647407910677
+.00000000000006801538
+3988.13076601933678578945
+100864416620775.31076855630746548983
+.00000000052530099381
+42612515855353136519261264261472677699404182.78776061098893912189
+.00000000000000001171
+-1256683291.21751059930310184507
+-26.59082202792136831688
+-.66666666666666666666
+-.00037517269438317975
+-9917962.53677709152161706906
+.66666666666666666666
+1.85714285714285714285
+2.14285714285714285714
+390.42802174311366273743
+.00000539168933053431
+4.17419336592637110778
+3
+4
+477894
+14472
+-1256683291
+-26
+0
+3
+2
+-9917962
+0
+1
+2
+390
+-4
+0
+35823
+6282998196
diff --git a/contrib/bc/tests/bc/engineering.txt b/contrib/bc/tests/bc/engineering.txt
new file mode 100644
index 000000000000..cf9c0c1b0117
--- /dev/null
+++ b/contrib/bc/tests/bc/engineering.txt
@@ -0,0 +1,19 @@
+obase=1
+0
+1
+-34
+298
+-8933
+29488
+-148232
+8927559
+.2
+-.02
+.002
+-.0003
+.0000209310
+-.00000289362
+.000000859289
+-.02983672
+.20201296
+-.8907210897000000000000000000
diff --git a/contrib/bc/tests/bc/engineering_results.txt b/contrib/bc/tests/bc/engineering_results.txt
new file mode 100644
index 000000000000..dd26f9bbb138
--- /dev/null
+++ b/contrib/bc/tests/bc/engineering_results.txt
@@ -0,0 +1,18 @@
+0
+1e0
+-34e0
+298e0
+-8.933e3
+29.488e3
+-148.232e3
+8.927559e6
+200e-3
+-20e-3
+2e-3
+-300e-6
+20.9310e-6
+-2.89362e-6
+859.289e-9
+-29.83672e-3
+202.01296e-3
+-890.7210897000000000000000000e-3
diff --git a/contrib/bc/tests/bc/errors.txt b/contrib/bc/tests/bc/errors.txt
new file mode 100644
index 000000000000..738b7a0c9dd8
--- /dev/null
+++ b/contrib/bc/tests/bc/errors.txt
@@ -0,0 +1,258 @@
+4 != 0 &^ 34 == 5
+4 & 5
+4 != 0 |% 34 == 5
+4 | 5
+3 $ 7
+4 @^ 5
+'
+1.892389ep
+"ontsjahoesu
+/* oerchaoegu
+\(<267)11111111111111111111111111111
+j(1,)
+a(3,3
+()
+(((((((((((((((((((()))))))))))))))
+3 +
+3 - -
+233*+ 32
+233*+ 32 869356734856
+293 * += 38297
+293 * += 38297 2839
+293 - %= 38297
+a * += 38297 2839
+a += * 38297
+a += * 38297 2839
+a %= % 38297
+a %= / 38297 2839
+"s" + 3
+3 - "o"
+"e" * "j"
+"3" / "2"
+!"3"
+--"4"
+"4"++
++ 4
+* 3
++ 4 + 3
+* 3 + 2
+c++ +
+c + ++
+(e * a)++
+++(e ^ a)
+(e + a)--
+--(e - a)
+++e++
+++e--
+--e++
+--e--
+++(e)
+(e)--
+++++e
+e----
+++-e
+---e
+++x += 4
+x++ += 4
+(i += 1) += 1
+-i+=1
+e a
+c!
+e! + a
+a + e!
+(0||!)
+(238497*(29348+238)
+a[234
+a238]
+a[(0] + 1)
+(1 + a[0)]
+283947 2983745289
+a 4
+a g
+define r(e,) {}
+p(,e)
+p(e,)
+! + 1l(2)
+l957)
+l(
+g[si+= j []a[s]>=]
+j[s
+!>5d
+a(1..)
+a(1;)
+1..
+1..0
+99""""""""""""""""""""""""""""""""99.9999999 + 0.0000000000001
+pll[zx<zb]--(<.+)1
+a(g2[] -3)
+.--1)-1)
+.--1)
+-1)
+(.2==)--d_ -8234+68. -d_ ---d_ -d_ ---d_ -d2 + 5
+break
+continue
+auto a,u
+define i(e) { auto p,; return(p); }
+define i(e) { auto e; return(e); }
+define i(e) { auto q; auto n; return(e); }
+define i(e) { auto q; e+=q; auto n; return(e); }
+define i(e, e) { auto p; return(p*e); }
+define i(e, g, e) { auto p; return(p*e*g); }
+define x(e) { define q(f) { return (0); } return q(e); }
+define x(3) { return q(e); }
+define x([]e) { return q(e); }
+define x([]) { return q(e); }
+define x(e,[]) { return q(e); }
+define x(a[]) { return a[]; }
+define x(*a) { return a; }
+define x(a) return a;
+while e!=0 { i+=1 }
+while (e!=0) { i+=1 } if (x) x
+for i=0;i<2;++i { c+=i; }
+for (i=0;i<2,++i) { c+=i; }
+for (i=0,i<2;++i) { c+=i; }
+for (i<2;++i) { c+=i; }
+for (i=0;++i) { c+=i; }
+return (0)
+sqrt(3,4)
+length(3,4)
+scale(3,4)
+3=4
+3+=4
+4-=3
+4*=3
+4/=3
+4%=3
+4^=3
+3++
+--3
+a[] = 4
+1 + $
+a[18446744073709552000] = 0
+j(1,2,3)
+j(1,a[])
+x(2)
+read(3)
+scale = 18446744073709552000
+ibase = 18446744073709552000
+obase = 18446744073709552000
+scale = -1
+sqrt(-1)
+0 ^ -251
+1/0
+1%0
+0/0
+0%0
+0/0.000000
+0.000000%0.00000000
+root(-15, 4)
+root(5, 0)
+root(13, -5)
+root(1548, 0)
+irand(-4)
+irand(3289.10827340)
+scale = 10000000000000000000000000000000000
+obase += 999999999999999999999999999999999999999999999999999999999999999999999999
+ibase *= 9999999999999999999999999999999999999999999999999999999999999.9
+obase += 9999999999999999999999999999999
+ibase *= 99999999999999999999999999999.9
+scale = 18446744073709551616
+1<<18446744073709551616
+1>>18446744073709551616
+1<<18446744073709551614
+1>>18446744073709551614
+i /= 0
+4^2903482.29304823
+4 @ 2389.21982
+1 @ -38
+3 @ 81906237540187263501872350127351023651023517239512635109283651203985123581235
+9 << 182397.283906123
+8 << -19
+4 << 1298376540182376510982365108263510823651082365120983561239851623590812365192830
+5 >> 21892073.28901672
+2 >> -29
+7 >> 10289374108237541829374123894571028345718923751908237518927809127350891723908
+"string"$
+-"str2"
+a[] + a
+a - a[]
+a[] * a[]
+a[] / a
+a % a[]
+a[] ^ a[]
+c(a[])
+j(a[], a)
+j(a, a[])
+j(a[], a[])
+c(;
+c(0;
+c[0;
+++c(0)
+--c(1)
+++scale(34.4)
+print "3", a[], "3"
+print a[]
+print a[], "e"
+print;
+print 1,2 print 45
+print "s" "4"
+}
+if x x
+if (x
+while (x
+for (i = 0
+for (i = 0; i < 10
+for (i = 0; i < 10; ++i
+define %(x) { return x; }
+define x x) { return x; }
+for (i=0; i; ++i) if (i) print "stuff"; else i; if (!i) i + 1; else i; }
+for (i=0; i; ++i) }
+if (i == 0) break; else i;
+while (x != 0) { break 4; }
+while (x != 0) { continue 4; }
+while (x != 0) 4 else 5
+else 1
+define t(a[) { return a[0]; }
+define u() { auto a[; return a[0]; }
+define v() { auto a, 4; return a; }
+define w() { auto a 4; return a; }
+define r() { auto a[], 4; return a[0]; }
+define s() { auto a[ 4; return a[0]; }
+define void y() { return (1); }
+print uint(0)
+4 + uint(4)
+s(uint(5))
+4 + 4 scale
+4 + 4 scale(s)
+4 * 4 read()
+5 abs(-5)
+2 sqrt(4)
+5 + 3 length(4)
+x$if(x) x else x
+bytes(1) + 4
+3 / 0.00000000000000
+4e4.4
+4e-4.2
+a[2^63] = 1
+ibase = 100
+length(l[] + i[])
+length("string")
+abs("string")
+abs(a[])
+scale("string")
+scale(b[])
+sqrt("string")
+sqrt(c[])
+sqrt
+length
+abs
+sqrt(1
+length(1
+abs(1
+scale(.2093
+a2(0,0)
+read
+read(
+read()
+read()
+read()
diff --git a/contrib/bc/tests/bc/errors/01.txt b/contrib/bc/tests/bc/errors/01.txt
new file mode 100644
index 000000000000..987f05c7a8c1
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/01.txt
@@ -0,0 +1,368 @@
+a(s691027461l[ ba])
+scal[ ca]
+a
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+u
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+u
+a
+s
+c = l[ ca]
+a
+a
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+scal[ ca]
+a
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+a
+a
+s
+c = l[ ca]
+a
+s
+c = l[ ca]
+a(s691027461l[ ba])
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+u
+a
+s
+c = l[ ca]
+a
+a
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+scal[ ca]
+a
+a*e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+a
+a
+s
+c = l[ ca]
+a
+a
+sa
+e
+css
+c = c[ ca]
+a
+a
+sa
+e
+cs
+a
+a
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+ cs
+c = l[ ca]
+a
+a
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+scal[ ca]
+a
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+a
+a
+s
+c = l[ ca]
+a
+a
+sa
+e
+css
+c = l[ ca]
+a
+a
+sa
+e
+cs
+a
+b
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+scal[ ca]
+a
+a
+e
+cs
+
+scal[ ca]
+a
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+u
+a
+s
+c = l[ ca]
+a
+a
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+scal[ ca]
+a
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+scal[ ca]
+a
+a
+s
+c = l[ ca]
+a
+a
+sa
+e
+css
+c = l[ ca]
+a
+a
+sa
+e
+cs
+a
+a
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+scs
+c = l[ ca]
+a
+a
+sa
+e
+cs
+c
+
+a(s691027461l[ ba])
+scal[ ca]
+a
+a
+e
+cs
+c
+
+a
+s(scal[ ba])
+s(1)
+sd= 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scalaaaaaaaaaaaaa^aaaaaaaaaaaaaaa20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=asj-=se-=as-=se-=axse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=as=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscales=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+sd= 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scale ==se-=a(1)
+scale = 20
+a(0)
+a==se-=as+=ase-=se8=as-=se-=a(1)
+s ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=se-=xse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=as-=ase-=se-=se4=ase-=se-=as-=e-=as=ae-=a(1)
+sc= 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=se-=xse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+sd= 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=s-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=a_=as-=ase-=se-=se4=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=se-=xse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as*=e-=as=aaaaaaaaaaaaaaaaaaaaaaa^aaaaaaaaaaaaaaa20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=axse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=as=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==sse-=ase-=s-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=as-=ase-=se-=se4=ase-=se-=as-=e-=as=ase0=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=se-=xse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=aaaaaaaaaaaaaaaaaaaaaaa^aaaaaaaaaaaaaaa20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=axse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=as=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=as-=ase-=se-=as-=as0
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=se-=xse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=aaa^aaaaaaaaaaaaaaa20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=axse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=as=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscales=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+sd= 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+de ==se-=a(1)
+scale = 20
+a(0)
+a==se-=as-=ase-=se8=as-=se-=a(1)
+s ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=se-=xse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=as-=ase-=se-=se4=ase-=se-=as-=e-=as=ae-=a(1)
+sc= 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=se-=xse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+sd= 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase = 20
+a(0)
+a1i-=se-=ase-=se-=ase-=s-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=c-=a_=as-se-=se-=se4=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=asse-=as-=e-=as=aaaaaaaaaaaaaaaaaaaaaaa^aaaaaaaaaaaaaaa20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=axse!=e-=ase-=i-=se-=ase-=se-=se-=ase-=se-=as-=e-=as=ase-=se-=as-=as=i-=se-=ase-=-=se-=ascccc-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=s-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+scale = 20
+a(0)
+a=i-=se-=ase-=se-=ase-=i-=s-=se-=xse!=e-=as=as-=ase-=se-=se4=ase-=se-=as-=e-=as=ase-=se-=as-=ase-=se-=as-=se-=a(1)
+scscale ==se-=a(1)
+sBale = 20
+a
diff --git a/contrib/bc/tests/bc/errors/02.txt b/contrib/bc/tests/bc/errors/02.txt
new file mode 100644
index 000000000000..a42dca886b75
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/02.txt
@@ -0,0 +1,16 @@
+obase^= 20-f-b-4^-f-4-4^-f-4^-d
+-f-4>-f-4^-0;759634576394-f-4^-f-4-4^-f-4^-4
+-f-4^-f>4^-4-f-f-4^-f-4-4^-f-4^-d
+-f-4>-f-4^-0;7-f-4^-f-4-4^-f-4^-4
+-f-4^-f>4^-4-f-b-4^-f-4-4^-f-4^-d
+-f-4>-f-4^-0;7454-f-4^-f-4-4^-f-4^-4
+-f-4^-f>4^-4-f-f-4^-f-4-4^-f-4^-d
+-f-4>-f-4^-0;75576394.3946587934658364894^-4-f-f-4^-f-4-4-4^-f-4-4^-f-4^-4
+-f*.^-f>4^-4-f-b-4^-f-4-4^-f-4^-d
+-f-4>-f-4^-0;759634576394-f-4^-f-4-4^-f-4^-4
+-f-4^-f>4^-4-f-f-4^-f-4-4^-f-4^-d
+-f-4>-f-4^-0;7-f-4^-f-4-4^-f-4^-4
+-f-4^-f>4^-4-f-b-4^-f-4-4^-f-4^-d
+-f-4>-f-4^-0;74576394-f-4^-f-4-4^-f-4^-4
+-f-4^-f>4^-4-f-f4^-f-4-4^-f-4^-d
+-f-4>-f-B^-0;75576394.3946587934658364894^-4-f-f-4^-f-4-4^-W-4^-d
diff --git a/contrib/bc/tests/bc/errors/03.txt b/contrib/bc/tests/bc/errors/03.txt
new file mode 100644
index 000000000000..25fee2fa07fe
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/03.txt
@@ -0,0 +1,2 @@
+for (i = 0; ; )
+for (i = 0; ;(ssqrt()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(ssssq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s()-p(sq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s(ssqrt()-p(t()-p(sstp(ssqrt()-sst()-p(qrt()-p(s()-p(srt()-s(ssqrt()-v(qrt(ssqrt()-p(ssqrt()-s(ssqrt()-p(ssssq(ssqrt()-p(ssq(ssqrt()-p(t()-sst()-prt()-s(ssqrt()-p(q(ssqrt()-p(ssqrt()-sst()-ssqrt()-t(ss(s()-p(srt()-s(ssqrt()-p(s(ssqrtt()-p(ssqrt()-sst()-p(qrt()-p(s()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(qr (itt()-p(q(s(ssqrt()-t(ss(ssqrt()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(sstsq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(sstsq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s(ssqrt()-p(t()-p(sstp(ssqrt()-sst()-p(qrt()-p(s()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(qr (itt()-p(q(s(ssqrt()-t(ss(ssqrt()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(sstsq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s()-p(srt()-s(ssqrt()-p(sstss(osqrt()-p(sstsq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s(ssqrt()-p(ssqrt()-sstfor (itt()-p(q(s(ssqrt()-t(ss(ssqrt()-p(srt()-s(ssqrt()-p(sstss(sssq(ssqrt()-p(ssqrt()-sst()-prt()-s(ssqrt()-p(q(ssqrt()-ssqrt(qrt()-p(s()-p(srt(s(ssqrt()-p(q(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s(ssqrt()-p(ssqrt()-sst()-p(ssqrt()-ssq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s-t()-s(ssurt()-p(sstss(ssqrt()-p(qr (itt()-p(q(s(ssqrt()-t(ss(ssqrt()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(sstsq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s()-p(srt()-s(ssqrt()-p(sstss(osqrt()-p(sstsq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s(ssqrt()-p(ssqrt()-sstfor (itt()-p(q(s(ssqrt()-t(ss(ssqrt()-p(srt()-s(ssqrt()-p(sstss(sssq(ssqrt()-p(ssqrt()-sst()-prt()-s(ssqrt()-p(q(ssqrt()-ssqrt(qrt()-p(s()-p(srt(s(ssqrt()-p(q(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s(ssqrt()-p(ssqrt()-sst()-p(ssqrt()-ssq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s-p(ssqrt()-sst()-p(qrt()-p(s(st()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(ssssq(ssqrt()-p(ssqrt()-sst()-p(qrt()-p(s()-p(srt()-s(ssqrt()-p(sstss(ssqrt()-p(ssssq(ssqrt()-p(ssqrt()-sst()-p(qrtrrrrr()-p(s(ssqrt()-p(ssqrt()-sst()-p(ssqrt(qrt(ssqrt()-p(ssqrt()-s(ssqrt()-p(ssssq(ssqrt()-p(ssq(ssqrt()-p(ssqrt()-sst()-prt()-s(ssqrt()-p(q(ssqrt()-p(ssqrt()-sst()-ssqrt()-t(ss(s()-p(srt()-s(ssqrt()-p(s(ssqrtt()-p()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))()%t(ss(s()-p(srt()))))))))))))))))))))))t()Cp(q(s(ssqrt()-t(ss(ssqrt()-p(srt()-s(ssqrt()-p(srt()-p(ssqrt()-sst=)-p(qrt()-p(s(t()-p(qrt()-p(s(ssqrt()-p(ssqrt()-sst()-p(ssqrt(qrt(ssqrt()-p(ssqrt()-s(ssqrt()-p(ssts*=!dd_ed0;#239
diff --git a/contrib/bc/tests/bc/errors/04.txt b/contrib/bc/tests/bc/errors/04.txt
new file mode 100644
index 000000000000..bb81925f15a4
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/04.txt
@@ -0,0 +1 @@
+"String
diff --git a/contrib/bc/tests/bc/errors/05.txt b/contrib/bc/tests/bc/errors/05.txt
new file mode 100644
index 000000000000..dd4f3dfce14c
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/05.txt
@@ -0,0 +1 @@
+/* Comment
diff --git a/contrib/bc/tests/bc/errors/06.txt b/contrib/bc/tests/bc/errors/06.txt
new file mode 100644
index 000000000000..29fe6be37021
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/06.txt
@@ -0,0 +1 @@
+while (i == 0) {
diff --git a/contrib/bc/tests/bc/errors/07.txt b/contrib/bc/tests/bc/errors/07.txt
new file mode 100644
index 000000000000..7cc293a73d8b
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/07.txt
@@ -0,0 +1,36 @@
+for (q = F; i <=020; ++i) # i
+{print "n"
+if(6)if(6){3
+ }
+{pryn}
+"" }
+{pryn}
+{print "" "" }
+{pryn}
+{print "" "" }
+{pryn}
+{print "" "" }
+{pryn}
+ "" }
+{pryn}
+{print "" "" }
+{pryn}
+{print "" "" }
+{tryn}
+{print "" "" }
+{print "" "" }
+{pryn}
+{print "" "" }
+{pryn}
+{print "" "" }
+{pryn}
+ "" }
+{prynn}
+{print "" "" }
+{print "" "" }
+{pryn}
+{print "" "" }
+{pryn}
+{print "" "" }
+{pryn}
+ "" }
diff --git a/contrib/bc/tests/bc/errors/08.txt b/contrib/bc/tests/bc/errors/08.txt
new file mode 100644
index 000000000000..6b36864add91
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/08.txt
@@ -0,0 +1,3 @@
+define i(x) {
+c673
+if(267)}
diff --git a/contrib/bc/tests/bc/errors/09.txt b/contrib/bc/tests/bc/errors/09.txt
new file mode 100644
index 000000000000..9558d1b4a2bc
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/09.txt
@@ -0,0 +1,18 @@
+de
+-1\
+#^ - 74 aA; ++i)
+{print "n"
+if(1)if(1)#3
+}
+if(0)if(1){3
+}
+else 4\
+#^ - 74 aA; ++i)f(1)if(1){3
+}
+if(0)if(1){3
+}
+else 4
+if(0){if(1){3
+}}
+elqe else}
+if(
diff --git a/contrib/bc/tests/bc/errors/10.txt b/contrib/bc/tests/bc/errors/10.txt
new file mode 100644
index 000000000000..44530b49f9cc
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/10.txt
@@ -0,0 +1,13 @@
+defi$++
+--x
+x += 9
+x
+length(2381)
+strt(9(çsbale(238.1)
+x=2
+x[0]=3
+(x)
+(x[p])*)scale)
+(ibase)
+(o
+--x \ No newline at end of file
diff --git a/contrib/bc/tests/bc/errors/11.txt b/contrib/bc/tests/bc/errors/11.txt
new file mode 100644
index 000000000000..94be82ee3d05
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/11.txt
@@ -0,0 +1,408 @@
+#! /usr/bin/bc -q
+
+define printarray(a[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a[i]
+ }
+}
+
+define a2(a[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a[i] = a[i] * a[i]
+ }
+
+ printarray(len, len)
+}
+
+define a4(a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = a__[i] * a__[i]
+ }
+
+ printarray(a__[], len)
+}
+
+define a6(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = a__[i] * a__[i]
+ }
+
+ printarray(a__[], len)
+}
+
+define a1(*a[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a[i] = i
+ }
+
+ a2(a[], len)
+
+ printarray(a[], len)
+}
+
+define a3(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = i
+ }
+
+ a4(a__[], len)
+
+ printarray(a__[], len)
+}
+
+define a5(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = i
+ }
+
+ a2(a__[], len)
+
+ printarray(a__[], len)
+}
+
+define a7(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = i
+ }
+
+ a6(a__[], len)
+
+ printarray(a__[], len)
+}
+
+len = 16
+
+a1(a[], len)
+printarray(a[], len)
+a3(a[], len)
+printarray(a[], len)
+a5(a[], len)
+printarray(a[], len)
+a7(a[], len)
+printarray(a[], len)
+
+a1(b[], len)
+printarray(b[], len)
+a3(b[], len)
+printarray(b[], len)
+a5(b[], len)
+printarray(b[], len)
+a7(b[], len)
+printarray(b[], len)
+
+a1[0] = 0
+a2[0] = 0
+a3[0] = 0
+a4[0] = 0
+a5[0] = 0
+a6[0] = 0
+a7[0] = 0
+a8[0] = 0
+a9[0] = 0
+a10[0] = 0
+a11[0] = 0
+a12[0] = 0
+a13[0] = 0
+a14[0] = 0
+a15[0] = 0
+a16[0] = 0
+a17[0] = 0
+a18[0] = 0
+a19[0] = 0
+a20[0] = 0
+a21[0] = 0
+a22[0] = 0
+a23[0] = 0
+a24[0] = 0
+a25[0] = 0
+a26[0] = 0
+a27[0] = 0
+a28[0] = 0
+a29[0] = 0
+a30[0] = 0
+a31[0] = 0
+a32[0] = 0
+a33[0] = 0
+a34[0] = 0
+a35[0] = 0
+a36[0] = 0
+a37[0] = 0
+a38[0] = 0
+a39[0] = 0
+a40[0] = 0
+a41[0] = 0
+a42[0] = 0
+a43[0] = 0
+a44[0] = 0
+a45[0] = 0
+a46[0] = 0
+a47[0] = 0
+a48[0] = 0
+a49[0] = 0
+a50[0] = 0
+a51[0] = 0
+a52[0] = 0
+a53[0] = 0
+a54[0] = 0
+a55[0] = 0
+a56[0] = 0
+a57[0] = 0
+a58[0] = 0
+a59[0] = 0
+a60[0] = 0
+a61[0] = 0
+a62[0] = 0
+a63[0] = 0
+a64[0] = 0
+a65[0] = 0
+a66[0] = 0
+a67[0] = 0
+a68[0] = 0
+a69[0] = 0
+a70[0] = 0
+a71[0] = 0
+a72[0] = 0
+a73[0] = 0
+a74[0] = 0
+a75[0] = 0
+a76[0] = 0
+a77[0] = 0
+a78[0] = 0
+a79[0] = 0
+a80[0] = 0
+a81[0] = 0
+a82[0] = 0
+a83[0] = 0
+a84[0] = 0
+a85[0] = 0
+a86[0] = 0
+a87[0] = 0
+a88[0] = 0
+a89[0] = 0
+a90[0] = 0
+a91[0] = 0
+a92[0] = 0
+a93[0] = 0
+a94[0] = 0
+a95[0] = 0
+a96[0] = 0
+a97[0] = 0
+a98[0] = 0
+a99[0] = 0
+a100[0] = 0
+a101[0] = 0
+a102[0] = 0
+a103[0] = 0
+a104[0] = 0
+a105[0] = 0
+a106[0] = 0
+a107[0] = 0
+a108[0] = 0
+a109[0] = 0
+a110[0] = 0
+a111[0] = 0
+a112[0] = 0
+a113[0] = 0
+a114[0] = 0
+a115[0] = 0
+a116[0] = 0
+a117[0] = 0
+a118[0] = 0
+a119[0] = 0
+a120[0] = 0
+a121[0] = 0
+a122[0] = 0
+a123[0] = 0
+a124[0] = 0
+a125[0] = 0
+a126[0] = 0
+a127[0] = 0
+a128[0] = 0
+a129[0] = 0
+a130[0] = 0
+a131[0] = 0
+a132[0] = 0
+a133[0] = 0
+a134[0] = 0
+a135[0] = 0
+a136[0] = 0
+a137[0] = 0
+a138[0] = 0
+a139[0] = 0
+a140[0] = 0
+a141[0] = 0
+a142[0] = 0
+a143[0] = 0
+a144[0] = 0
+a145[0] = 0
+a146[0] = 0
+a147[0] = 0
+a148[0] = 0
+a149[0] = 0
+a150[0] = 0
+a151[0] = 0
+a152[0] = 0
+a153[0] = 0
+a154[0] = 0
+a155[0] = 0
+a156[0] = 0
+a157[0] = 0
+a158[0] = 0
+a159[0] = 0
+a160[0] = 0
+a161[0] = 0
+a162[0] = 0
+a163[0] = 0
+a164[0] = 0
+a165[0] = 0
+a166[0] = 0
+a167[0] = 0
+a168[0] = 0
+a169[0] = 0
+a170[0] = 0
+a171[0] = 0
+a172[0] = 0
+a173[0] = 0
+a174[0] = 0
+a175[0] = 0
+a176[0] = 0
+a177[0] = 0
+a178[0] = 0
+a179[0] = 0
+a180[0] = 0
+a181[0] = 0
+a182[0] = 0
+a183[0] = 0
+a184[0] = 0
+a185[0] = 0
+a186[0] = 0
+a187[0] = 0
+a188[0] = 0
+a189[0] = 0
+a190[0] = 0
+a191[0] = 0
+a192[0] = 0
+a193[0] = 0
+a194[0] = 0
+a195[0] = 0
+a196[0] = 0
+a197[0] = 0
+a198[0] = 0
+a199[0] = 0
+a200[0] = 0
+a201[0] = 0
+a202[0] = 0
+a203[0] = 0
+a204[0] = 0
+a205[0] = 0
+a206[0] = 0
+a207[0] = 0
+a208[0] = 0
+a209[0] = 0
+a210[0] = 0
+a211[0] = 0
+a212[0] = 0
+a213[0] = 0
+a214[0] = 0
+a215[0] = 0
+a216[0] = 0
+a217[0] = 0
+a218[0] = 0
+a219[0] = 0
+a220[0] = 0
+a221[0] = 0
+a222[0] = 0
+a223[0] = 0
+a224[0] = 0
+a225[0] = 0
+a226[0] = 0
+a227[0] = 0
+a228[0] = 0
+a229[0] = 0
+a230[0] = 0
+a231[0] = 0
+a232[0] = 0
+a233[0] = 0
+a234[0] = 0
+a235[0] = 0
+a236[0] = 0
+a237[0] = 0
+a238[0] = 0
+a239[0] = 0
+a240[0] = 0
+a241[0] = 0
+a242[0] = 0
+a243[0] = 0
+a244[0] = 0
+a245[0] = 0
+a246[0] = 0
+a247[0] = 0
+a248[0] = 0
+a249[0] = 0
+a250[0] = 0
+a251[0] = 0
+a252[0] = 0
+a253[0] = 0
+a254[0] = 0
+a255[0] = 0
+a256[0] = 0
+
+a1(a253[], len)
+printarray(a253[], len)
+a3(a253[], len)
+printarray(a253[], len)
+a5(a253[], len)
+printarray(a253[], len)
+a7(a253[], len)
+printarray(a253[], len)
+
+a1(a254[], len)
+printarray(a254[], len)
+a3(a254[], len)
+printarray(a254[], len)
+a5(a254[], len)
+printarray(a254[], len)
+a7(a254[], len)
+printarray(a254[], len)
+
+a1(a255[], len)
+printarray(a255[], len)
+a3(a255[], len)
+printarray(a255[], len)
+a5(a255[], len)
+printarray(a255[], len)
+a7(a255[], len)
+printarray(a255[], len)
+
+a1(a256[], len)
+printarray(a256[], len)
+a3(a256[], len)
+printarray(a256[], len)
+a5(a256[], len)
+printarray(a256[], len)
+a7(a256[], len)
+printarray(a256[], len)
diff --git a/contrib/bc/tests/bc/errors/12.txt b/contrib/bc/tests/bc/errors/12.txt
new file mode 100644
index 000000000000..b08b4cb70fa2
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/12.txt
@@ -0,0 +1,3 @@
+for (v ;!j -90-90; ++i)
+x1da= ibase ++;1
+'.2
diff --git a/contrib/bc/tests/bc/errors/13.txt b/contrib/bc/tests/bc/errors/13.txt
new file mode 100644
index 000000000000..5e22841d6916
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/13.txt
@@ -0,0 +1,57 @@
+#! /usr/bin/bc -q
+
+define z(a[]) {
+ for (i = 0; i < l; ++i) {
+ a[i]
+ }
+}
+
+define x(a[]) {
+
+ # Test for separate vars and arrays.
+ auto a
+
+ for (a = 0; a < l; ++a) {
+ a[a] = -a
+ }
+
+ z(a[])
+}
+
+define g(x[], y[]) {
+ return x[0] - y[0]
+}
+
+define h(uto, x[]) {
+ return g(x[], y[])
+}
+
+define m(*x[], *y[]) {
+ return x[0] / y[0]
+}
+
+define n(*y[], *x[]) {
+ return m(x[], y[])
+}
+
+for (i = 0; i < 101; ++i) {
+ a[i] = i
+}
+
+a[104] = 204
+
+l = length(a[])
+
+for (i = 0; i <= l; ++i) {
+ a[i]
+}
+
+z(a[])
+x(a[])
+z(a[])
+l
+
+x[0] = 5
+y[0] = 4
+
+h(x[], y[])
diff --git a/contrib/bc/tests/bc/errors/14.txt b/contrib/bc/tests/bc/errors/14.txt
new file mode 100644
index 000000000000..b014e310dd41
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/14.txt
@@ -0,0 +1 @@
+a(int32(O143483647))
diff --git a/contrib/bc/tests/bc/errors/15.txt b/contrib/bc/tests/bc/errors/15.txt
new file mode 100644
index 000000000000..cf1f81dfb005
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/15.txt
@@ -0,0 +1,3 @@
+for (i = 0; int32(29834); ++i) {
+ i
+}
diff --git a/contrib/bc/tests/bc/errors/16.txt b/contrib/bc/tests/bc/errors/16.txt
new file mode 100644
index 000000000000..00a258400871
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/16.txt
@@ -0,0 +1 @@
+"\ \ No newline at end of file
diff --git a/contrib/bc/tests/bc/errors/17.txt b/contrib/bc/tests/bc/errors/17.txt
new file mode 100644
index 000000000000..3f861a018772
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/17.txt
@@ -0,0 +1,313 @@
+print "Gathering array...\n"
+
+s = seed
+
+sum = 0
+
+for (i = 0; i < 100; ++i) {
+ a[i] = rand()
+ sum += a[i]
+ b[i] = irand(sum)
+}
+
+print "Testing implementation...\n"
+
+if (maxrand() >= 2^64 - 1) {
+
+ seed = 54.86785590782347282592869373784717814475564948862907968939159536927733440\
+ 901359008180088183692646452982444316148757934570312500000
+
+ ibase = G
+ obase = G
+
+ for (i = 0; i < 64; ++i) {
+ rand()
+ }
+
+ 7B47F409
+ BA1D3330
+ 83D2F293
+ BFA4784B
+ CBED606E
+ BFC6A3AD
+ 812FFF6D
+ E61F305A
+ F9384B90
+ 32DB86FE
+ 1DC035F9
+ ED786826
+ 3822441D
+ 2BA113D7
+ 1C5B818B
+ A233956A
+ 84DA65E3
+ CED67292
+ B2C0FE06
+ 91817130
+
+ 55FE8917
+ 47E92091
+ 486AF299
+ B1E882BB
+ C261E845
+ 1A9B90F6
+ 7964E884
+ 5F36D7A4
+ 1EE2052D
+ 8519F5D5
+ 293D4E4F
+ 6D8F99FC
+ C3421509
+ A06CD7C6
+ E43064D3
+ E20F9BF0
+ 401B50B7
+ 8EF1FF3E
+ E357E2B2
+ A4AEEE37
+
+ 2AD4426A
+ 9D11BE94
+ 7290C556
+ 6E6F3787
+ 050C2EE3
+ 4FD73703
+ C6FF478B
+ 4B1CA1E1
+ 1654EA91
+ CD08B2F2
+ F7FF3DA8
+ 78B1B8DA
+ A100602C
+ 9588585F
+ DA028873
+ 66B4F376
+ 0E6B4B9A
+ 48167094
+ 0D58CDA0
+ 8F7238BE
+
+ F79983F3
+ 07E5D324
+ AD78DF52
+ 1532BA74
+ 1E4899E2
+ 6C75DF64
+ 171DDC36
+ F2D8D74A
+ 24E6D907
+ 4780FD32
+ 9ADF408C
+ A25544CF
+ EFC6A738
+ 1AA23A54
+ C5A13EBB
+ F739EDC9
+ C3A015FA
+ 3D5E1511
+ AFC4D7FB
+ 3F413B5E
+
+ 4660CB73
+ 88FC773F
+ D6BED59C
+ 63B3B54A
+ D67D3DDE
+ 23394F8B
+ 13384B44
+ DD8B3ABC
+ FF59A21E
+ 3BB16D7E
+ 6E01CB68
+ EC34790E
+ B26C42AD
+ D723C830
+ DFD10FCA
+ 7E362AA1
+ 826FF323
+ CB8F63B5
+ 9B3227E5
+ 9A61E339
+}
+else {
+
+ ibase = G
+ obase = G
+
+ 86B1DA1D72062B68
+ 1304AA46C9853D39
+ A3670E9E0DD50358
+ F9090E529A7DAE00
+ C85B9FD837996F2C
+ 606121F8E3919196
+ 7CE1C7FF478354BA
+ CBC4AC70E541310E
+ 74BE71999EC37F2C
+ B81F9C99A934F1A7
+ 120E9901A900C97F
+ 0F983BAD4B19F493
+ 5934619363660D96
+ D5A7FE2717A2014E
+ 6E437241C9E6676E
+ 6A75C9DD6329CD29
+ 2D9E477683673437
+ 51FB0CF3D4405437
+ 217BB90392D08B20
+ 47C528A018B07A82
+
+ 1B4E474C418C835E
+ BDB2BDA74A119ED6
+ C6DB79D0B9E43493
+ C3CF4834E94A41D1
+ AB8312FC7877C7DC
+ 094B108133E8B5EC
+ 37CA97AC830113BD
+ EF02D7347F9192BF
+ 959517DD9896C53A
+ 7A80EB7629EFE9F9
+ AE53C23F2B1CF57C
+ CA605CD189F6D5CD
+ 921C2704886A9622
+ B68C9FBF826AF7AA
+ 73F8C733124772C3
+ 6B57F7E459EFBCDF
+ 9DE7696DDB6B8E18
+ 02CA67560DC26877
+ A24E353080777DEC
+ 4D600156763FD65C
+
+ 5CDF9C7E26DD2C38
+ 6A32443BBBB16774
+ 3D8415FFECFB8B7F
+ 3090ED9C47@6
+ 6DBF241361C3E652
+ 2CA9EF5A2AD971FC
+ 44FBE937A1CF0FFC
+ DB17CF0577CB7853
+ AA3747D98D31B24C
+ 5D9A104C5D7F43F7
+ BAE65E3E293B2C7B
+ 16A396F0DB4EF984
+ 6DD2BACDC4445A05
+ 7B7A13D1858E5CA8
+ F73722BCAA52447C
+ 31A2C7BBE77CBA00
+ 7FC8AF9003BA1ACE
+ 5703F11DD3F235EF
+ FA1952267EF836C7
+ BBFA558C9E2D51E2
+
+ 3A29661D8145AF36
+ 608DEA6358DABD7C
+ 9E34E9E53431B447
+ 325A05E35EA524EB
+ 63A87CCF0C80ABB1
+ 8EA183287A46F292
+ E2AA5F119CBF2A08
+ 2F3BEB0DE8B730C8
+ 4B8006A928CF8F5B
+ 57B8BA85069C201C
+ 3422D962DDF59474
+ FD744940BA7366A1
+ 23D24B06B5DA4F6F
+ AA187C608319D1DC
+ DC60CA6FEA738B8A
+ C9FC61DF96A769FE
+ 82E2457708658A20
+ 2BECEC9B3E7D93EC
+ 1340DAEC04588952
+ F533446AD5C50B1D
+
+ 31FD1C7F434A62CE
+ D16DAEDD1F281A39
+ 6B5D9648931D7057
+ 62FEE3392DBB06D5
+ 0358BC87B00DF25A
+ F3C882D22946175D
+ 65BA8F11B4516EFE
+ 2DA5A96E626DA4FE
+ DCC669F4CD6121F0
+ 7A47FAC054319CA2
+ 9661CFEE277284C8
+ 01E483A14F4EB23A
+ ADDC115507390607
+ 5AB47C343BD3B0BD
+ 4882FB3A3957B11F
+ 615B7C9C3626DD44
+ F79CF49562969219
+ 88C32C194EA78D27
+ DA8AFFE1353FF352
+ A7A3C331A64CB146
+
+ ibase = A
+
+ seed = 54.0950779151573258314404657465246373249101452529430389404296875000
+
+ ibase = G
+
+ for (i = 0; i < 64; ++i) {
+ rand()
+ }
+}
+
+print "Testing array...\n"
+
+ibase = A
+
+seed = s
+
+sum = 0
+
+for (i = 0; i < 100; ++i) {
+ a[i] == rand()
+ sum += a[i]
+ b[i] == irand(sum)
+}
+
+print "Exercising irand()...\n"
+
+scale = 256
+
+pow = (maxrand() + 1) ^ 4
+s =!2^256 + 2^128 + (irand(pow) / pow)
+seed = s
+seed < s
+
+s = -459.125
+seed = s
+seed == -s
+
+irand(0)
+irand(1)
+seed == -s
+irand(maxrand() + 1) <= maxrand()
+
+for (i = 0; i < 200; ++i) {
+ irand(20) < 20
+}
+
+seed = 738
+seed != 738
+
+s = 2398@0625
+seed = s
+seed != s
+
+pow = (maxrand() + 1) ^ 4
+s = 2^2560 + 2^128 + (irand(pow) / pow)
+seed = s
+seed < s
+
+b = 0
+m = maxrand() + 1
+n = m + 1
+
+for (i = 0; !b && i < 100; ++i) {
+ c = irand(n)
+ b = (c != 0 && c != m)
+ if (c >= n) print "irand() result is too large.\n"
+}
+
+b
+
+sqrt(-1)
diff --git a/contrib/bc/tests/bc/errors/18.txt b/contrib/bc/tests/bc/errors/18.txt
new file mode 100644
index 000000000000..18cde714e872
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/18.txt
@@ -0,0 +1,7 @@
+while (1) {
+
+define x(x) {
+ return x
+}
+
+}
diff --git a/contrib/bc/tests/bc/errors/19.txt b/contrib/bc/tests/bc/errors/19.txt
new file mode 100644
index 000000000000..bc2cf3a91eb5
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/19.txt
@@ -0,0 +1,16 @@
+define i(x) {
+
+i(11)
+ibase
+o(12)`ase
+}
+
+define o(x) {
+ñnbase=x
+ return obage
+}i(11)
+ibase
+_(12)
+obase
+r(15)
+sMale
diff --git a/contrib/bc/tests/bc/errors/20.txt b/contrib/bc/tests/bc/errors/20.txt
new file mode 100644
index 000000000000..db1908537a0b
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/20.txt
@@ -0,0 +1,68 @@
+define w() { auto z; return 1; }
+define x() {
+ "x"
+ return (1)
+}
+define y() {
+ "y"
+ return (2)
+}
+define z() {
+ "z"
+ return (3)
+}
+
+define v() { return }
+
+v()
+
+w()
+
+if (x() == y()) { 1 }
+1
+if (x() <= y()) { 2 }
+if (y() >= x()) { 3 }
+if (x() != y()) { 4 }
+if (x() < y()) { 5 }
+if (y() > x()) { 6 }
+
+if (x() == z()) { 11 }
+11
+if (x() <= z()) { 12 }
+if (z() >= x()) { 13 }
+if (x() != z()) { 14 }
+if (x() < z()) { 15 }
+if (z() > x()) { 16 }
+
+x = -10
+while (x <= 0) {
+ x
+ if (x == -5) break;
+ x += 1
+}
+
+define u() {
+ auto a[];
+ return a[H]
+}
+
+u()
+
+if (x == -4) x
+else x - (i += 1) print "true\ÿÿÿlse print "fal"
+
+i = ÿÿÿhile (i -= 2) print "i: ", i += 1, "\n"
+
+a = 5
+
+for (i = 5; i-= 1; --a) print "i: ", i, "; a: ", a, "\n"
+
+define void t(x, y) {
+ print "x: ", x, "; y: ", y, "\n"
+}
+
+t(i++, i++
+i
+
+t(++i, ++i)
+i
diff --git a/contrib/bc/tests/bc/errors/21.txt b/contrib/bc/tests/bc/errors/21.txt
new file mode 100644
index 000000000000..12d08653d9b5
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/21.txt
Binary files differ
diff --git a/contrib/bc/tests/bc/errors/22.txt b/contrib/bc/tests/bc/errors/22.txt
new file mode 100644
index 000000000000..07ed133da930
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/22.txt
@@ -0,0 +1,5 @@
+#! /\yefine z(a[]) {
+ for (i = 0; i < M; ++i) leiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii= length(aiiiiiiiiiii= l[])
+
+for (i = 0; i <= l\yefine z(a[]) {
+ \ No newline at end of file
diff --git a/contrib/bc/tests/bc/errors/23.txt b/contrib/bc/tests/bc/errors/23.txt
new file mode 100644
index 000000000000..1a42997385ea
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/23.txt
Binary files differ
diff --git a/contrib/bc/tests/bc/errors/24.txt b/contrib/bc/tests/bc/errors/24.txt
new file mode 100644
index 000000000000..0fbfe2762504
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/24.txt
@@ -0,0 +1,9 @@
+perm(10, 2)
+comb(10, 2)
+perm(6, 2)
+comb(6, ++i[])
+}
+
+define m(*x[], *y[]) {
+ r@turn x[0])
+z \ No newline at end of file
diff --git a/contrib/bc/tests/bc/exponent.txt b/contrib/bc/tests/bc/exponent.txt
new file mode 100644
index 000000000000..40bcf3c5a585
--- /dev/null
+++ b/contrib/bc/tests/bc/exponent.txt
@@ -0,0 +1,22 @@
+e(0)
+e(0.5)
+e(1)
+e(1.5)
+e(1.74)
+e(2)
+e(3.2345)
+e(5.283957)
+e(13.23857)
+e(100)
+e(283.238957)
+e(-0.5)
+e(-1)
+e(-1.5)
+e(-1.74)
+e(-2)
+e(-3.2345)
+e(-5.283957)
+e(-13.23857)
+e(-100)
+e(-283.238957)
+e(142.749502399)
diff --git a/contrib/bc/tests/bc/exponent_results.txt b/contrib/bc/tests/bc/exponent_results.txt
new file mode 100644
index 000000000000..a1f1fe2b4cfb
--- /dev/null
+++ b/contrib/bc/tests/bc/exponent_results.txt
@@ -0,0 +1,25 @@
+1.00000000000000000000
+1.64872127070012814684
+2.71828182845904523536
+4.48168907033806482260
+5.69734342267199101193
+7.38905609893065022723
+25.39367176822616278859
+197.14845034328553587817
+561613.96621445383501864766
+26881171418161354484126255515800135873611118.77374192241519160861
+10212124131159922810249757193864245307850725332411569566443792548720\
+75182918653384240389953781407569563117008113027037939783.70141667971\
+570827872
+.60653065971263342360
+.36787944117144232159
+.22313016014842982893
+.17552040061699687169
+.13533528323661269189
+.03937988996342191888
+.00507231985977442865
+.00000178058250000525
+0
+0
+98928445824097165243611240348236907682258759298273030827411201.25833\
+645622510213538
diff --git a/contrib/bc/tests/bc/functions.txt b/contrib/bc/tests/bc/functions.txt
new file mode 100644
index 000000000000..5e540ed66a11
--- /dev/null
+++ b/contrib/bc/tests/bc/functions.txt
@@ -0,0 +1,13 @@
+define x(x, y) {
+ return x - y + 5
+}
+
+define y(y, x) {
+ return x(y, x) + x(x, y)
+}
+
+y(1, 4)
+y(2, 4)
+y(3, 4)
+y(4, 3)
+y(3, 2)
diff --git a/contrib/bc/tests/bc/functions_results.txt b/contrib/bc/tests/bc/functions_results.txt
new file mode 100644
index 000000000000..f5c1b1de44a4
--- /dev/null
+++ b/contrib/bc/tests/bc/functions_results.txt
@@ -0,0 +1,5 @@
+10
+10
+10
+10
+10
diff --git a/contrib/bc/tests/bc/globals.txt b/contrib/bc/tests/bc/globals.txt
new file mode 100644
index 000000000000..4b20f5725864
--- /dev/null
+++ b/contrib/bc/tests/bc/globals.txt
@@ -0,0 +1,21 @@
+define i(x) {
+ ibase=x
+ return ibase
+}
+
+define o(x) {
+ obase=x
+ return obase
+}
+
+define r(x) {
+ scale=x
+ return scale
+}
+
+i(11)
+ibase
+o(12)
+obase
+r(15)
+scale
diff --git a/contrib/bc/tests/bc/globals_results.txt b/contrib/bc/tests/bc/globals_results.txt
new file mode 100644
index 000000000000..bf756acbe50d
--- /dev/null
+++ b/contrib/bc/tests/bc/globals_results.txt
@@ -0,0 +1,6 @@
+11
+11
+10
+10
+13
+13
diff --git a/contrib/bc/tests/bc/length.txt b/contrib/bc/tests/bc/length.txt
new file mode 100644
index 000000000000..5461f76cbf59
--- /dev/null
+++ b/contrib/bc/tests/bc/length.txt
@@ -0,0 +1,129 @@
+length(0)
+length(1)
+length(12)
+length(123)
+length(1234)
+length(12345)
+length(123456)
+length(1234567)
+length(12345678)
+length(123456789)
+length(1234567890)
+length(1.0)
+length(12.0)
+length(123.0)
+length(1234.0)
+length(12345.0)
+length(123456.0)
+length(1234567.0)
+length(12345678.0)
+length(123456789.0)
+length(1234567890.0)
+length(.1)
+length(.12)
+length(.123)
+length(.1234)
+length(.12345)
+length(.123456)
+length(.1234567)
+length(.12345678)
+length(.123456789)
+length(.1234567890)
+length(.01)
+length(.012)
+length(.0123)
+length(.01234)
+length(.012345)
+length(.0123456)
+length(.01234567)
+length(.012345678)
+length(.0123456789)
+length(.01234567890)
+length(.001)
+length(.0012)
+length(.00123)
+length(.001234)
+length(.0012345)
+length(.00123456)
+length(.001234567)
+length(.0012345678)
+length(.00123456789)
+length(.001234567890)
+length(.0001)
+length(.00012)
+length(.000123)
+length(.0001234)
+length(.00012345)
+length(.000123456)
+length(.0001234567)
+length(.00012345678)
+length(.000123456789)
+length(.0001234567890)
+length(.00001)
+length(.000012)
+length(.0000123)
+length(.00001234)
+length(.000012345)
+length(.0000123456)
+length(.00001234567)
+length(.000012345678)
+length(.0000123456789)
+length(.00001234567890)
+length(.000001)
+length(.0000012)
+length(.00000123)
+length(.000001234)
+length(.0000012345)
+length(.00000123456)
+length(.000001234567)
+length(.0000012345678)
+length(.00000123456789)
+length(.000001234567890)
+length(.0000001)
+length(.00000012)
+length(.000000123)
+length(.0000001234)
+length(.00000012345)
+length(.000000123456)
+length(.0000001234567)
+length(.00000012345678)
+length(.000000123456789)
+length(.0000001234567890)
+length(.00000001)
+length(.000000012)
+length(.0000000123)
+length(.00000001234)
+length(.000000012345)
+length(.0000000123456)
+length(.00000001234567)
+length(.000000012345678)
+length(.0000000123456789)
+length(.00000001234567890)
+length(.000000001)
+length(.0000000012)
+length(.00000000123)
+length(.000000001234)
+length(.0000000012345)
+length(.00000000123456)
+length(.000000001234567)
+length(.0000000012345678)
+length(.00000000123456789)
+length(.000000001234567890)
+length(.0000000001)
+length(.00000000012)
+length(.000000000123)
+length(.0000000001234)
+length(.00000000012345)
+length(.000000000123456)
+length(.0000000001234567)
+length(.00000000012345678)
+length(.000000000123456789)
+length(.0000000001234567890)
+length(289.29837)
+length(2893.00000)
+length(289.0)
+length(1802973.0000000238)
+length(.000000000000000093182394080000000000)
+a[0] = 0
+a[5] = 0
+length(a[])
diff --git a/contrib/bc/tests/bc/length_results.txt b/contrib/bc/tests/bc/length_results.txt
new file mode 100644
index 000000000000..53a58e2be678
--- /dev/null
+++ b/contrib/bc/tests/bc/length_results.txt
@@ -0,0 +1,127 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+8
+9
+4
+17
+20
+6
diff --git a/contrib/bc/tests/bc/letters.txt b/contrib/bc/tests/bc/letters.txt
new file mode 100644
index 000000000000..88993cd26fc4
--- /dev/null
+++ b/contrib/bc/tests/bc/letters.txt
@@ -0,0 +1,53 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+A
+B
+C
+D
+E
+F
+G
+H
+I
+J
+K
+L
+M
+N
+O
+P
+Q
+R
+S
+T
+U
+V
+W
+X
+Y
+Z
+AA
+ZZ
+ibase=B
+AA
+AB
+ZZ
+ibase=G
+AA
+AB
+B0
+Y0
+Y1
+YY
+YZ
+ZE
+ZF
+ZG
diff --git a/contrib/bc/tests/bc/letters_results.txt b/contrib/bc/tests/bc/letters_results.txt
new file mode 100644
index 000000000000..4f052f78c52f
--- /dev/null
+++ b/contrib/bc/tests/bc/letters_results.txt
@@ -0,0 +1,51 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+99
+99
+120
+120
+120
+170
+171
+176
+240
+241
+255
+255
+254
+255
+255
diff --git a/contrib/bc/tests/bc/lib2.txt b/contrib/bc/tests/bc/lib2.txt
new file mode 100644
index 000000000000..9fdf50d06141
--- /dev/null
+++ b/contrib/bc/tests/bc/lib2.txt
@@ -0,0 +1,463 @@
+p(2, 8.0000)
+p(2, 8.0001)
+p(2, -8.0001)
+r(0, 0)
+r(0, 1)
+r(0, 100)
+r(1, 0)
+r(1, 3)
+r(1.4, 0)
+r(1.5, 0)
+r(34.45, 2)
+r(64.1223, 4)
+r(283.1983893, 6)
+r(283.1983895, 6)
+r(283.1983899, 6)
+r(99.999999999, 5)
+r(-1, 0)
+r(-1, 3)
+r(-1.4, 0)
+r(-1.5, 0)
+r(-34.45, 2)
+r(-64.1223, 4)
+r(-283.1983893, 6)
+r(-283.1983895, 6)
+r(-283.1983899, 6)
+r(-99.999999999, 5)
+ceil(0, 0)
+ceil(0, 1)
+ceil(0, 100)
+ceil(1, 0)
+ceil(1, 3)
+ceil(1.4, 0)
+ceil(1.5, 0)
+ceil(34.45, 2)
+ceil(64.1223, 4)
+ceil(283.1983893, 6)
+ceil(283.1983895, 6)
+ceil(283.1983899, 6)
+ceil(99.999999999, 5)
+ceil(-1, 0)
+ceil(-1, 3)
+ceil(-1.4, 0)
+ceil(-1.5, 0)
+ceil(-34.45, 2)
+ceil(-64.1223, 4)
+ceil(-283.1983893, 6)
+ceil(-283.1983895, 6)
+ceil(-283.1983899, 6)
+ceil(-99.999999999, 5)
+ceil(8770735.0705156250000000000, 0)
+l2(0)
+l2(1)
+l2(2)
+l2(7)
+l2(7.9999999999999999999999)
+l2(8)
+l10(0)
+l10(1)
+l10(2)
+l10(5)
+l10(9)
+l10(9.999999999999999999999)
+l10(10)
+l10(11)
+l10(99)
+l10(99.99999999999999999999)
+l10(100)
+l2(-1)
+l2(-2)
+l2(-7)
+l2(-7.9999999999999999999999)
+l2(-8)
+l10(-1)
+l10(-2)
+l10(-5)
+l10(-9)
+l10(-9.999999999999999999999)
+l10(-10)
+l10(-11)
+l10(-99)
+l10(-99.99999999999999999999)
+l10(-100)
+cbrt(27)
+cbrt(-27)
+cbrt(4096)
+cbrt(-4096)
+root(16, 4)
+root(3125, 5)
+root(-3125, 5)
+ubytes(0)
+ubytes(1)
+ubytes(2)
+ubytes(254)
+ubytes(255)
+ubytes(256)
+ubytes(65535)
+ubytes(65536)
+ubytes(131072)
+ubytes(4294967295)
+ubytes(4294967296)
+ubytes(18446744073709551615)
+ubytes(18446744073709551616)
+sbytes(0)
+sbytes(1)
+sbytes(-1)
+sbytes(2)
+sbytes(127)
+sbytes(128)
+sbytes(-127)
+sbytes(-128)
+sbytes(-129)
+sbytes(254)
+sbytes(255)
+sbytes(256)
+sbytes(32767)
+sbytes(32768)
+sbytes(-32767)
+sbytes(-32768)
+sbytes(65535)
+sbytes(65536)
+sbytes(131072)
+sbytes(2147483647)
+sbytes(2147483648)
+sbytes(2147483649)
+sbytes(-2147483647)
+sbytes(-2147483648)
+sbytes(-2147483649)
+sbytes(4294967295)
+sbytes(4294967296)
+sbytes(9223372036854775807)
+sbytes(9223372036854775808)
+sbytes(9223372036854775809)
+sbytes(-9223372036854775807)
+sbytes(-9223372036854775808)
+sbytes(-9223372036854775809)
+pi(0)
+pi(1)
+pi(2)
+pi(5)
+pi(100)
+p=pi(100)
+t(0)
+t(1)
+t(-1)
+t(2)
+t(-2)
+t(3)
+t(-3)
+t(p)
+t(-p)
+t(p/2)
+t(-p/2)
+t(p/3)
+t(-p/3)
+t(p/4)
+t(-p/4)
+t(p/5)
+t(-p/5)
+t(p/6)
+t(-p/6)
+t(p/7)
+t(-p/7)
+t(p/8)
+t(-p/8)
+t(p/9)
+t(-p/9)
+t(p/10)
+t(-p/10)
+t(p/15)
+t(-p/15)
+a2(0, 1)
+a2(1, 1)
+a2(2, 1)
+a2(1, 2)
+a2(0, -1)
+a2(1, -1)
+a2(2, -1)
+a2(1, -2)
+a2(-1, 1)
+a2(-2, 1)
+a2(-1, 2)
+a2(-1, -1)
+a2(-2, -1)
+a2(-1, -2)
+a2(1, 0)
+a2(2, 0)
+a2(-1, 0)
+a2(-2, 0)
+r2d(p)
+r2d(2 * p)
+r2d(p / 2)
+r2d(p / 4)
+r2d(p / 3)
+r2d(p / 5)
+r2d(p / 6)
+r2d(p / 10)
+r2d(-p)
+r2d(2 * -p)
+r2d(-p / 2)
+r2d(-p / 4)
+r2d(-p / 3)
+r2d(-p / 5)
+r2d(-p / 6)
+r2d(-p / 10)
+d2r(180)
+d2r(360)
+d2r(90)
+d2r(45)
+d2r(120)
+d2r(72)
+d2r(60)
+d2r(36)
+d2r(-180)
+d2r(-360)
+d2r(-90)
+d2r(-45)
+d2r(-120)
+d2r(-72)
+d2r(-60)
+d2r(-36)
+f(0)
+f(1)
+f(2)
+f(3)
+f(4)
+f(5)
+perm(10, 2)
+comb(10, 2)
+perm(6, 2)
+comb(6, 2)
+perm(12, 10)
+comb(12, 10)
+perm(24, 15)
+comb(24, 15)
+binary(0)
+hex(0)
+binary(1)
+hex(1)
+binary(2)
+hex(2)
+binary(15)
+hex(15)
+binary(16)
+hex(16)
+uint(0)
+int(0)
+uint(1)
+int(1)
+int(-1)
+uint(127)
+int(127)
+int(-127)
+uint(128)
+int(128)
+int(-128)
+uint(129)
+int(129)
+int(-129)
+uint(255)
+int(255)
+int(-255)
+uint(256)
+int(256)
+int(-256)
+uint(32767)
+int(32767)
+int(-32767)
+uint(32768)
+int(32768)
+int(-32768)
+uint(32769)
+int(32769)
+int(-32769)
+uint(65535)
+int(65535)
+int(-65535)
+uint(65536)
+int(65536)
+int(-65536)
+uint(2147483647)
+int(2147483647)
+int(-2147483647)
+uint(2147483648)
+int(2147483648)
+int(-2147483648)
+uint(2147483649)
+int(2147483649)
+int(-2147483649)
+uint(4294967295)
+int(4294967295)
+int(-4294967295)
+uint(4294967296)
+int(4294967296)
+int(-4294967296)
+uint8(0)
+int8(0)
+uint16(0)
+int16(0)
+uint32(0)
+int32(0)
+uint64(0)
+int64(0)
+uint8(1)
+int8(1)
+int8(-1)
+uint16(1)
+int16(1)
+int16(-1)
+uint32(1)
+int32(1)
+int32(-1)
+uint64(1)
+int64(1)
+int64(-1)
+uint8(127)
+int8(127)
+int8(-127)
+uint16(127)
+int16(127)
+int16(-127)
+uint32(127)
+int32(127)
+int32(-127)
+uint64(127)
+int64(127)
+int64(-127)
+uint8(128)
+int8(128)
+int8(-128)
+uint16(128)
+int16(128)
+int16(-128)
+uint32(128)
+int32(128)
+int32(-128)
+uint64(128)
+int64(128)
+int64(-128)
+uint8(129)
+int8(129)
+int8(-129)
+uint16(129)
+int16(129)
+int16(-129)
+uint32(129)
+int32(129)
+int32(-129)
+uint64(129)
+int64(129)
+int64(-129)
+uint8(255)
+int8(255)
+int8(-255)
+uint16(255)
+int16(255)
+int16(-255)
+uint32(255)
+int32(255)
+int32(-255)
+uint64(255)
+int64(255)
+int64(-255)
+uint8(256)
+int8(256)
+int8(-256)
+uint16(256)
+int16(256)
+int16(-256)
+uint32(256)
+int32(256)
+int32(-256)
+uint64(256)
+int64(256)
+int64(-256)
+uint16(32767)
+int16(32767)
+int16(-32767)
+uint32(32767)
+int32(32767)
+int32(-32767)
+uint64(32767)
+int64(32767)
+int64(-32767)
+uint16(32768)
+int16(32768)
+int16(-32768)
+uint32(32768)
+int32(32768)
+int32(-32768)
+uint64(32768)
+int64(32768)
+int64(-32768)
+uint16(32769)
+int16(32769)
+int16(-32769)
+uint32(32769)
+int32(32769)
+int32(-32769)
+uint64(32769)
+int64(32769)
+int64(-32769)
+uint16(65535)
+int16(65535)
+int16(-65535)
+uint32(65535)
+int32(65535)
+int32(-65535)
+uint64(65535)
+int64(65535)
+int64(-65535)
+uint16(65536)
+int16(65536)
+int16(-65536)
+uint32(65536)
+int32(65536)
+int32(-65536)
+uint64(65536)
+int64(65536)
+int64(-65536)
+uint32(2147483647)
+int32(2147483647)
+int32(-2147483647)
+uint64(2147483647)
+int64(2147483647)
+int64(-2147483647)
+uint32(2147483648)
+int32(2147483648)
+int32(-2147483648)
+uint64(2147483648)
+int64(2147483648)
+int64(-2147483648)
+uint32(2147483649)
+int32(2147483649)
+int32(-2147483649)
+uint64(2147483649)
+int64(2147483649)
+int64(-2147483649)
+uint32(4294967295)
+int32(4294967295)
+int32(-4294967295)
+uint64(4294967295)
+int64(4294967295)
+int64(-4294967295)
+uint32(4294967296)
+int32(4294967296)
+int32(-4294967296)
+uint64(4294967296)
+int64(4294967296)
+int64(-4294967296)
+uint(-3)
+uint(3.928375)
+int(4.000000)
+b = brand()
+b < 2
+b >= 0
+i = irand(maxrand() + 1)
+i <= maxrand()
+i >= 0
+f = frand(10)
+scale(f) == 10
+fi = ifrand(123, 28)
+scale(fi) == 28
+fi < 128
diff --git a/contrib/bc/tests/bc/lib2_results.txt b/contrib/bc/tests/bc/lib2_results.txt
new file mode 100644
index 000000000000..ca5a37cfce0a
--- /dev/null
+++ b/contrib/bc/tests/bc/lib2_results.txt
@@ -0,0 +1,698 @@
+256.00000000000000000000
+256.01774518281640169821
+.00390597924876622489
+0
+0
+0
+1
+1.000
+1
+2
+34.45
+64.1223
+283.198389
+283.198390
+283.198390
+100.00000
+-1
+-1.000
+-1
+-2
+-34.45
+-64.1223
+-283.198389
+-283.198390
+-283.198390
+-100.00000
+0
+0
+0
+1
+1.000
+2
+2
+34.45
+64.1223
+283.198390
+283.198390
+283.198390
+100.00000
+-1
+-1.000
+-2
+-2
+-34.45
+-64.1223
+-283.198390
+-283.198390
+-283.198390
+-100.00000
+8770736
+-14426950408889634073599246810018921374265.01964302164603717234
+0
+1.00000000000000000000
+2.80735492205760410744
+2.99999999999999999999
+3.00000000000000000000
+-4342944819032518276511289189166050822943.53857128275332257904
+0
+.30102999566398119521
+.69897000433601880478
+.95424250943932487459
+.99999999999999999999
+1.00000000000000000000
+1.04139268515822504075
+1.99563519459754991534
+1.99999999999999999999
+2.00000000000000000000
+-14426950408889634073599246810018921374265.01964302164603717234
+-14426950408889634073599246810018921374265.01964302164603717234
+-14426950408889634073599246810018921374265.01964302164603717234
+-144269504088896340735992468100189213742664594.88013355604393225658
+-14426950408889634073599246810018921374265.01964302164603717234
+-4342944819032518276511289189166050822943.53857128275332257904
+-4342944819032518276511289189166050822943.53857128275332257904
+-4342944819032518276511289189166050822943.53857128275332257904
+-4342944819032518276511289189166050822943.53857128275332257904
+-434294481903251827651128918916605082294396.66367028674257491242
+-4342944819032518276511289189166050822943.53857128275332257904
+-4342944819032518276511289189166050822943.53857128275332257904
+-4342944819032518276511289189166050822943.53857128275332257904
+-4342944819032518276511289189166050822943.53857128275332257904
+-4342944819032518276511289189166050822943.53857128275332257904
+3.00000000000000000000
+-3.00000000000000000000
+16.00000000000000000000
+-16.00000000000000000000
+2.00000000000000000000
+5.00000000000000000000
+-5.00000000000000000000
+1
+1
+1
+1
+1
+2
+2
+4
+4
+4
+8
+8
+16
+1
+1
+1
+1
+1
+2
+1
+1
+2
+2
+2
+2
+2
+4
+2
+2
+4
+4
+4
+4
+8
+8
+4
+4
+8
+8
+8
+8
+16
+16
+8
+8
+16
+3
+3.1
+3.14
+3.14159
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089986280348253421170679
+0
+1.55740772465490223050
+-1.55740772465490223050
+-2.18503986326151899164
+2.18503986326151899164
+-.14254654307427780529
+.14254654307427780529
+0
+0
+769230769230769230769.23076923076923076923
+-769230769230769230769.23076923076923076923
+1.73205080756887729351
+-1.73205080756887729351
+.99999999999999999998
+-.99999999999999999998
+.72654252800536088589
+-.72654252800536088589
+.57735026918962576449
+-.57735026918962576449
+.48157461880752864432
+-.48157461880752864432
+.41421356237309504879
+-.41421356237309504879
+.36397023426620236134
+-.36397023426620236134
+.32491969623290632614
+-.32491969623290632614
+.21255656167002212525
+-.21255656167002212525
+0
+.78539816339744830961
+1.10714871779409050301
+.46364760900080611621
+3.14159265358979323846
+2.35619449019234492884
+2.03444393579570273544
+2.67794504458898712224
+-.78539816339744830961
+-1.10714871779409050301
+-.46364760900080611621
+-2.35619449019234492884
+-2.03444393579570273544
+-2.67794504458898712224
+1.57079632679489661923
+1.57079632679489661923
+-1.57079632679489661923
+-1.57079632679489661923
+180.00000000000000000000
+360.00000000000000000000
+89.99999999999999999992
+44.99999999999999999967
+59.99999999999999999975
+35.99999999999999999985
+29.99999999999999999959
+17.99999999999999999964
+-180.00000000000000000000
+-360.00000000000000000000
+-89.99999999999999999992
+-44.99999999999999999967
+-59.99999999999999999975
+-35.99999999999999999985
+-29.99999999999999999959
+-17.99999999999999999964
+3.14159265358979323846
+6.28318530717958647692
+1.57079632679489661923
+.78539816339744830961
+2.09439510239319549230
+1.25663706143591729538
+1.04719755119659774615
+.62831853071795864769
+-3.14159265358979323846
+-6.28318530717958647692
+-1.57079632679489661923
+-.78539816339744830961
+-2.09439510239319549230
+-1.25663706143591729538
+-1.04719755119659774615
+-.62831853071795864769
+1
+1
+2
+6
+24
+120
+90
+45
+30
+15
+239500800
+66
+1709789466857472000
+1307504
+0
+0
+1
+1
+10
+2
+1111
+F
+10000
+10
+00000000
+00
+00000000
+00
+00000001
+01
+00000001
+01
+11111111
+FF
+01111111
+7F
+01111111
+7F
+10000001
+81
+10000000
+80
+00000000 10000000
+00 80
+10000000
+80
+10000001
+81
+00000000 10000001
+00 81
+11111111 01111111
+FF 7F
+11111111
+FF
+00000000 11111111
+00 FF
+11111111 00000001
+FF 01
+00000001 00000000
+01 00
+00000001 00000000
+01 00
+11111111 00000000
+FF 00
+01111111 11111111
+7F FF
+01111111 11111111
+7F FF
+10000000 00000001
+80 01
+10000000 00000000
+80 00
+00000000 00000000 10000000 00000000
+00 00 80 00
+10000000 00000000
+80 00
+10000000 00000001
+80 01
+00000000 00000000 10000000 00000001
+00 00 80 01
+11111111 11111111 01111111 11111111
+FF FF 7F FF
+11111111 11111111
+FF FF
+00000000 00000000 11111111 11111111
+00 00 FF FF
+11111111 11111111 00000000 00000001
+FF FF 00 01
+00000000 00000001 00000000 00000000
+00 01 00 00
+00000000 00000001 00000000 00000000
+00 01 00 00
+11111111 11111111 00000000 00000000
+FF FF 00 00
+01111111 11111111 11111111 11111111
+7F FF FF FF
+01111111 11111111 11111111 11111111
+7F FF FF FF
+10000000 00000000 00000000 00000001
+80 00 00 01
+10000000 00000000 00000000 00000000
+80 00 00 00
+00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000\
+000
+00 00 00 00 80 00 00 00
+10000000 00000000 00000000 00000000
+80 00 00 00
+10000000 00000000 00000000 00000001
+80 00 00 01
+00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000\
+001
+00 00 00 00 80 00 00 01
+11111111 11111111 11111111 11111111 01111111 11111111 11111111 11111\
+111
+FF FF FF FF 7F FF FF FF
+11111111 11111111 11111111 11111111
+FF FF FF FF
+00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111\
+111
+00 00 00 00 FF FF FF FF
+11111111 11111111 11111111 11111111 00000000 00000000 00000000 00000\
+001
+FF FF FF FF 00 00 00 01
+00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000\
+000
+00 00 00 01 00 00 00 00
+00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000\
+000
+00 00 00 01 00 00 00 00
+11111111 11111111 11111111 11111111 00000000 00000000 00000000 00000\
+000
+FF FF FF FF 00 00 00 00
+00000000
+00
+00000000
+00
+00000000 00000000
+00 00
+00000000 00000000
+00 00
+00000000 00000000 00000000 00000000
+00 00 00 00
+00000000 00000000 00000000 00000000
+00 00 00 00
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000\
+000
+00 00 00 00 00 00 00 00
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000\
+000
+00 00 00 00 00 00 00 00
+00000001
+01
+00000001
+01
+11111111
+FF
+00000000 00000001
+00 01
+00000000 00000001
+00 01
+11111111 11111111
+FF FF
+00000000 00000000 00000000 00000001
+00 00 00 01
+00000000 00000000 00000000 00000001
+00 00 00 01
+11111111 11111111 11111111 11111111
+FF FF FF FF
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000\
+001
+00 00 00 00 00 00 00 01
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000\
+001
+00 00 00 00 00 00 00 01
+11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111\
+111
+FF FF FF FF FF FF FF FF
+01111111
+7F
+01111111
+7F
+10000001
+81
+00000000 01111111
+00 7F
+00000000 01111111
+00 7F
+11111111 10000001
+FF 81
+00000000 00000000 00000000 01111111
+00 00 00 7F
+00000000 00000000 00000000 01111111
+00 00 00 7F
+11111111 11111111 11111111 10000001
+FF FF FF 81
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 01111\
+111
+00 00 00 00 00 00 00 7F
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 01111\
+111
+00 00 00 00 00 00 00 7F
+11111111 11111111 11111111 11111111 11111111 11111111 11111111 10000\
+001
+FF FF FF FF FF FF FF 81
+10000000
+80
+Error: 128 cannot fit into 1 signed byte(s).
+10000000
+80
+00000000 10000000
+00 80
+00000000 10000000
+00 80
+11111111 10000000
+FF 80
+00000000 00000000 00000000 10000000
+00 00 00 80
+00000000 00000000 00000000 10000000
+00 00 00 80
+11111111 11111111 11111111 10000000
+FF FF FF 80
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 10000\
+000
+00 00 00 00 00 00 00 80
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 10000\
+000
+00 00 00 00 00 00 00 80
+11111111 11111111 11111111 11111111 11111111 11111111 11111111 10000\
+000
+FF FF FF FF FF FF FF 80
+10000001
+81
+Error: 129 cannot fit into 1 signed byte(s).
+Error: -129 cannot fit into 1 signed byte(s).
+00000000 10000001
+00 81
+00000000 10000001
+00 81
+11111111 01111111
+FF 7F
+00000000 00000000 00000000 10000001
+00 00 00 81
+00000000 00000000 00000000 10000001
+00 00 00 81
+11111111 11111111 11111111 01111111
+FF FF FF 7F
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 10000\
+001
+00 00 00 00 00 00 00 81
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 10000\
+001
+00 00 00 00 00 00 00 81
+11111111 11111111 11111111 11111111 11111111 11111111 11111111 01111\
+111
+FF FF FF FF FF FF FF 7F
+11111111
+FF
+Error: 255 cannot fit into 1 signed byte(s).
+Error: -255 cannot fit into 1 signed byte(s).
+00000000 11111111
+00 FF
+00000000 11111111
+00 FF
+11111111 00000001
+FF 01
+00000000 00000000 00000000 11111111
+00 00 00 FF
+00000000 00000000 00000000 11111111
+00 00 00 FF
+11111111 11111111 11111111 00000001
+FF FF FF 01
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111\
+111
+00 00 00 00 00 00 00 FF
+00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111\
+111
+00 00 00 00 00 00 00 FF
+11111111 11111111 11111111 11111111 11111111 11111111 11111111 00000\
+001
+FF FF FF FF FF FF FF 01
+Error: 256 cannot fit into 1 unsigned byte(s).
+Error: 256 cannot fit into 1 signed byte(s).
+Error: -256 cannot fit into 1 signed byte(s).
+00000001 00000000
+01 00
+00000001 00000000
+01 00
+11111111 00000000
+FF 00
+00000000 00000000 00000001 00000000
+00 00 01 00
+00000000 00000000 00000001 00000000
+00 00 01 00
+11111111 11111111 11111111 00000000
+FF FF FF 00
+00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000\
+000
+00 00 00 00 00 00 01 00
+00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000\
+000
+00 00 00 00 00 00 01 00
+11111111 11111111 11111111 11111111 11111111 11111111 11111111 00000\
+000
+FF FF FF FF FF FF FF 00
+01111111 11111111
+7F FF
+01111111 11111111
+7F FF
+10000000 00000001
+80 01
+00000000 00000000 01111111 11111111
+00 00 7F FF
+00000000 00000000 01111111 11111111
+00 00 7F FF
+11111111 11111111 10000000 00000001
+FF FF 80 01
+00000000 00000000 00000000 00000000 00000000 00000000 01111111 11111\
+111
+00 00 00 00 00 00 7F FF
+00000000 00000000 00000000 00000000 00000000 00000000 01111111 11111\
+111
+00 00 00 00 00 00 7F FF
+11111111 11111111 11111111 11111111 11111111 11111111 10000000 00000\
+001
+FF FF FF FF FF FF 80 01
+10000000 00000000
+80 00
+Error: 32768 cannot fit into 2 signed byte(s).
+10000000 00000000
+80 00
+00000000 00000000 10000000 00000000
+00 00 80 00
+00000000 00000000 10000000 00000000
+00 00 80 00
+11111111 11111111 10000000 00000000
+FF FF 80 00
+00000000 00000000 00000000 00000000 00000000 00000000 10000000 00000\
+000
+00 00 00 00 00 00 80 00
+00000000 00000000 00000000 00000000 00000000 00000000 10000000 00000\
+000
+00 00 00 00 00 00 80 00
+11111111 11111111 11111111 11111111 11111111 11111111 10000000 00000\
+000
+FF FF FF FF FF FF 80 00
+10000000 00000001
+80 01
+Error: 32769 cannot fit into 2 signed byte(s).
+Error: -32769 cannot fit into 2 signed byte(s).
+00000000 00000000 10000000 00000001
+00 00 80 01
+00000000 00000000 10000000 00000001
+00 00 80 01
+11111111 11111111 01111111 11111111
+FF FF 7F FF
+00000000 00000000 00000000 00000000 00000000 00000000 10000000 00000\
+001
+00 00 00 00 00 00 80 01
+00000000 00000000 00000000 00000000 00000000 00000000 10000000 00000\
+001
+00 00 00 00 00 00 80 01
+11111111 11111111 11111111 11111111 11111111 11111111 01111111 11111\
+111
+FF FF FF FF FF FF 7F FF
+11111111 11111111
+FF FF
+Error: 65535 cannot fit into 2 signed byte(s).
+Error: -65535 cannot fit into 2 signed byte(s).
+00000000 00000000 11111111 11111111
+00 00 FF FF
+00000000 00000000 11111111 11111111
+00 00 FF FF
+11111111 11111111 00000000 00000001
+FF FF 00 01
+00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111\
+111
+00 00 00 00 00 00 FF FF
+00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111\
+111
+00 00 00 00 00 00 FF FF
+11111111 11111111 11111111 11111111 11111111 11111111 00000000 00000\
+001
+FF FF FF FF FF FF 00 01
+Error: 65536 cannot fit into 2 unsigned byte(s).
+Error: 65536 cannot fit into 2 signed byte(s).
+Error: -65536 cannot fit into 2 signed byte(s).
+00000000 00000001 00000000 00000000
+00 01 00 00
+00000000 00000001 00000000 00000000
+00 01 00 00
+11111111 11111111 00000000 00000000
+FF FF 00 00
+00000000 00000000 00000000 00000000 00000000 00000001 00000000 00000\
+000
+00 00 00 00 00 01 00 00
+00000000 00000000 00000000 00000000 00000000 00000001 00000000 00000\
+000
+00 00 00 00 00 01 00 00
+11111111 11111111 11111111 11111111 11111111 11111111 00000000 00000\
+000
+FF FF FF FF FF FF 00 00
+01111111 11111111 11111111 11111111
+7F FF FF FF
+01111111 11111111 11111111 11111111
+7F FF FF FF
+10000000 00000000 00000000 00000001
+80 00 00 01
+00000000 00000000 00000000 00000000 01111111 11111111 11111111 11111\
+111
+00 00 00 00 7F FF FF FF
+00000000 00000000 00000000 00000000 01111111 11111111 11111111 11111\
+111
+00 00 00 00 7F FF FF FF
+11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000\
+001
+FF FF FF FF 80 00 00 01
+10000000 00000000 00000000 00000000
+80 00 00 00
+Error: 2147483648 cannot fit into 4 signed byte(s).
+10000000 00000000 00000000 00000000
+80 00 00 00
+00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000\
+000
+00 00 00 00 80 00 00 00
+00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000\
+000
+00 00 00 00 80 00 00 00
+11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000\
+000
+FF FF FF FF 80 00 00 00
+10000000 00000000 00000000 00000001
+80 00 00 01
+Error: 2147483649 cannot fit into 4 signed byte(s).
+Error: -2147483649 cannot fit into 4 signed byte(s).
+00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000\
+001
+00 00 00 00 80 00 00 01
+00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000\
+001
+00 00 00 00 80 00 00 01
+11111111 11111111 11111111 11111111 01111111 11111111 11111111 11111\
+111
+FF FF FF FF 7F FF FF FF
+11111111 11111111 11111111 11111111
+FF FF FF FF
+Error: 4294967295 cannot fit into 4 signed byte(s).
+Error: -4294967295 cannot fit into 4 signed byte(s).
+00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111\
+111
+00 00 00 00 FF FF FF FF
+00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111\
+111
+00 00 00 00 FF FF FF FF
+11111111 11111111 11111111 11111111 00000000 00000000 00000000 00000\
+001
+FF FF FF FF 00 00 00 01
+Error: 4294967296 cannot fit into 4 unsigned byte(s).
+Error: 4294967296 cannot fit into 4 signed byte(s).
+Error: -4294967296 cannot fit into 4 signed byte(s).
+00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000\
+000
+00 00 00 01 00 00 00 00
+00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000\
+000
+00 00 00 01 00 00 00 00
+11111111 11111111 11111111 11111111 00000000 00000000 00000000 00000\
+000
+FF FF FF FF 00 00 00 00
+Error: -3 is negative.
+Error: 3.928375 is not an integer.
+Error: 4.000000 is not an integer.
+1
+1
+1
+1
+1
+1
+1
diff --git a/contrib/bc/tests/bc/log.txt b/contrib/bc/tests/bc/log.txt
new file mode 100644
index 000000000000..54115e380ec7
--- /dev/null
+++ b/contrib/bc/tests/bc/log.txt
@@ -0,0 +1,22 @@
+l(0)
+l(0.5)
+l(1)
+l(1.5)
+l(1.74)
+l(2)
+l(3.2345)
+l(5.283957)
+l(13.23857)
+l(100)
+l(283.238957)
+l(-0.5)
+l(-1)
+l(-1.5)
+l(-1.74)
+l(-2)
+l(-3.2345)
+l(-5.283957)
+l(-13.23857)
+l(-100)
+l(-283.238957)
+l(10430710.3325472917)
diff --git a/contrib/bc/tests/bc/log_results.txt b/contrib/bc/tests/bc/log_results.txt
new file mode 100644
index 000000000000..ce840a0d9e94
--- /dev/null
+++ b/contrib/bc/tests/bc/log_results.txt
@@ -0,0 +1,22 @@
+-99999999999999999999.00000000000000000000
+-.69314718055994530941
+0
+.40546510810816438197
+.55388511322643765995
+.69314718055994530941
+1.17387435650190306676
+1.66467524885255369652
+2.58313453863349348434
+4.60517018598809136803
+5.64629091238730017971
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+-99999999999999999999.00000000000000000000
+16.16026492940839137014
diff --git a/contrib/bc/tests/bc/misc.txt b/contrib/bc/tests/bc/misc.txt
new file mode 100644
index 000000000000..571f4a87e262
--- /dev/null
+++ b/contrib/bc/tests/bc/misc.txt
@@ -0,0 +1,13 @@
+4.1*1.-13^ - 74 - 1284597623841*1.-13^ - 757
+4.1*1.\
+-1\
+3^ - 74 - 1284597623841*1.\
+-1\
+3^ - 757
+obase = 9
+4.1*1.-13^ - 74 - 1284597623841*1.-13^ - 757
+4.1*1.\
+-1\
+3^ - 74 - 1284597623841*1.\
+-1\
+3^ - 757
diff --git a/contrib/bc/tests/bc/misc1.txt b/contrib/bc/tests/bc/misc1.txt
new file mode 100644
index 000000000000..7e9d9660457f
--- /dev/null
+++ b/contrib/bc/tests/bc/misc1.txt
@@ -0,0 +1,76 @@
+define x(x) {
+ return(x)
+}
+define y() {
+ return;
+}
+define z() {
+ return ();
+}
+scale = 0
+x=2
+x[0]=3
+x
+x[0]
+scale
+ibase
+obase
+x ( 7 )
+x + x( 8 )
+x - x[0]
+321 * x
+2 ^ x[0]
+x++
+--x
+x += 9
+x
+length(2381)
+sqrt(9)
+scale(238.1)
+x=2
+x[0]=3
+(x)
+(x[0])
+(scale)
+(ibase)
+(obase)
+(x ( 7 ))
+(x + x( 8 ))
+(x - x[0])
+(321 * x)
+(2 ^ x[0])
+(x++)
+(--x)
+(x += 9)
+(length(2381))
+(sqrt(9))
+(scale(238.1))
+(scale = 0)
+(x = 10)
+(x += 100)
+(x -= 10)
+(x *= 10)
+(x /= 100)
+(x ^= 10)
+(x = sqrt(x))
+(x[1 - 1])
+x[(1 - 1)]
+2 + \
+3
+++ibase
+--ibase
+++obase
+--obase
+++last
+--last
+last
+last = 100
+last
+. = 150
+.
+++scale
+--scale
+y()
+z()
+2 + /*
+*/3
diff --git a/contrib/bc/tests/bc/misc1_results.txt b/contrib/bc/tests/bc/misc1_results.txt
new file mode 100644
index 000000000000..a9c278069439
--- /dev/null
+++ b/contrib/bc/tests/bc/misc1_results.txt
@@ -0,0 +1,57 @@
+2
+3
+0
+10
+10
+7
+10
+-1
+642
+8
+2
+2
+11
+4
+3
+1
+2
+3
+0
+10
+10
+7
+10
+-1
+642
+8
+2
+2
+11
+4
+3
+1
+0
+10
+110
+100
+1000
+10
+10000000000
+100000
+3
+3
+5
+11
+10
+10
+10
+11
+10
+10
+100
+150
+1
+0
+0
+0
+5
diff --git a/contrib/bc/tests/bc/misc2.txt b/contrib/bc/tests/bc/misc2.txt
new file mode 100644
index 000000000000..3b3aa683402c
--- /dev/null
+++ b/contrib/bc/tests/bc/misc2.txt
@@ -0,0 +1,110 @@
+define w() { auto z; return 1; }
+define x() {
+ "x"
+ return (1)
+}
+define y() {
+ "y"
+ return (2)
+}
+define z() {
+ "z"
+ return (3)
+}
+
+define v() { return }
+
+v()
+
+w()
+
+if (x() == y()) { 1 }
+1
+if (x() <= y()) { 2 }
+if (y() >= x()) { 3 }
+if (x() != y()) { 4 }
+if (x() < y()) { 5 }
+if (y() > x()) { 6 }
+
+if (x() == z()) { 11 }
+11
+if (x() <= z()) { 12 }
+if (z() >= x()) { 13 }
+if (x() != z()) { 14 }
+if (x() < z()) { 15 }
+if (z() > x()) { 16 }
+
+x = -10
+while (x <= 0) {
+ x
+ if (x == -5) break;
+ x += 1
+}
+
+define u() {
+ auto a[];
+ return a[0]
+}
+
+u()
+
+if (x == -4) x
+else x - 4
+
+x = 1
+
+if (x == 1) 1 else 2
+if (x == 0) 1 else 2
+
+if (x == 1) 1 else if (x == 0) 2 else 3
+if (x == 0) 1 else if (x == 1) 2 else 3
+if (x == -1) 1 else if (x == 0) 2 else 3
+
+if (x == 1) if (x != 0) 1 else 2 else 3
+if (x == 1) if (x == 0) 1 else 2 else 3
+if (x != 1) if (x == 0) 1 else 2 else 3
+
+if (x == 1) while (x > 0) { x ; x -= 1 } else 0
+x = 1
+if (x == 0) while (x > 0) { x ; x -= 1 } else 0
+
+if(x == 1) {
+ 11
+ while(x == 1) {
+ 21
+ while(x == 1) {
+ 31
+ break
+ 32
+ }
+ 22
+ break
+ 23
+ }
+ 12
+}
+99
+
+for (;;) { 123 ; break; }
+for (i = 0;; ++i) { i ; if (i == 2) break; else i; }
+for (i = 0;;!++i) { i ; if (i == 2) break; else i; }
+for (i = 0;; ++i) { i ; if (i != 2) i else break }
+
+while (i > 0) if (i == 1) break else i--
+while (i < 3) if (i != 2) i++ else break
+
+for(i=1; i<=3; i++) { i; if(i==2) continue; print i,i,"\n" }
+
+print 1,2,3
+print "\n"
+
+ifz = 1
+ifz
+++ifz
+ifz++
+ifz
+
+{
+ 4
+ 5
+}
diff --git a/contrib/bc/tests/bc/misc2_results.txt b/contrib/bc/tests/bc/misc2_results.txt
new file mode 100644
index 000000000000..93b15e508170
--- /dev/null
+++ b/contrib/bc/tests/bc/misc2_results.txt
@@ -0,0 +1,68 @@
+0
+1
+xy1
+xy2
+yx3
+xy4
+xy5
+yx6
+xz11
+xz12
+zx13
+xz14
+xz15
+zx16
+-10
+-9
+-8
+-7
+-6
+-5
+0
+-9
+1
+2
+1
+2
+3
+1
+2
+3
+1
+0
+11
+21
+31
+22
+12
+99
+123
+0
+0
+1
+1
+2
+0
+0
+1
+1
+2
+0
+0
+1
+1
+2
+2
+1
+1
+11
+2
+3
+33
+123
+1
+2
+2
+3
+4
+5
diff --git a/contrib/bc/tests/bc/misc3.txt b/contrib/bc/tests/bc/misc3.txt
new file mode 100644
index 000000000000..7aad374c4ef6
--- /dev/null
+++ b/contrib/bc/tests/bc/misc3.txt
@@ -0,0 +1,12 @@
+for (i = 0; i < A; ++i)
+{print "n"
+if(1)if(1){3
+}
+if(0)if(1){3
+}
+else 4
+if(0){if(1){3
+}}
+else 5
+{i}
+}
diff --git a/contrib/bc/tests/bc/misc3_results.txt b/contrib/bc/tests/bc/misc3_results.txt
new file mode 100644
index 000000000000..06d8bdcbd06e
--- /dev/null
+++ b/contrib/bc/tests/bc/misc3_results.txt
@@ -0,0 +1,30 @@
+n3
+5
+0
+n3
+5
+1
+n3
+5
+2
+n3
+5
+3
+n3
+5
+4
+n3
+5
+5
+n3
+5
+6
+n3
+5
+7
+n3
+5
+8
+n3
+5
+9
diff --git a/contrib/bc/tests/bc/misc4.txt b/contrib/bc/tests/bc/misc4.txt
new file mode 100644
index 000000000000..b225b286fd5f
--- /dev/null
+++ b/contrib/bc/tests/bc/misc4.txt
@@ -0,0 +1,2 @@
+if ( 1 != 1 ) 7
+maxibase() + 1
diff --git a/contrib/bc/tests/bc/misc4_results.txt b/contrib/bc/tests/bc/misc4_results.txt
new file mode 100644
index 000000000000..81b5c5d06cc0
--- /dev/null
+++ b/contrib/bc/tests/bc/misc4_results.txt
@@ -0,0 +1 @@
+37
diff --git a/contrib/bc/tests/bc/misc5.txt b/contrib/bc/tests/bc/misc5.txt
new file mode 100644
index 000000000000..41852d4a2492
--- /dev/null
+++ b/contrib/bc/tests/bc/misc5.txt
@@ -0,0 +1,20 @@
+if (1) {}
+else 4
+
+if (0) {}
+else 5
+
+if (1) 6
+else {}
+
+if (0) 7
+else {}
+
+{
+ if (1) if (1)
+}
+print "n\n"
+
+if (1) {
+ print "true\n"
+}
diff --git a/contrib/bc/tests/bc/misc5_results.txt b/contrib/bc/tests/bc/misc5_results.txt
new file mode 100644
index 000000000000..d8c70d83c1d5
--- /dev/null
+++ b/contrib/bc/tests/bc/misc5_results.txt
@@ -0,0 +1,4 @@
+5
+6
+n
+true
diff --git a/contrib/bc/tests/bc/misc6.txt b/contrib/bc/tests/bc/misc6.txt
new file mode 120000
index 000000000000..1ddbfa42bea4
--- /dev/null
+++ b/contrib/bc/tests/bc/misc6.txt
@@ -0,0 +1 @@
+stdin1.txt \ No newline at end of file
diff --git a/contrib/bc/tests/bc/misc6_results.txt b/contrib/bc/tests/bc/misc6_results.txt
new file mode 120000
index 000000000000..a0374545ed82
--- /dev/null
+++ b/contrib/bc/tests/bc/misc6_results.txt
@@ -0,0 +1 @@
+stdin1_results.txt \ No newline at end of file
diff --git a/contrib/bc/tests/bc/misc7.txt b/contrib/bc/tests/bc/misc7.txt
new file mode 120000
index 000000000000..17ea58ae3ffd
--- /dev/null
+++ b/contrib/bc/tests/bc/misc7.txt
@@ -0,0 +1 @@
+stdin2.txt \ No newline at end of file
diff --git a/contrib/bc/tests/bc/misc7_results.txt b/contrib/bc/tests/bc/misc7_results.txt
new file mode 120000
index 000000000000..394d3e9d57c1
--- /dev/null
+++ b/contrib/bc/tests/bc/misc7_results.txt
@@ -0,0 +1 @@
+stdin2_results.txt \ No newline at end of file
diff --git a/contrib/bc/tests/bc/misc_results.txt b/contrib/bc/tests/bc/misc_results.txt
new file mode 100644
index 000000000000..e2db76e0ef90
--- /dev/null
+++ b/contrib/bc/tests/bc/misc_results.txt
@@ -0,0 +1,4 @@
+-1284597623836.9
+-1284597623836.9
+-4483684050181.80
+-4483684050181.80
diff --git a/contrib/bc/tests/bc/modulus.txt b/contrib/bc/tests/bc/modulus.txt
new file mode 100644
index 000000000000..e2656a6e919c
--- /dev/null
+++ b/contrib/bc/tests/bc/modulus.txt
@@ -0,0 +1,70 @@
+1 % 1
+2 % 1
+16 % 4
+15 % 4
+17 % 4
+2389473 % 5
+39240687239 % 1
+346728934 % 23958
+3496723859067234 % 298375462837546928347623059375486
+-1 % 1
+-2 % 1
+-47589634875689345 % 37869235
+-1274852934765 % 2387628935486273546
+-6324758963 % 237854962
+1 % -1
+2 % -1
+2 % -2
+2 % -3
+16 % 5
+15 % 5
+14 % 5
+89237423 % -237856923854
+123647238946 % -12467
+-1 % -1
+-2 % -1
+-2 % -2
+-2 % -3
+-13 % -7
+-14 % -7
+-15 % -7
+-12784956 % -32746
+-127849612 % -23712347682193
+1 % 0.2395672438567234
+scale = 0
+1 % 1
+2 % 1
+16 % 4
+15 % 4
+17 % 4
+2389473 % 5
+39240687239 % 1
+346728934 % 23958
+3496723859067234 % 298375462837546928347623059375486
+-1 % 1
+-2 % 1
+-47589634875689345 % 37869235
+-1274852934765 % 2387628935486273546
+-6324758963 % 237854962
+1 % -1
+2 % -1
+2 % -2
+2 % -3
+16 % 5
+15 % 5
+14 % 5
+89237423 % -237856923854
+123647238946 % -12467
+-1 % -1
+-2 % -1
+-2 % -2
+-2 % -3
+-13 % -7
+-14 % -7
+-15 % -7
+-12784956 % -32746
+-127849612 % -23712347682193
+-3191280681 % 641165986
+scale = 0; -899510228 % -2448300078.40314
+scale = 0; -7424863 % -207.2609738667
+scale = 0; 3769798918 % 0.6
diff --git a/contrib/bc/tests/bc/modulus_results.txt b/contrib/bc/tests/bc/modulus_results.txt
new file mode 100644
index 000000000000..e85145be70da
--- /dev/null
+++ b/contrib/bc/tests/bc/modulus_results.txt
@@ -0,0 +1,69 @@
+0
+0
+0
+0
+0
+0
+0
+.00000000000000002026
+2747189239559.46904933397471305894
+0
+0
+-.00000000000011057855
+-.00076922992566770712
+-.00000000000050364144
+0
+0
+0
+.00000000000000000002
+0
+0
+0
+.00000000070585524350
+.00000000000000002898
+0
+0
+0
+-.00000000000000000002
+-.00000000000000000005
+0
+-.00000000000000000002
+-.00000000000000011722
+-.00000002640923745817
+.000000000000000000000404744340951948
+0
+0
+0
+3
+1
+3
+0
+8758
+3496723859067234
+0
+0
+-8236960
+-1274852934765
+-140529951
+0
+0
+0
+2
+1
+0
+4
+89237423
+6692
+0
+0
+0
+-2
+-6
+0
+-1
+-14016
+-127849612
+-626616737
+-899510228.00000
+-153.1331732059
+.4
diff --git a/contrib/bc/tests/bc/multiply.txt b/contrib/bc/tests/bc/multiply.txt
new file mode 100644
index 000000000000..e4b023d86d2f
--- /dev/null
+++ b/contrib/bc/tests/bc/multiply.txt
@@ -0,0 +1,64 @@
+0 * 0
+0.000 * 0
+1 * 0
+0 * 1
+0 * 2498752389672835476
+873246913745129084576134 * 0
+1 * 472638590273489273456
+12374861230476103672835496 * 1
+1 * 1
+2 * 1
+1 * 2
+2 * 2
+3 * 14
+17 * 8
+1892467513846753 * 1872439821374591038746
+328962735862.2973546835638947635 * 1728465791348762356
+38745962374538.387427384672934867234 * 0.1932476528394672837568923754
+9878894576289457634856.2738627161689017387608947567654 * 37842939768237596237854203.29874372139852739126739621793162
+-1 * 1
+-1 * 2
+1 * -1
+2 * -1
+-1 * -1
+-1 * -2
+78893457 * -34876238956
+235678324957634 * -0.2349578349672389576
+-12849567821934 * 12738462937681
+1274861293467.927843682937462 * -28935678239
+2936077239872.12937462836 * -0.012842357682435762
+2387692387566.2378569237546 * -272189345628.123875629835876
+0.012348629356782835962 * -23487692356
+0.4768349567348675934 * -0.23756834576934857638495
+0.98748395367485962735486 * -4675839462354867.376834956738456
+-321784627934586 * -235762378596
+-32578623567892356 * -0.32567384579638456
+-35768232346876 * -2348672935602387620.28375682349576237856
+-0.2356728394765234 * -238759624356978
+-0.2345768212346780 * -0.235768124697074385948943532045
+-0.370873860736785306278630 * -7835678398607.7086378076867096270
+-78365713707.7089637863786730 * -738580798679306780
+-73867038956790490258249 * -0.7379862716391723672803679
+-378621971598721837710387 * -98465373878350798.09743896037963078560
+37164201 * 2931559660
+679468076118972457796560530571.46287161642138401685 * 93762.2836
+.000000000000000000000000001 * .0000000000000000000000001
+scale = 0; 237854962 * -26
+scale = 20; -989840367 * -604515309.000000000000000000000000000934882580147931989975995184020932681975029644558793192923907
+scale = 20; 623151276.1106104320046667401793737969130124845763706302869482103753909 * -605483272.00000000000000000000000000000000000000000000000000000000000000000001214399683339235971324443660465351061300645722062237312361947
+scale = 20; -4036255151 * -107387984.0000000000000000000000000000000000000211170318819607129506079448130618538050115777171523510326383
+scale = 19; 207225741.422284845290215111137445727462936392828872808516127361319675 * -1915632919.00000000000000000001200266819789205382734342543620744656564870683107249138254072
+scale = 4; -3700694776.00000000000000000000000001187600351487950366746489017325409746844911432455524847144387 * 3138176186.1604970875815488831816899415825759179598942878342303599901133
+scale = 4; 2471252773 * -2993804686
+scale = 5; -4136888605.1006664686088985948377077150956015758460597074849621165317181 * -356481995.883644326721780591302331282263396633424696084971708651216219
+scale = 10; -1226031704.000000000000000000000000000001604564576253363548680043729535457438899040946479243020383986 * -1255956056
+scale = 19; 1916023355.00000000000000000000000000000000000590795041191824027930567027047057471024023798017409006012644 * -3373891612
+scale = 22; 579072526.647812809110145427578413082391478903947155934872093047795435 * -2359518757
+scale = 16; 3426351583 * -1097923200.1397570019820419234583136053292187927164488359163611530503423
+scale = 29; 2500140133 * 2519408882.136359515749313850856768153433872015185470839039102302348122
+scale = 26; -2643644458 * -1308250843
+scale = 1; -1657954173 * 3046852834.163701388468236163905483103301582741070980569231164917728216
+scale = 19; -2350345163 * 1973064755
+scale = 23; -847296455 * 0
+scale = 32; -340132470 * 0
+scale = 30; 0 * -898777681
diff --git a/contrib/bc/tests/bc/multiply_results.txt b/contrib/bc/tests/bc/multiply_results.txt
new file mode 100644
index 000000000000..c37e8dea8899
--- /dev/null
+++ b/contrib/bc/tests/bc/multiply_results.txt
@@ -0,0 +1,78 @@
+0
+0
+0
+0
+0
+0
+472638590273489273456
+12374861230476103672835496
+1
+2
+2
+4
+42
+136
+3543531533584430580556128344529291738
+568600835566479683035874339053.4411638427543228060
+7487566285885.8557453089005171423976251098
+373846412427291014394738378015501363938345620046.7869650248829232267\
+2297002026819
+-1
+-2
+-1
+-2
+1
+2
+-2751507058396910892
+-55374468980751.0837656919743223184
+-163683743464924630346895054
+-36888976187143312550878.567134791289418
+-37706154097.69662826215753378160
+-649904428532907022680241.94791869424754101064
+-290040807.350385412976669306472
+-.11328089187650139309272
+-4617316439035114.40320367843985107357898
+75864709277486862054521256
+10610005628108234.92015040406042336
+84007879267445533366251128067927.91168012197674537856
+56269158624557.1027018519702852
+.055305737239900889424090264801
+2906048299183.472237078104362540110129
+57879411419313585866282299201.3825582163029400
+54512860676747314187949.9414724679950990587298071
+37281153992026463004361915151761464058058.54968338992209002720
+108949072447731660
+63708478450213482928510139572007971.83536929222529239687
+0
+-6184229012
+598373655317678403.0000000000000000009253845162355359152488793941415\
+12541608457628205955407160901907953869
+-377307673610427838.287519137113381113465954298538150423110843701312\
+63603041103236754712381166109996409858143288621328522821527713676934\
+622001341437
+433445303575505584.0000000000000000000000000000852337287073951516265\
+237258332446395020869301754929979072465074948833
+-396968451932710729.832758175488621830920257166881504044017181955086\
+43506193467199715507328434681876
+-11613432218291755069.5762524259791142629353752893708044134847560553\
+8136567321175929541134735412916995398760
+-7398448132097894278
+1474726306694590904.736489533186588598709217518359873918376540725558\
+9059364344850
+1539841943486799424.000000000000000000002015262596788485739334351728\
+454883837115500449322577149746998662119216
+-6464455125830598260.00000000000000000000000001993278433888289570814\
+993810957844330769886942619318475359317157542128
+-1366332488288896656.12024861536905075619688089083311576513457394212\
+2626381474295
+-3761870894811282224.97650348201375765613020604657735333908053129235\
+37456182968609
+6298875257665779203.841305125739782495076325186750781083182842822393\
+239949380226
+3458550090770778094
+-5051542370918585682.13680622589660768869984918306341072395872527699\
+8697397045368
+-4637383203200030065
+0
+0
+0
diff --git a/contrib/bc/tests/bc/pi.txt b/contrib/bc/tests/bc/pi.txt
new file mode 100644
index 000000000000..b98419f1236b
--- /dev/null
+++ b/contrib/bc/tests/bc/pi.txt
@@ -0,0 +1,4 @@
+for (i = 0; i <= 100; ++i) {
+ scale = i
+ 4 * a(1)
+}
diff --git a/contrib/bc/tests/bc/pi_results.txt b/contrib/bc/tests/bc/pi_results.txt
new file mode 100644
index 000000000000..128d6c0ca758
--- /dev/null
+++ b/contrib/bc/tests/bc/pi_results.txt
@@ -0,0 +1,135 @@
+0
+2.8
+3.12
+3.140
+3.1412
+3.14156
+3.141592
+3.1415924
+3.14159264
+3.141592652
+3.1415926532
+3.14159265356
+3.141592653588
+3.1415926535896
+3.14159265358976
+3.141592653589792
+3.1415926535897932
+3.14159265358979320
+3.141592653589793236
+3.1415926535897932384
+3.14159265358979323844
+3.141592653589793238460
+3.1415926535897932384624
+3.14159265358979323846264
+3.141592653589793238462640
+3.1415926535897932384626432
+3.14159265358979323846264336
+3.141592653589793238462643380
+3.1415926535897932384626433832
+3.14159265358979323846264338324
+3.141592653589793238462643383276
+3.1415926535897932384626433832792
+3.14159265358979323846264338327948
+3.141592653589793238462643383279500
+3.1415926535897932384626433832795028
+3.14159265358979323846264338327950288
+3.141592653589793238462643383279502884
+3.1415926535897932384626433832795028840
+3.14159265358979323846264338327950288416
+3.141592653589793238462643383279502884196
+3.1415926535897932384626433832795028841968
+3.14159265358979323846264338327950288419716
+3.141592653589793238462643383279502884197168
+3.1415926535897932384626433832795028841971692
+3.14159265358979323846264338327950288419716936
+3.141592653589793238462643383279502884197169396
+3.1415926535897932384626433832795028841971693992
+3.14159265358979323846264338327950288419716939936
+3.141592653589793238462643383279502884197169399372
+3.1415926535897932384626433832795028841971693993748
+3.14159265358979323846264338327950288419716939937508
+3.141592653589793238462643383279502884197169399375104
+3.1415926535897932384626433832795028841971693993751056
+3.14159265358979323846264338327950288419716939937510580
+3.141592653589793238462643383279502884197169399375105820
+3.1415926535897932384626433832795028841971693993751058208
+3.14159265358979323846264338327950288419716939937510582096
+3.141592653589793238462643383279502884197169399375105820972
+3.1415926535897932384626433832795028841971693993751058209748
+3.14159265358979323846264338327950288419716939937510582097492
+3.141592653589793238462643383279502884197169399375105820974944
+3.1415926535897932384626433832795028841971693993751058209749444
+3.14159265358979323846264338327950288419716939937510582097494456
+3.141592653589793238462643383279502884197169399375105820974944592
+3.1415926535897932384626433832795028841971693993751058209749445920
+3.14159265358979323846264338327950288419716939937510582097494459228
+3.141592653589793238462643383279502884197169399375105820974944592304
+3.141592653589793238462643383279502884197169399375105820974944592307\
+6
+3.141592653589793238462643383279502884197169399375105820974944592307\
+80
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816404
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164060
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406284
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062860
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862088
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620896
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208996
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089984
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620899860
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208998628
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089986280
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620899862800
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208998628032
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089986280348
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620899862803480
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208998628034824
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089986280348252
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620899862803482532
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208998628034825340
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089986280348253420
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620899862803482534208
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208998628034825342116
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089986280348253421168
+3.141592653589793238462643383279502884197169399375105820974944592307\
+81640628620899862803482534211704
+3.141592653589793238462643383279502884197169399375105820974944592307\
+816406286208998628034825342117064
+3.141592653589793238462643383279502884197169399375105820974944592307\
+8164062862089986280348253421170676
diff --git a/contrib/bc/tests/bc/places.txt b/contrib/bc/tests/bc/places.txt
new file mode 100644
index 000000000000..f10952330a06
--- /dev/null
+++ b/contrib/bc/tests/bc/places.txt
@@ -0,0 +1,20 @@
+0 @ 0
+1 @ 0
+2 @ 0
+0.0023896 @ 0
+1.298346 @ 0
+2.00000000 @ 0
+0.0023896 @ 3
+1.298346 @ 4
+2.00000000 @ 5
+289 @ 3
+18.34 @ 6
+-183.1 @ 0
+-23.238 @ 8
+-343.23 @ 2
+x = 89136.892348976
+x @= 7
+x
+-.1897263 @ 0
+.1982365 @ 0
+.0 @ 2
diff --git a/contrib/bc/tests/bc/places_results.txt b/contrib/bc/tests/bc/places_results.txt
new file mode 100644
index 000000000000..381ad9c3e54c
--- /dev/null
+++ b/contrib/bc/tests/bc/places_results.txt
@@ -0,0 +1,18 @@
+0
+1
+2
+0
+1
+2
+.002
+1.2983
+2.00000
+289.000
+18.340000
+-183
+-23.23800000
+-343.23
+89136.8923489
+0
+0
+0
diff --git a/contrib/bc/tests/bc/posix_errors.txt b/contrib/bc/tests/bc/posix_errors.txt
new file mode 100644
index 000000000000..2bd5d9feed84
--- /dev/null
+++ b/contrib/bc/tests/bc/posix_errors.txt
@@ -0,0 +1,31 @@
+aa = 0
+# This is a comment.
+while (q==0) { ++q; continue; }
+last
+print "i: ", i
+halt
+define x(e) { return 0; }
+define x(e) { return 4*(e+e); }
+define x(e) { return (e+e)*4; }
+limits
+.
+if (q!=0) { x=3; } else { x=4; }
+x<=0
+while (q!=0 && x==0) { ++q; }
+while (q!=0 || x==0) { ++q; }
+while (!q) { ++q; }
+for (; x<0; ++x) { y += 1; }
+for (x=0;; ++x) { y += 1; }
+for (x=0; x<0;) { y += 1; }
+for (x=0;;) { y += 1; }
+for (; x<0;) { y += 1; }
+for (;; ++x) { y += 1; }
+for (;;) { y += 1; }
+3e2981
+9.892108e-20
+obase = 0
+obase = 1
+define void a(e) { "stuff" }
+maxibase()
+maxobase()
+maxscale()
diff --git a/contrib/bc/tests/bc/power.txt b/contrib/bc/tests/bc/power.txt
new file mode 100644
index 000000000000..e4065fbfa256
--- /dev/null
+++ b/contrib/bc/tests/bc/power.txt
@@ -0,0 +1,43 @@
+0 ^ 0
+0 ^ 1
+0 ^ 1894
+1 ^ 0
+39746823 ^ 0
+0.238672983047682 ^ 0
+18394762374689237468.97354862973846 ^ 0
+1 ^ 1
+2 ^ 1
+18927361346 ^ 1
+0.23523785962738592635777 ^ 1
+328956734869213746.89782398457234 ^ 1
+8937 ^ 98
+0.124876812394 ^ 2396
+93762.2836 ^ 13
+1 ^ -1
+2 ^ -1
+10 ^ -1
+683734768 ^ -1
+38579623756.897937568235 ^ -1
+1 ^ -32467
+2 ^ -53
+23897 ^ -213
+-1 ^ 1
+-1 ^ 2
+-2 ^ 1
+-2 ^ 2
+-237 ^ 294
+-3746 ^ 28
+-0.3548 ^ 35
+-4267.234 ^ 37
+-326.3246 ^ 78
+-1 ^ -1
+-1 ^ -2
+-2 ^ -1
+-2 ^ -2
+-237 ^ -293
+-784 ^ -23
+-86 ^ -7
+-0.23424398 ^ -781
+-178.234786 ^ -879
+-1274.346 ^ -768
+-0.2959371298 ^ 227
diff --git a/contrib/bc/tests/bc/power_results.txt b/contrib/bc/tests/bc/power_results.txt
new file mode 100644
index 000000000000..280347a9f258
--- /dev/null
+++ b/contrib/bc/tests/bc/power_results.txt
@@ -0,0 +1,72 @@
+1
+0
+0
+1
+1
+1
+1
+1
+2
+18927361346
+.23523785962738592635777
+328956734869213746.89782398457234
+16473742664221279051571200630760751138799221376964991600670000200609\
+08006052596520320731708604393844468006290371918262741885989163144389\
+39367835091560809036359941703341471396407660150658436796925310445979\
+21333166245765946557344383284626113908419359990042883048537750217279\
+17481980123593363177308481941550382845381799410533956718500484099889\
+610805653325917409549921909941664118421333562129
+0
+43287877285033571298394739716218787350087163435619825150259705419.98\
+016445740928054425
+1.00000000000000000000
+.50000000000000000000
+.10000000000000000000
+.00000000146255543348
+.00000000002592041867
+1.00000000000000000000
+.00000000000000011102
+0
+-1
+1
+-2
+4
+14997322375665265051328725757939209353051902095893907150382724666290\
+49749481660976421019742616298227588464420182758442163654172400528243\
+00885441207762486233574213374503090372518590691583139696652847404883\
+08573912261119588874308960204159666762789603037188471170006223907416\
+60492840269152716750700089148882139254399347568222390231015487895905\
+73727080561379177721440905866857248917982113340543176658480139248897\
+54802503253413282808814063861470711399810899724515727713334909764746\
+27910290211411231279325882505708287941671508154740003122373284699097\
+78346501539634198926772266511968381368929692275950529960923432771985\
+12597189390708050983487158873301681237787429436264801751664042999180\
+3448659818912436089
+11478830555358864333472551120140548480416206583184496764727387456058\
+792742209537931243951391229607936
+-.00000000000000017759
+-2067373624686414405470850679965010694114490999957199847684803894306\
+56243666149296582304582679590231948238805965642713928910384741502707\
+.23224479257866798694
+11606078892843496082360561256965139908586179418605021706789617179085\
+85768049299693425729565480314913006780973928345684673490252494674985\
+0186164225375953066263609289359900615361965737717208159874390.293769\
+70206344604971
+-1.00000000000000000000
+1.00000000000000000000
+-.50000000000000000000
+.25000000000000000000
+0
+0
+-.00000000000002874159
+-1945134149489344891879057554905782841936258356736314337975569799825\
+94091939572752348215929683891336730843553721422164737465108229034947\
+87333189564755763444242676978610321731298729194092653999616928308494\
+26419468484566422775668903315088810746121307679948574976162519479931\
+18935243698160094347216562490000767121041786977792546155155934655909\
+14123833869470494708767968978717730012864171105540029928688274136791\
+98175053824022144065005509214813689232148489884560100200475909009813\
+340098100705258138.98542904577525702068
+0
+0
+0
diff --git a/contrib/bc/tests/bc/print2.txt b/contrib/bc/tests/bc/print2.txt
new file mode 100644
index 000000000000..7f65fbe4c106
--- /dev/null
+++ b/contrib/bc/tests/bc/print2.txt
@@ -0,0 +1,194 @@
+define prnt(i) {
+
+ obase = i - 1
+ a
+ b
+ c
+
+ obase = i
+ a
+ b
+ c
+
+ return i
+}
+
+define prnt2(i) {
+
+ obase = i + 1
+ a
+ b
+ c
+
+ print "\n"
+
+ return i * 10
+}
+
+a = 999999999999999999999999999999999999
+b = a + 1
+c = b + 1
+
+i = 100
+i = prnt(i)
+
+if (i + 1 <= maxobase()) {
+ i = prnt2(i)
+}
+else {
+ print " 084 044 021 047 096 073 015 052 088 014 072 097 047 021 094 051 083\e\n 000\n"
+ print " 084 044 021 047 096 073 015 052 088 014 072 097 047 021 094 051 083\e\n 001\n"
+ print " 084 044 021 047 096 073 015 052 088 014 072 097 047 021 094 051 083\e\n 002\n"
+ print "\n"
+ i *= 10
+}
+
+if (i <= maxobase()) {
+ i = prnt(i)
+}
+else {
+ print " 001 012 066 220 495 792 924 792 495 220 066 012 000\n"
+ print " 001 012 066 220 495 792 924 792 495 220 066 012 001\n"
+ print " 001 012 066 220 495 792 924 792 495 220 066 012 002\n"
+ print " 999 999 999 999 999 999 999 999 999 999 999 999\n"
+ print " 001 000 000 000 000 000 000 000 000 000 000 000 000\n"
+ print " 001 000 000 000 000 000 000 000 000 000 000 000 001\n"
+}
+
+if (i + 1 <= maxobase()) {
+ i = prnt2(i)
+}
+else {
+ print " 0989 0065 0781 0494 0209 0923 0209 0494 0781 0065 0989 0000\n"
+ print " 0989 0065 0781 0494 0209 0923 0209 0494 0781 0065 0989 0001\n"
+ print " 0989 0065 0781 0494 0209 0923 0209 0494 0781 0065 0989 0002\n"
+ print "\n"
+ i *= 10
+}
+
+if (i <= maxobase()) {
+ i = prnt(i)
+}
+else {
+ print " 0001 0009 0036 0084 0126 0126 0084 0036 0009 0000\n"
+ print " 0001 0009 0036 0084 0126 0126 0084 0036 0009 0001\n"
+ print " 0001 0009 0036 0084 0126 0126 0084 0036 0009 0002\n"
+ print " 9999 9999 9999 9999 9999 9999 9999 9999 9999\n"
+ print " 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000\n"
+ print " 0001 0000 0000 0000 0000 0000 0000 0000 0000 0001\n"
+}
+
+if (i + 1 <= maxobase()) {
+ i = prnt2(i)
+}
+else {
+ print " 09992 00035 09917 00125 09875 00083 09965 00008 09999\n"
+ print " 09992 00035 09917 00125 09875 00083 09965 00008 10000\n"
+ print " 09992 00035 09917 00125 09875 00083 09965 00009 00000\n"
+ print "\n"
+ i *= 10
+}
+
+if (i <= maxobase()) {
+ i = prnt(i)
+}
+else {
+ print " 00010 00070 00210 00350 00350 00210 00070 00009\n"
+ print " 00010 00070 00210 00350 00350 00210 00070 00010\n"
+ print " 00010 00070 00210 00350 00350 00210 00070 00011\n"
+ print " 00009 99999 99999 99999 99999 99999 99999 99999\n"
+ print " 00010 00000 00000 00000 00000 00000 00000 00000\n"
+ print " 00010 00000 00000 00000 00000 00000 00000 00001\n"
+}
+
+if (i + 1 <= maxobase()) {
+ i = prnt2(i)
+}
+else {
+ print " 000009 099931 000209 099651 000349 099791 000069 099990\n"
+ print " 000009 099931 000209 099651 000349 099791 000069 099991\n"
+ print " 000009 099931 000209 099651 000349 099791 000069 099992\n"
+ print "\n"
+ i *= 10
+}
+
+if (i <= maxobase()) {
+ i = prnt(i)
+}
+else {
+ print " 000001 000006 000015 000020 000015 000006 000000\n"
+ print " 000001 000006 000015 000020 000015 000006 000001\n"
+ print " 000001 000006 000015 000020 000015 000006 000002\n"
+ print " 999999 999999 999999 999999 999999 999999\n"
+ print " 000001 000000 000000 000000 000000 000000 000000\n"
+ print " 000001 000000 000000 000000 000000 000000 000001\n"
+}
+
+if (i + 1 <= maxobase()) {
+ i = prnt2(i)
+}
+else {
+ print " 0999995 0000014 0999981 0000014 0999995 0000000\n"
+ print " 0999995 0000014 0999981 0000014 0999995 0000001\n"
+ print " 0999995 0000014 0999981 0000014 0999995 0000002\n"
+ print "\n"
+ i *= 10
+}
+
+if (i <= maxobase()) {
+ i = prnt(i)
+}
+else {
+ print " 0000010 0000050 0000100 0000100 0000050 0000009\n"
+ print " 0000010 0000050 0000100 0000100 0000050 0000010\n"
+ print " 0000010 0000050 0000100 0000100 0000050 0000011\n"
+ print " 0000009 9999999 9999999 9999999 9999999 9999999\n"
+ print " 0000010 0000000 0000000 0000000 0000000 0000000\n"
+ print " 0000010 0000000 0000000 0000000 0000000 0000001\n"
+}
+
+if (i + 1 <= maxobase()) {
+ i = prnt2(i)
+}
+else {
+ print " 00000009 09999951 00000099 09999901 00000049 09999990\n"
+ print " 00000009 09999951 00000099 09999901 00000049 09999991\n"
+ print " 00000009 09999951 00000099 09999901 00000049 09999992\n"
+ print "\n"
+ i *= 10
+}
+
+if (i <= maxobase()) {
+ i = prnt(i)
+}
+else {
+ print " 00010000 00040000 00060000 00040000 00009999\n"
+ print " 00010000 00040000 00060000 00040000 00010000\n"
+ print " 00010000 00040000 00060000 00040000 00010001\n"
+ print " 00009999 99999999 99999999 99999999 99999999\n"
+ print " 00010000 00000000 00000000 00000000 00000000\n"
+ print " 00010000 00000000 00000000 00000000 00000001\n"
+}
+
+if (i + 1 <= maxobase()) {
+ i = prnt2(i)
+}
+else {
+ print " 000009999 099960001 000059999 099960001 000009999\n"
+ print " 000009999 099960001 000059999 099960001 000010000\n"
+ print " 000009999 099960001 000059999 099960001 000010001\n"
+ print "\n"
+ i *= 10
+}
+
+if (i <= maxobase()) {
+ i = prnt(i)
+}
+else {
+ print " 000000001 000000004 000000006 000000004 000000000\n"
+ print " 000000001 000000004 000000006 000000004 000000001\n"
+ print " 000000001 000000004 000000006 000000004 000000002\n"
+ print " 999999999 999999999 999999999 999999999\n"
+ print " 000000001 000000000 000000000 000000000 000000000\n"
+ print " 000000001 000000000 000000000 000000000 000000001\n"
+}
diff --git a/contrib/bc/tests/bc/print2_results.txt b/contrib/bc/tests/bc/print2_results.txt
new file mode 100644
index 000000000000..625e6f0bfd07
--- /dev/null
+++ b/contrib/bc/tests/bc/print2_results.txt
@@ -0,0 +1,79 @@
+ 01 19 62 55 79 46 79 96 00 60 26 35 38 84 98 25 54 18 00
+ 01 19 62 55 79 46 79 96 00 60 26 35 38 84 98 25 54 18 01
+ 01 19 62 55 79 46 79 96 00 60 26 35 38 84 98 25 54 18 02
+ 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99
+ 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+ 084 044 021 047 096 073 015 052 088 014 072 097 047 021 094 051 083\
+ 000
+ 084 044 021 047 096 073 015 052 088 014 072 097 047 021 094 051 083\
+ 001
+ 084 044 021 047 096 073 015 052 088 014 072 097 047 021 094 051 083\
+ 002
+
+ 001 012 066 220 495 792 924 792 495 220 066 012 000
+ 001 012 066 220 495 792 924 792 495 220 066 012 001
+ 001 012 066 220 495 792 924 792 495 220 066 012 002
+ 999 999 999 999 999 999 999 999 999 999 999 999
+ 001 000 000 000 000 000 000 000 000 000 000 000 000
+ 001 000 000 000 000 000 000 000 000 000 000 000 001
+ 0989 0065 0781 0494 0209 0923 0209 0494 0781 0065 0989 0000
+ 0989 0065 0781 0494 0209 0923 0209 0494 0781 0065 0989 0001
+ 0989 0065 0781 0494 0209 0923 0209 0494 0781 0065 0989 0002
+
+ 0001 0009 0036 0084 0126 0126 0084 0036 0009 0000
+ 0001 0009 0036 0084 0126 0126 0084 0036 0009 0001
+ 0001 0009 0036 0084 0126 0126 0084 0036 0009 0002
+ 9999 9999 9999 9999 9999 9999 9999 9999 9999
+ 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000
+ 0001 0000 0000 0000 0000 0000 0000 0000 0000 0001
+ 09992 00035 09917 00125 09875 00083 09965 00008 09999
+ 09992 00035 09917 00125 09875 00083 09965 00008 10000
+ 09992 00035 09917 00125 09875 00083 09965 00009 00000
+
+ 00010 00070 00210 00350 00350 00210 00070 00009
+ 00010 00070 00210 00350 00350 00210 00070 00010
+ 00010 00070 00210 00350 00350 00210 00070 00011
+ 00009 99999 99999 99999 99999 99999 99999 99999
+ 00010 00000 00000 00000 00000 00000 00000 00000
+ 00010 00000 00000 00000 00000 00000 00000 00001
+ 000009 099931 000209 099651 000349 099791 000069 099990
+ 000009 099931 000209 099651 000349 099791 000069 099991
+ 000009 099931 000209 099651 000349 099791 000069 099992
+
+ 000001 000006 000015 000020 000015 000006 000000
+ 000001 000006 000015 000020 000015 000006 000001
+ 000001 000006 000015 000020 000015 000006 000002
+ 999999 999999 999999 999999 999999 999999
+ 000001 000000 000000 000000 000000 000000 000000
+ 000001 000000 000000 000000 000000 000000 000001
+ 0999995 0000014 0999981 0000014 0999995 0000000
+ 0999995 0000014 0999981 0000014 0999995 0000001
+ 0999995 0000014 0999981 0000014 0999995 0000002
+
+ 0000010 0000050 0000100 0000100 0000050 0000009
+ 0000010 0000050 0000100 0000100 0000050 0000010
+ 0000010 0000050 0000100 0000100 0000050 0000011
+ 0000009 9999999 9999999 9999999 9999999 9999999
+ 0000010 0000000 0000000 0000000 0000000 0000000
+ 0000010 0000000 0000000 0000000 0000000 0000001
+ 00000009 09999951 00000099 09999901 00000049 09999990
+ 00000009 09999951 00000099 09999901 00000049 09999991
+ 00000009 09999951 00000099 09999901 00000049 09999992
+
+ 00010000 00040000 00060000 00040000 00009999
+ 00010000 00040000 00060000 00040000 00010000
+ 00010000 00040000 00060000 00040000 00010001
+ 00009999 99999999 99999999 99999999 99999999
+ 00010000 00000000 00000000 00000000 00000000
+ 00010000 00000000 00000000 00000000 00000001
+ 000009999 099960001 000059999 099960001 000009999
+ 000009999 099960001 000059999 099960001 000010000
+ 000009999 099960001 000059999 099960001 000010001
+
+ 000000001 000000004 000000006 000000004 000000000
+ 000000001 000000004 000000006 000000004 000000001
+ 000000001 000000004 000000006 000000004 000000002
+ 999999999 999999999 999999999 999999999
+ 000000001 000000000 000000000 000000000 000000000
+ 000000001 000000000 000000000 000000000 000000001
diff --git a/contrib/bc/tests/bc/rand.txt b/contrib/bc/tests/bc/rand.txt
new file mode 100644
index 000000000000..5b53d10debe6
--- /dev/null
+++ b/contrib/bc/tests/bc/rand.txt
@@ -0,0 +1,323 @@
+print "Gathering array...\n"
+
+s = seed
+
+sum = 0
+
+for (i = 0; i < 100; ++i) {
+ a[i] = rand()
+ sum += a[i]
+ b[i] = irand(sum)
+}
+
+print "Testing implementation...\n"
+
+if (maxrand() >= 2^64 - 1) {
+
+ seed = 54.86785590782347282592869373784717814475564948862907968939359536927733440\
+ 901359008180088183692646452982444316148757934570312500000
+
+ ibase = G
+ obase = G
+
+ for (i = 0; i < 64; ++i) {
+ rand()
+ }
+
+ seed = 0.2890120
+
+ rand()
+
+ 7B47F409
+ BA1D3330
+ 83D2F293
+ BFA4784B
+ CBED606E
+ BFC6A3AD
+ 812FFF6D
+ E61F305A
+ F9384B90
+ 32DB86FE
+ 1DC035F9
+ ED786826
+ 3822441D
+ 2BA113D7
+ 1C5B818B
+ A233956A
+ 84DA65E3
+ CED67292
+ B2C0FE06
+ 91817130
+
+ 55FE8917
+ 47E92091
+ 486AF299
+ B1E882BB
+ C261E845
+ 1A9B90F6
+ 7964E884
+ 5F36D7A4
+ 1EE2052D
+ 8519F5D5
+ 293D4E4F
+ 6D8F99FC
+ C3421509
+ A06CD7C6
+ E43064D3
+ E20F9BF0
+ 401B50B7
+ 8EF1FF3E
+ E357E2B2
+ A4AEEE37
+
+ 2AD4426A
+ 9D11BE94
+ 7290C556
+ 6E6F3787
+ 050C2EE3
+ 4FD73703
+ C6FF478B
+ 4B1CA1E1
+ 1654EA91
+ CD08B2F2
+ F7FF3DA8
+ 78B1B8DA
+ A100602C
+ 9588585F
+ DA028873
+ 66B4F376
+ 0E6B4B9A
+ 48167094
+ 0D58CDA0
+ 8F7238BE
+
+ F79983F3
+ 07E5D324
+ AD78DF52
+ 1532BA74
+ 1E4899E2
+ 6C75DF64
+ 171DDC36
+ F2D8D74A
+ 24E6D907
+ 4780FD32
+ 9ADF408C
+ A25544CF
+ EFC6A738
+ 1AA23A54
+ C5A13EBB
+ F739EDC9
+ C3A015FA
+ 3D5E1511
+ AFC4D7FB
+ 3F413B5E
+
+ 4660CB73
+ 88FC773F
+ D6BED59C
+ 63B3B54A
+ D67D3DDE
+ 23394F8B
+ 13384B44
+ DD8B3ABC
+ FF59A21E
+ 3BB16D7E
+ 6E01CB68
+ EC34790E
+ B26C42AD
+ D723C830
+ DFD10FCA
+ 7E362AA1
+ 826FF323
+ CB8F63B5
+ 9B3227E5
+ 9A61E339
+
+ 40BDACF
+}
+else {
+
+ ibase = G
+ obase = G
+
+ 86B1DA1D72062B68
+ 1304AA46C9853D39
+ A3670E9E0DD50358
+ F9090E529A7DAE00
+ C85B9FD837996F2C
+ 606121F8E3919196
+ 7CE1C7FF478354BA
+ CBC4AC70E541310E
+ 74BE71999EC37F2C
+ B81F9C99A934F1A7
+ 120E9901A900C97F
+ 0F983BAD4B19F493
+ 5934619363660D96
+ D5A7FE2717A2014E
+ 6E437241C9E6676E
+ 6A75C9DD6329CD29
+ 2D9E477683673437
+ 51FB0CF3D4405437
+ 217BB90392D08B20
+ 47C528A018B07A82
+
+ 1B4E474C418C835E
+ BDB2BDA74A119ED6
+ C6DB79D0B9E43493
+ C3CF4834E94A41D1
+ AB8312FC7877C7DC
+ 094B108133E8B5EC
+ 37CA97AC830113BD
+ EF02D7347F9192BF
+ 959517DD9896C53A
+ 7A80EB7629EFE9F9
+ AE53C23F2B1CF57C
+ CA605CD189F6D5CD
+ 921C2704886A9622
+ B68C9FBF826AF7AA
+ 73F8C733124772C3
+ 6B57F7E459EFBCDF
+ 9DE7696DDB6B8E18
+ 02CA67560DC26877
+ A24E353080777DEC
+ 4D600156763FD65C
+
+ 5CDF9C7E26DD2C38
+ 6A32443BBBB16774
+ 3D8415FFECFB8B7F
+ 3090ED9C475635A3
+ 6DBF241361C3E652
+ 2CA9EF5A2AD971FC
+ 44FBE937A1CF0FFC
+ DB17CF0577CB7853
+ AA3747D98D31B24C
+ 5D9A104C5D7F43F7
+ BAE65E3E293B2C7B
+ 16A396F0DB4EF984
+ 6DD2BACDC4445A05
+ 7B7A13D1858E5CA8
+ F73722BCAA52447C
+ 31A2C7BBE77CBA00
+ 7FC8AF9003BA1ACE
+ 5703F11DD3F235EF
+ FA1952267EF836C7
+ BBFA558C9E2D51E2
+
+ 3A29661D8145AF36
+ 608DEA6358DABD7C
+ 9E34E9E53431B447
+ 325A05E35EA524EB
+ 63A87CCF0C80ABB1
+ 8EA183287A46F292
+ E2AA5F119CBF2A08
+ 2F3BEB0DE8B730C8
+ 4B8006A928CF8F5B
+ 57B8BA85069C201C
+ 3422D962DDF59474
+ FD744940BA7366A1
+ 23D24B06B5DA4F6F
+ AA187C608319D1DC
+ DC60CA6FEA738B8A
+ C9FC61DF96A769FE
+ 82E2457708658A20
+ 2BECEC9B3E7D93EC
+ 1340DAEC04588952
+ F533446AD5C50B1D
+
+ 31FD1C7F434A62CE
+ D16DAEDD1F281A39
+ 6B5D9648931D7057
+ 62FEE3392DBB06D5
+ 0358BC87B00DF25A
+ F3C882D22946175D
+ 65BA8F11B4516EFE
+ 2DA5A96E626DA4FE
+ DCC669F4CD6121F0
+ 7A47FAC054319CA2
+ 9661CFEE277284C8
+ 01E483A14F4EB23A
+ ADDC115507390607
+ 5AB47C343BD3B0BD
+ 4882FB3A3957B11F
+ 615B7C9C3626DD44
+ F79CF49562969219
+ 88C32C194EA78D27
+ DA8AFFE1353FF352
+ A7A3C331A64CB146
+
+ A1F53517A7BE0CAA
+
+ ibase = A
+
+ seed = 54.0950779151573258314404657465246373249101452529430389404296875000
+
+ ibase = G
+
+ for (i = 0; i < 64; ++i) {
+ rand()
+ }
+
+ seed = 0.2890120
+
+ rand()
+}
+
+print "Testing array...\n"
+
+ibase = A
+
+seed = s
+
+sum = 0
+
+for (i = 0; i < 100; ++i) {
+ a[i] == rand()
+ sum += a[i]
+ b[i] == irand(sum)
+}
+
+print "Exercising irand()...\n"
+
+scale = 256
+
+pow = (maxrand() + 1) ^ 4
+s = 2^256 + 2^128 + (irand(pow) / pow)
+seed = s
+seed < s
+
+s = -459.125
+seed = s
+seed == -s
+
+irand(0)
+irand(1)
+seed == -s
+irand(maxrand() + 1) <= maxrand()
+
+for (i = 0; i < 200; ++i) {
+ irand(20) < 20
+}
+
+seed = 738
+seed != 738
+
+s = 2398@0625
+seed = s
+seed != s
+
+pow = (maxrand() + 1) ^ 4
+s = 2^2560 + 2^128 + (irand(pow) / pow)
+seed = s
+seed < s
+
+b = 0
+m = maxrand() + 1
+n = m + 1
+
+for (i = 0; !b && i < 100; ++i) {
+ c = irand(n)
+ b = (c != 0 && c != m)
+ if (c >= n) print "irand() result is too large.\n"
+}
+
+b
diff --git a/contrib/bc/tests/bc/rand_results.txt b/contrib/bc/tests/bc/rand_results.txt
new file mode 100644
index 000000000000..fc6177f718e7
--- /dev/null
+++ b/contrib/bc/tests/bc/rand_results.txt
@@ -0,0 +1,616 @@
+Gathering array...
+Testing implementation...
+86B1DA1D72062B68
+1304AA46C9853D39
+A3670E9E0DD50358
+F9090E529A7DAE00
+C85B9FD837996F2C
+606121F8E3919196
+7CE1C7FF478354BA
+CBC4AC70E541310E
+74BE71999EC37F2C
+B81F9C99A934F1A7
+120E9901A900C97F
+F983BAD4B19F493
+5934619363660D96
+D5A7FE2717A2014E
+6E437241C9E6676E
+6A75C9DD6329CD29
+2D9E477683673437
+51FB0CF3D4405437
+217BB90392D08B20
+47C528A018B07A82
+1B4E474C418C835E
+BDB2BDA74A119ED6
+C6DB79D0B9E43493
+C3CF4834E94A41D1
+AB8312FC7877C7DC
+94B108133E8B5EC
+37CA97AC830113BD
+EF02D7347F9192BF
+959517DD9896C53A
+7A80EB7629EFE9F9
+AE53C23F2B1CF57C
+CA605CD189F6D5CD
+921C2704886A9622
+B68C9FBF826AF7AA
+73F8C733124772C3
+6B57F7E459EFBCDF
+9DE7696DDB6B8E18
+2CA67560DC26877
+A24E353080777DEC
+4D600156763FD65C
+5CDF9C7E26DD2C38
+6A32443BBBB16774
+3D8415FFECFB8B7F
+3090ED9C475635A3
+6DBF241361C3E652
+2CA9EF5A2AD971FC
+44FBE937A1CF0FFC
+DB17CF0577CB7853
+AA3747D98D31B24C
+5D9A104C5D7F43F7
+BAE65E3E293B2C7B
+16A396F0DB4EF984
+6DD2BACDC4445A05
+7B7A13D1858E5CA8
+F73722BCAA52447C
+31A2C7BBE77CBA00
+7FC8AF9003BA1ACE
+5703F11DD3F235EF
+FA1952267EF836C7
+BBFA558C9E2D51E2
+3A29661D8145AF36
+608DEA6358DABD7C
+9E34E9E53431B447
+325A05E35EA524EB
+63A87CCF0C80ABB1
+8EA183287A46F292
+E2AA5F119CBF2A08
+2F3BEB0DE8B730C8
+4B8006A928CF8F5B
+57B8BA85069C201C
+3422D962DDF59474
+FD744940BA7366A1
+23D24B06B5DA4F6F
+AA187C608319D1DC
+DC60CA6FEA738B8A
+C9FC61DF96A769FE
+82E2457708658A20
+2BECEC9B3E7D93EC
+1340DAEC04588952
+F533446AD5C50B1D
+31FD1C7F434A62CE
+D16DAEDD1F281A39
+6B5D9648931D7057
+62FEE3392DBB06D5
+358BC87B00DF25A
+F3C882D22946175D
+65BA8F11B4516EFE
+2DA5A96E626DA4FE
+DCC669F4CD6121F0
+7A47FAC054319CA2
+9661CFEE277284C8
+1E483A14F4EB23A
+ADDC115507390607
+5AB47C343BD3B0BD
+4882FB3A3957B11F
+615B7C9C3626DD44
+F79CF49562969219
+88C32C194EA78D27
+DA8AFFE1353FF352
+A7A3C331A64CB146
+A1F53517A7BE0CAA
+7B47F409
+BA1D3330
+83D2F293
+BFA4784B
+CBED606E
+BFC6A3AD
+812FFF6D
+E61F305A
+F9384B90
+32DB86FE
+1DC035F9
+ED786826
+3822441D
+2BA113D7
+1C5B818B
+A233956A
+84DA65E3
+CED67292
+B2C0FE06
+91817130
+55FE8917
+47E92091
+486AF299
+B1E882BB
+C261E845
+1A9B90F6
+7964E884
+5F36D7A4
+1EE2052D
+8519F5D5
+293D4E4F
+6D8F99FC
+C3421509
+A06CD7C6
+E43064D3
+E20F9BF0
+401B50B7
+8EF1FF3E
+E357E2B2
+A4AEEE37
+2AD4426A
+9D11BE94
+7290C556
+6E6F3787
+50C2EE3
+4FD73703
+C6FF478B
+4B1CA1E1
+1654EA91
+CD08B2F2
+F7FF3DA8
+78B1B8DA
+A100602C
+9588585F
+DA028873
+66B4F376
+E6B4B9A
+48167094
+D58CDA0
+8F7238BE
+F79983F3
+7E5D324
+AD78DF52
+1532BA74
+1E4899E2
+6C75DF64
+171DDC36
+F2D8D74A
+24E6D907
+4780FD32
+9ADF408C
+A25544CF
+EFC6A738
+1AA23A54
+C5A13EBB
+F739EDC9
+C3A015FA
+3D5E1511
+AFC4D7FB
+3F413B5E
+4660CB73
+88FC773F
+D6BED59C
+63B3B54A
+D67D3DDE
+23394F8B
+13384B44
+DD8B3ABC
+FF59A21E
+3BB16D7E
+6E01CB68
+EC34790E
+B26C42AD
+D723C830
+DFD10FCA
+7E362AA1
+826FF323
+CB8F63B5
+9B3227E5
+9A61E339
+40BDACF
+Testing array...
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+Exercising irand()...
+1
+1
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/contrib/bc/tests/bc/read.txt b/contrib/bc/tests/bc/read.txt
new file mode 100644
index 000000000000..8d2f0971e2ce
--- /dev/null
+++ b/contrib/bc/tests/bc/read.txt
@@ -0,0 +1 @@
+1 + 1
diff --git a/contrib/bc/tests/bc/read_errors.txt b/contrib/bc/tests/bc/read_errors.txt
new file mode 100644
index 000000000000..1990eaeea621
--- /dev/null
+++ b/contrib/bc/tests/bc/read_errors.txt
@@ -0,0 +1,2 @@
+5+5;
+read()
diff --git a/contrib/bc/tests/bc/read_results.txt b/contrib/bc/tests/bc/read_results.txt
new file mode 100644
index 000000000000..0cfbf08886fc
--- /dev/null
+++ b/contrib/bc/tests/bc/read_results.txt
@@ -0,0 +1 @@
+2
diff --git a/contrib/bc/tests/bc/scale.txt b/contrib/bc/tests/bc/scale.txt
new file mode 100644
index 000000000000..e8bee791bce7
--- /dev/null
+++ b/contrib/bc/tests/bc/scale.txt
@@ -0,0 +1,57 @@
+scale(0)
+scale(1)
+scale(12)
+scale(123)
+scale(1234)
+scale(12345)
+scale(123456)
+scale(1234567)
+scale(12345678)
+scale(123456789)
+scale(1234567890)
+scale(1.0)
+scale(12.0)
+scale(123.0)
+scale(1234.0)
+scale(12345.0)
+scale(123456.0)
+scale(1234567.0)
+scale(12345678.0)
+scale(123456789.0)
+scale(1234567890.0)
+scale(.1)
+scale(.12)
+scale(.123)
+scale(.1234)
+scale(.12345)
+scale(.123456)
+scale(.1234567)
+scale(.12345678)
+scale(.123456789)
+scale(.1234567890)
+scale(.01)
+scale(.012)
+scale(.0123)
+scale(.01234)
+scale(.012345)
+scale(.0123456)
+scale(.01234567)
+scale(.012345678)
+scale(.0123456789)
+scale(.01234567890)
+scale(.0000000001)
+scale(.00000000012)
+scale(.000000000123)
+scale(.0000000001234)
+scale(.00000000012345)
+scale(.000000000123456)
+scale(.0000000001234567)
+scale(.00000000012345678)
+scale(.000000000123456789)
+scale(.0000000001234567890)
+scale(289.29837)
+scale(2893.00000)
+scale(289.0)
+scale(1802973.0000000238)
+scale(.000000000000000093182394080000000000)
+scale(0.00000000000000000000)
diff --git a/contrib/bc/tests/bc/scale_results.txt b/contrib/bc/tests/bc/scale_results.txt
new file mode 100644
index 000000000000..386ef5422173
--- /dev/null
+++ b/contrib/bc/tests/bc/scale_results.txt
@@ -0,0 +1,57 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+5
+5
+1
+10
+36
+20
diff --git a/contrib/bc/tests/bc/scientific.txt b/contrib/bc/tests/bc/scientific.txt
new file mode 100644
index 000000000000..bd04562a8df3
--- /dev/null
+++ b/contrib/bc/tests/bc/scientific.txt
@@ -0,0 +1,51 @@
+0e0
+0e1
+0e5
+0e-2
+0e-100
+1e0
+-1e1
+1e9
+-1e21
+1e-1
+-1e-2
+1e-5
+4.92837e5
+-3.28971028e20
+6.2e3
+-8.289371e2
+5.9817280937e8
+-3.28977e-1
+8.8927891e-20
+-7.98239e-4
+4.4892e-4
+-18937e0
+198273e10
+-18927e-4
+28937e-5
+-891072e-7
+.28972e0
+-.891273e-1
+.8928397e1
+-.0002983172e5
+.00022e3
+-.00022e4
+.0000328937e8
+obase=0
+0
+1
+10
+-289
+2894
+-89434
+894370
+-1239839
+28931708
+-8052098.8029731809
+.1
+-.01
+.001
+-.00038
+.0000483
+-.0002894378190
+.2893712083
diff --git a/contrib/bc/tests/bc/scientific_results.txt b/contrib/bc/tests/bc/scientific_results.txt
new file mode 100644
index 000000000000..557fcf61fe5e
--- /dev/null
+++ b/contrib/bc/tests/bc/scientific_results.txt
@@ -0,0 +1,50 @@
+0
+0
+0
+0
+0
+1
+-10
+1000000000
+-1000000000000000000000
+.1
+-.01
+.00001
+492837
+-328971028000000000000
+6200
+-828.9371
+598172809.37
+-.328977
+.000000000000000000088927891
+-.000798239
+.00044892
+-18937
+1982730000000000
+-1.8927
+.28937
+-.0891072
+.28972
+-.0891273
+8.928397
+-29.83172
+.22
+-2.2
+3289.37
+0
+1e0
+1.0e1
+-2.89e2
+2.894e3
+-8.9434e4
+8.94370e5
+-1.239839e6
+2.8931708e7
+-8.0520988029731809e6
+1e-1
+-1e-2
+1e-3
+-3.8e-4
+4.83e-5
+-2.894378190e-4
+2.893712083e-1
diff --git a/contrib/bc/tests/bc/scripts/add.bc b/contrib/bc/tests/bc/scripts/add.bc
new file mode 100644
index 000000000000..03f8581251be
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/add.bc
@@ -0,0 +1,17 @@
+#! /usr/bin/bc -lq
+
+scale = 20
+x = 1234567890 / scale
+len = length(x) + 1 + scale
+len *= 2
+
+for (i = 0; i <= len; ++i) {
+ a[i] = x * (10^i)
+ a[i]
+}
+
+for (i = 1; i <= 10000; ++i) {
+ for (j = 0; j < len; ++j) {
+ a[0] + a[j]
+ }
+}
diff --git a/contrib/bc/tests/bc/scripts/array.bc b/contrib/bc/tests/bc/scripts/array.bc
new file mode 100755
index 000000000000..dac232804914
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/array.bc
@@ -0,0 +1,60 @@
+#! /usr/bin/bc -q
+
+define z(a[]) {
+ for (i = 0; i < l; ++i) {
+ a[i]
+ }
+}
+
+define x(a[]) {
+
+ # Test for separate vars and arrays.
+ auto a
+
+ for (a = 0; a < l; ++a) {
+ a[a] = -a
+ }
+
+ z(a[])
+}
+
+define g(x[], y[]) {
+ return x[0] - y[0]
+}
+
+define h(y[], x[]) {
+ return g(x[], y[])
+}
+
+define m(*x[], *y[]) {
+ return x[0] / y[0]
+}
+
+define n(*y[], *x[]) {
+ return m(x[], y[])
+}
+
+for (i = 0; i < 101; ++i) {
+ a[i] = i
+}
+
+a[104] = 204
+
+l = length(a[])
+
+for (i = 0; i <= l; ++i) {
+ a[i]
+}
+
+z(a[])
+x(a[])
+z(a[])
+l
+
+x[0] = 5
+y[0] = 4
+
+h(x[], y[])
+n(x[], y[])
+
+halt
diff --git a/contrib/bc/tests/bc/scripts/array.txt b/contrib/bc/tests/bc/scripts/array.txt
new file mode 100644
index 000000000000..2e30ae5899e8
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/array.txt
@@ -0,0 +1,428 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+0
+0
+0
+204
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+0
+0
+0
+204
+0
+0
+-1
+-2
+-3
+-4
+-5
+-6
+-7
+-8
+-9
+-10
+-11
+-12
+-13
+-14
+-15
+-16
+-17
+-18
+-19
+-20
+-21
+-22
+-23
+-24
+-25
+-26
+-27
+-28
+-29
+-30
+-31
+-32
+-33
+-34
+-35
+-36
+-37
+-38
+-39
+-40
+-41
+-42
+-43
+-44
+-45
+-46
+-47
+-48
+-49
+-50
+-51
+-52
+-53
+-54
+-55
+-56
+-57
+-58
+-59
+-60
+-61
+-62
+-63
+-64
+-65
+-66
+-67
+-68
+-69
+-70
+-71
+-72
+-73
+-74
+-75
+-76
+-77
+-78
+-79
+-80
+-81
+-82
+-83
+-84
+-85
+-86
+-87
+-88
+-89
+-90
+-91
+-92
+-93
+-94
+-95
+-96
+-97
+-98
+-99
+-100
+-101
+-102
+-103
+-104
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+0
+0
+0
+204
+0
+105
+-1
+.80000000000000000000
diff --git a/contrib/bc/tests/bc/scripts/atan.bc b/contrib/bc/tests/bc/scripts/atan.bc
new file mode 100755
index 000000000000..9d47f415c5b5
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/atan.bc
@@ -0,0 +1,11 @@
+#! /usr/bin/bc -q
+
+for (i = 1; i <= 100; ++i) {
+ print "scale = ", i, "\n"
+ print "a(.267)\n"
+ print "a(1)\n"
+}
+
+print "halt\n"
+
+halt
diff --git a/contrib/bc/tests/bc/scripts/atan.txt b/contrib/bc/tests/bc/scripts/atan.txt
new file mode 100644
index 000000000000..f4383f544ec6
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/atan.txt
@@ -0,0 +1,301 @@
+scale = 1
+a(.267)
+a(1)
+scale = 2
+a(.267)
+a(1)
+scale = 3
+a(.267)
+a(1)
+scale = 4
+a(.267)
+a(1)
+scale = 5
+a(.267)
+a(1)
+scale = 6
+a(.267)
+a(1)
+scale = 7
+a(.267)
+a(1)
+scale = 8
+a(.267)
+a(1)
+scale = 9
+a(.267)
+a(1)
+scale = 10
+a(.267)
+a(1)
+scale = 11
+a(.267)
+a(1)
+scale = 12
+a(.267)
+a(1)
+scale = 13
+a(.267)
+a(1)
+scale = 14
+a(.267)
+a(1)
+scale = 15
+a(.267)
+a(1)
+scale = 16
+a(.267)
+a(1)
+scale = 17
+a(.267)
+a(1)
+scale = 18
+a(.267)
+a(1)
+scale = 19
+a(.267)
+a(1)
+scale = 20
+a(.267)
+a(1)
+scale = 21
+a(.267)
+a(1)
+scale = 22
+a(.267)
+a(1)
+scale = 23
+a(.267)
+a(1)
+scale = 24
+a(.267)
+a(1)
+scale = 25
+a(.267)
+a(1)
+scale = 26
+a(.267)
+a(1)
+scale = 27
+a(.267)
+a(1)
+scale = 28
+a(.267)
+a(1)
+scale = 29
+a(.267)
+a(1)
+scale = 30
+a(.267)
+a(1)
+scale = 31
+a(.267)
+a(1)
+scale = 32
+a(.267)
+a(1)
+scale = 33
+a(.267)
+a(1)
+scale = 34
+a(.267)
+a(1)
+scale = 35
+a(.267)
+a(1)
+scale = 36
+a(.267)
+a(1)
+scale = 37
+a(.267)
+a(1)
+scale = 38
+a(.267)
+a(1)
+scale = 39
+a(.267)
+a(1)
+scale = 40
+a(.267)
+a(1)
+scale = 41
+a(.267)
+a(1)
+scale = 42
+a(.267)
+a(1)
+scale = 43
+a(.267)
+a(1)
+scale = 44
+a(.267)
+a(1)
+scale = 45
+a(.267)
+a(1)
+scale = 46
+a(.267)
+a(1)
+scale = 47
+a(.267)
+a(1)
+scale = 48
+a(.267)
+a(1)
+scale = 49
+a(.267)
+a(1)
+scale = 50
+a(.267)
+a(1)
+scale = 51
+a(.267)
+a(1)
+scale = 52
+a(.267)
+a(1)
+scale = 53
+a(.267)
+a(1)
+scale = 54
+a(.267)
+a(1)
+scale = 55
+a(.267)
+a(1)
+scale = 56
+a(.267)
+a(1)
+scale = 57
+a(.267)
+a(1)
+scale = 58
+a(.267)
+a(1)
+scale = 59
+a(.267)
+a(1)
+scale = 60
+a(.267)
+a(1)
+scale = 61
+a(.267)
+a(1)
+scale = 62
+a(.267)
+a(1)
+scale = 63
+a(.267)
+a(1)
+scale = 64
+a(.267)
+a(1)
+scale = 65
+a(.267)
+a(1)
+scale = 66
+a(.267)
+a(1)
+scale = 67
+a(.267)
+a(1)
+scale = 68
+a(.267)
+a(1)
+scale = 69
+a(.267)
+a(1)
+scale = 70
+a(.267)
+a(1)
+scale = 71
+a(.267)
+a(1)
+scale = 72
+a(.267)
+a(1)
+scale = 73
+a(.267)
+a(1)
+scale = 74
+a(.267)
+a(1)
+scale = 75
+a(.267)
+a(1)
+scale = 76
+a(.267)
+a(1)
+scale = 77
+a(.267)
+a(1)
+scale = 78
+a(.267)
+a(1)
+scale = 79
+a(.267)
+a(1)
+scale = 80
+a(.267)
+a(1)
+scale = 81
+a(.267)
+a(1)
+scale = 82
+a(.267)
+a(1)
+scale = 83
+a(.267)
+a(1)
+scale = 84
+a(.267)
+a(1)
+scale = 85
+a(.267)
+a(1)
+scale = 86
+a(.267)
+a(1)
+scale = 87
+a(.267)
+a(1)
+scale = 88
+a(.267)
+a(1)
+scale = 89
+a(.267)
+a(1)
+scale = 90
+a(.267)
+a(1)
+scale = 91
+a(.267)
+a(1)
+scale = 92
+a(.267)
+a(1)
+scale = 93
+a(.267)
+a(1)
+scale = 94
+a(.267)
+a(1)
+scale = 95
+a(.267)
+a(1)
+scale = 96
+a(.267)
+a(1)
+scale = 97
+a(.267)
+a(1)
+scale = 98
+a(.267)
+a(1)
+scale = 99
+a(.267)
+a(1)
+scale = 100
+a(.267)
+a(1)
+halt
diff --git a/contrib/bc/tests/bc/scripts/bessel.bc b/contrib/bc/tests/bc/scripts/bessel.bc
new file mode 100755
index 000000000000..b82eee30d19e
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/bessel.bc
@@ -0,0 +1,43 @@
+#! /usr/bin/bc -q
+
+t[0] = 0
+t[1] = 0.5
+t[2] = 1
+t[3] = 1.5
+t[4] = 1.74
+t[5] = 2
+t[6] = 3.2345
+t[7] = 100
+t[8] = -0.5
+t[9] = -1
+t[10] = -1.5
+t[11] = -1.74
+t[12] = -2
+t[13] = -3.2345
+t[14] = -100
+
+l = 15
+
+a[0] = t[0]
+
+for (i = 1; i < l; ++i) {
+ a[i * 2 - 1] = t[i]
+ a[i * 2] = -t[i]
+}
+
+l *= 2
+l -= 1
+
+for (i = 0; i < l; ++i) {
+ for (j = 0; j < l; ++j) {
+ print "j(", a[i], ", ", a[j], ")\n"
+ }
+}
+
+# These are specific tests that bc could not pass at one time.
+print "j(3, 0.75)\n"
+print "scale = 0; j(40, 0.75)\n"
+
+print "halt\n"
+
+halt
diff --git a/contrib/bc/tests/bc/scripts/divide.bc b/contrib/bc/tests/bc/scripts/divide.bc
new file mode 100644
index 000000000000..8527ffc35666
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/divide.bc
@@ -0,0 +1,22 @@
+#! /usr/bin/bc -lq
+
+scale = 20
+x = 1234567890 * 10^(-scale)
+len = 1 + 2 * scale
+
+x
+scale += 10
+
+for (i = 0; i <= len; ++i) {
+ a[i] = x * (10^i)
+ a[i]
+}
+
+for (i = 1; i <= 10000; ++i) {
+ for (j = 0; j < len; ++j) {
+ a[0] / a[j]
+ (a[0] * i) / a[j]
+ a[0] / (a[j] * i)
+ (a[0] * i) / (a[j] * i)
+ }
+}
diff --git a/contrib/bc/tests/bc/scripts/functions.bc b/contrib/bc/tests/bc/scripts/functions.bc
new file mode 100644
index 000000000000..80d6d1623d8d
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/functions.bc
@@ -0,0 +1,7 @@
+e(0.5)
+
+define e(x) {
+ return x
+}
+
+e(0.5)
diff --git a/contrib/bc/tests/bc/scripts/functions.txt b/contrib/bc/tests/bc/scripts/functions.txt
new file mode 100644
index 000000000000..6e5975cb9d67
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/functions.txt
@@ -0,0 +1,2 @@
+1.64872127070012814684
+.5
diff --git a/contrib/bc/tests/bc/scripts/globals.bc b/contrib/bc/tests/bc/scripts/globals.bc
new file mode 100755
index 000000000000..e9a0c6dbacd3
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/globals.bc
@@ -0,0 +1,23 @@
+#! /usr/bin/bc -gq
+
+define i(x) {
+ ibase=x
+ return ibase
+}
+
+define o(x) {
+ obase=x
+ return obase
+}
+
+define r(x) {
+ scale=x
+ return scale
+}
+
+i(11)
+ibase
+o(12)
+obase
+r(15)
+scale
diff --git a/contrib/bc/tests/bc/scripts/globals.txt b/contrib/bc/tests/bc/scripts/globals.txt
new file mode 100644
index 000000000000..e7faccdfed0b
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/globals.txt
@@ -0,0 +1,6 @@
+11
+10
+12
+10
+15
+20
diff --git a/contrib/bc/tests/bc/scripts/len.bc b/contrib/bc/tests/bc/scripts/len.bc
new file mode 100644
index 000000000000..ec931f2386a5
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/len.bc
@@ -0,0 +1,48 @@
+define fast_gcd(a, b) {
+
+ if (a == b) return a;
+ if (a > b) return fast_gcd(a - b, b)
+
+ return fast_gcd(a, b - a);
+}
+
+define void r_reduce(*r[]) {
+
+ auto g,s;
+
+ if (length(r[]) != 2) sqrt(-1);
+ if (scale(r[0])) 2^r[0];
+ if (scale(r[1])) 2^r[1];
+
+ if (r[0] >= 0 && r[1] >= 0) g = fast_gcd(r[0], r[1]);
+ else g = gcd(r[0], r[1]);
+
+ s = scale;
+ scale = 0;
+
+ r[0] /= g;
+ r[1] /= g;
+
+ scale = s;
+}
+
+define void r_init(*r[], a, b) {
+ r[0] = a;
+ r[1] = b;
+ r_reduce(r[]);
+}
+
+define void r_initi(*r[], i, a, b) {
+
+ length(r[]);
+
+ r[0] = i * b + a;
+ r[1] = b;
+
+ length(r[]);
+
+ r_reduce(r[]);
+}
+
+length(a[])
+r_initi(a[], 5, 63, 94);
diff --git a/contrib/bc/tests/bc/scripts/len.txt b/contrib/bc/tests/bc/scripts/len.txt
new file mode 100644
index 000000000000..33280629d45d
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/len.txt
@@ -0,0 +1,3 @@
+1
+1
+2
diff --git a/contrib/bc/tests/bc/scripts/multiply.bc b/contrib/bc/tests/bc/scripts/multiply.bc
new file mode 100644
index 000000000000..2eb975aa68c4
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/multiply.bc
@@ -0,0 +1,19 @@
+#! /usr/bin/bc -lq
+
+scale = 20
+x = 1234567890 / scale
+len = length(x) + 1 + scale
+
+for (i = 0; i <= len; ++i) {
+ a[i] = x * (10^i)
+ a[i]
+}
+
+for (i = 1; i <= 10000; ++i) {
+ for (j = 0; j < len; ++j) {
+ a[0] * a[j]
+ (a[0] * i) * a[j]
+ a[0] * (a[j] * i)
+ (a[0] * i) * (a[j] * i)
+ }
+}
diff --git a/contrib/bc/tests/bc/scripts/parse.bc b/contrib/bc/tests/bc/scripts/parse.bc
new file mode 100755
index 000000000000..179daf116efd
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/parse.bc
@@ -0,0 +1,20 @@
+#! /usr/bin/bc -q
+
+for (b = 2; b <= 16; ++b) {
+ if (b == 10) continue
+ obase = 10
+ print "ibase = A; ibase = ", b, "\n"
+ print "\qibase = \q\n"
+ b
+ obase = b
+ for (i = 0; i <= 4096; ++i) {
+ i
+ print "0.", i, "\n"
+ print ".", i, "\n"
+ print "1.", i, "\n"
+ print i, ".", "\n"
+ print i, ".", i, "\n"
+ }
+}
+
+halt
diff --git a/contrib/bc/tests/bc/scripts/print.bc b/contrib/bc/tests/bc/scripts/print.bc
new file mode 100755
index 000000000000..9530cbdb3fc2
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/print.bc
@@ -0,0 +1,25 @@
+#! /usr/bin/bc -q
+
+for (b = 2; b <= 100; ++b) {
+
+ if (b == 10) continue
+
+ s = b * b
+
+ print "obase = ", b, "\n"
+ print "\qobase = \q\n"
+ b
+
+ for (i = 0; i <= s; ++i) {
+ i
+ print "0.", i, "\n"
+ print ".", i, "\n"
+ print "1.", i, "\n"
+ print i, ".", "\n"
+ print i, ".", i, "\n"
+ }
+
+ 2189432174861923048671023498128347619023487610234689172304.192748960128745108927461089237469018723460
+}
+
+halt
diff --git a/contrib/bc/tests/bc/scripts/rand.bc b/contrib/bc/tests/bc/scripts/rand.bc
new file mode 100644
index 000000000000..54173c713612
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/rand.bc
@@ -0,0 +1,97 @@
+#! /usr/bin/bc
+
+define x(x) {
+ seed = x
+ seed@20
+ return seed
+}
+
+define y(x) {
+ auto s
+ seed@20
+ s = x(x)
+ seed@20
+ return s
+}
+
+define void u(x) {
+ seed = x
+ seed@20
+}
+
+define void v(x) {
+ u(x)
+ seed@20
+}
+
+define g(x) {
+ auto s
+ s = irand(x)
+ s < x
+ return seed
+}
+
+define h(x) {
+ auto s
+ s = g(x)
+ s == seed
+ return s
+}
+
+define j(x) {
+ auto s, r
+ seed@20
+ s = seed
+ r = rand()
+ seed = x
+ s != seed
+ return rand()
+}
+
+define k(x) {
+ auto s, r
+ s = seed
+ seed@20
+ r = j(x)
+ s != seed
+ seed = x
+ rand() == r
+ return r
+}
+
+define m(*a[]) {
+ auto i
+ seed = seed
+ for (i = 0; i < 100; ++i) {
+ a[i] = rand()
+ }
+ return seed
+}
+
+v(50.5)
+seed@20
+
+s = y(75.25)
+s@20
+seed@20
+
+r = rand()
+i = irand(r)
+
+i < r
+
+s = h(maxrand() ^ 4)
+s == seed
+
+seed = 2398.0625
+r = k(38.45)
+seed = 38.45
+r == rand()
+
+s = m(a[])
+
+for (i = 0; i < 100; ++i) {
+ rand() == a[i]
+}
+
+s == seed
diff --git a/contrib/bc/tests/bc/scripts/rand.txt b/contrib/bc/tests/bc/scripts/rand.txt
new file mode 100644
index 000000000000..886daca15ec0
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/rand.txt
@@ -0,0 +1,119 @@
+50.50000000000000000000
+50.50000000000000000000
+50.50000000000000000000
+50.50000000000000000000
+75.25000000000000000000
+50.50000000000000000000
+75.25000000000000000000
+50.50000000000000000000
+1
+1
+1
+1
+2398.06250000000000000000
+2398.06250000000000000000
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/contrib/bc/tests/bc/scripts/references.bc b/contrib/bc/tests/bc/scripts/references.bc
new file mode 100755
index 000000000000..8188f17aa017
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/references.bc
@@ -0,0 +1,408 @@
+#! /usr/bin/bc -q
+
+define printarray(a[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a[i]
+ }
+}
+
+define a2(a[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a[i] = a[i] * a[i]
+ }
+
+ printarray(a[], len)
+}
+
+define a4(a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = a__[i] * a__[i]
+ }
+
+ printarray(a__[], len)
+}
+
+define a6(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = a__[i] * a__[i]
+ }
+
+ printarray(a__[], len)
+}
+
+define a1(*a[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a[i] = i
+ }
+
+ a2(a[], len)
+
+ printarray(a[], len)
+}
+
+define a3(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = i
+ }
+
+ a4(a__[], len)
+
+ printarray(a__[], len)
+}
+
+define a5(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = i
+ }
+
+ a2(a__[], len)
+
+ printarray(a__[], len)
+}
+
+define a7(*a__[], len) {
+
+ auto i
+
+ for (i = 0; i < len; ++i) {
+ a__[i] = i
+ }
+
+ a6(a__[], len)
+
+ printarray(a__[], len)
+}
+
+len = 16
+
+a1(a[], len)
+printarray(a[], len)
+a3(a[], len)
+printarray(a[], len)
+a5(a[], len)
+printarray(a[], len)
+a7(a[], len)
+printarray(a[], len)
+
+a1(b[], len)
+printarray(b[], len)
+a3(b[], len)
+printarray(b[], len)
+a5(b[], len)
+printarray(b[], len)
+a7(b[], len)
+printarray(b[], len)
+
+a1[0] = 0
+a2[0] = 0
+a3[0] = 0
+a4[0] = 0
+a5[0] = 0
+a6[0] = 0
+a7[0] = 0
+a8[0] = 0
+a9[0] = 0
+a10[0] = 0
+a11[0] = 0
+a12[0] = 0
+a13[0] = 0
+a14[0] = 0
+a15[0] = 0
+a16[0] = 0
+a17[0] = 0
+a18[0] = 0
+a19[0] = 0
+a20[0] = 0
+a21[0] = 0
+a22[0] = 0
+a23[0] = 0
+a24[0] = 0
+a25[0] = 0
+a26[0] = 0
+a27[0] = 0
+a28[0] = 0
+a29[0] = 0
+a30[0] = 0
+a31[0] = 0
+a32[0] = 0
+a33[0] = 0
+a34[0] = 0
+a35[0] = 0
+a36[0] = 0
+a37[0] = 0
+a38[0] = 0
+a39[0] = 0
+a40[0] = 0
+a41[0] = 0
+a42[0] = 0
+a43[0] = 0
+a44[0] = 0
+a45[0] = 0
+a46[0] = 0
+a47[0] = 0
+a48[0] = 0
+a49[0] = 0
+a50[0] = 0
+a51[0] = 0
+a52[0] = 0
+a53[0] = 0
+a54[0] = 0
+a55[0] = 0
+a56[0] = 0
+a57[0] = 0
+a58[0] = 0
+a59[0] = 0
+a60[0] = 0
+a61[0] = 0
+a62[0] = 0
+a63[0] = 0
+a64[0] = 0
+a65[0] = 0
+a66[0] = 0
+a67[0] = 0
+a68[0] = 0
+a69[0] = 0
+a70[0] = 0
+a71[0] = 0
+a72[0] = 0
+a73[0] = 0
+a74[0] = 0
+a75[0] = 0
+a76[0] = 0
+a77[0] = 0
+a78[0] = 0
+a79[0] = 0
+a80[0] = 0
+a81[0] = 0
+a82[0] = 0
+a83[0] = 0
+a84[0] = 0
+a85[0] = 0
+a86[0] = 0
+a87[0] = 0
+a88[0] = 0
+a89[0] = 0
+a90[0] = 0
+a91[0] = 0
+a92[0] = 0
+a93[0] = 0
+a94[0] = 0
+a95[0] = 0
+a96[0] = 0
+a97[0] = 0
+a98[0] = 0
+a99[0] = 0
+a100[0] = 0
+a101[0] = 0
+a102[0] = 0
+a103[0] = 0
+a104[0] = 0
+a105[0] = 0
+a106[0] = 0
+a107[0] = 0
+a108[0] = 0
+a109[0] = 0
+a110[0] = 0
+a111[0] = 0
+a112[0] = 0
+a113[0] = 0
+a114[0] = 0
+a115[0] = 0
+a116[0] = 0
+a117[0] = 0
+a118[0] = 0
+a119[0] = 0
+a120[0] = 0
+a121[0] = 0
+a122[0] = 0
+a123[0] = 0
+a124[0] = 0
+a125[0] = 0
+a126[0] = 0
+a127[0] = 0
+a128[0] = 0
+a129[0] = 0
+a130[0] = 0
+a131[0] = 0
+a132[0] = 0
+a133[0] = 0
+a134[0] = 0
+a135[0] = 0
+a136[0] = 0
+a137[0] = 0
+a138[0] = 0
+a139[0] = 0
+a140[0] = 0
+a141[0] = 0
+a142[0] = 0
+a143[0] = 0
+a144[0] = 0
+a145[0] = 0
+a146[0] = 0
+a147[0] = 0
+a148[0] = 0
+a149[0] = 0
+a150[0] = 0
+a151[0] = 0
+a152[0] = 0
+a153[0] = 0
+a154[0] = 0
+a155[0] = 0
+a156[0] = 0
+a157[0] = 0
+a158[0] = 0
+a159[0] = 0
+a160[0] = 0
+a161[0] = 0
+a162[0] = 0
+a163[0] = 0
+a164[0] = 0
+a165[0] = 0
+a166[0] = 0
+a167[0] = 0
+a168[0] = 0
+a169[0] = 0
+a170[0] = 0
+a171[0] = 0
+a172[0] = 0
+a173[0] = 0
+a174[0] = 0
+a175[0] = 0
+a176[0] = 0
+a177[0] = 0
+a178[0] = 0
+a179[0] = 0
+a180[0] = 0
+a181[0] = 0
+a182[0] = 0
+a183[0] = 0
+a184[0] = 0
+a185[0] = 0
+a186[0] = 0
+a187[0] = 0
+a188[0] = 0
+a189[0] = 0
+a190[0] = 0
+a191[0] = 0
+a192[0] = 0
+a193[0] = 0
+a194[0] = 0
+a195[0] = 0
+a196[0] = 0
+a197[0] = 0
+a198[0] = 0
+a199[0] = 0
+a200[0] = 0
+a201[0] = 0
+a202[0] = 0
+a203[0] = 0
+a204[0] = 0
+a205[0] = 0
+a206[0] = 0
+a207[0] = 0
+a208[0] = 0
+a209[0] = 0
+a210[0] = 0
+a211[0] = 0
+a212[0] = 0
+a213[0] = 0
+a214[0] = 0
+a215[0] = 0
+a216[0] = 0
+a217[0] = 0
+a218[0] = 0
+a219[0] = 0
+a220[0] = 0
+a221[0] = 0
+a222[0] = 0
+a223[0] = 0
+a224[0] = 0
+a225[0] = 0
+a226[0] = 0
+a227[0] = 0
+a228[0] = 0
+a229[0] = 0
+a230[0] = 0
+a231[0] = 0
+a232[0] = 0
+a233[0] = 0
+a234[0] = 0
+a235[0] = 0
+a236[0] = 0
+a237[0] = 0
+a238[0] = 0
+a239[0] = 0
+a240[0] = 0
+a241[0] = 0
+a242[0] = 0
+a243[0] = 0
+a244[0] = 0
+a245[0] = 0
+a246[0] = 0
+a247[0] = 0
+a248[0] = 0
+a249[0] = 0
+a250[0] = 0
+a251[0] = 0
+a252[0] = 0
+a253[0] = 0
+a254[0] = 0
+a255[0] = 0
+a256[0] = 0
+
+a1(a253[], len)
+printarray(a253[], len)
+a3(a253[], len)
+printarray(a253[], len)
+a5(a253[], len)
+printarray(a253[], len)
+a7(a253[], len)
+printarray(a253[], len)
+
+a1(a254[], len)
+printarray(a254[], len)
+a3(a254[], len)
+printarray(a254[], len)
+a5(a254[], len)
+printarray(a254[], len)
+a7(a254[], len)
+printarray(a254[], len)
+
+a1(a255[], len)
+printarray(a255[], len)
+a3(a255[], len)
+printarray(a255[], len)
+a5(a255[], len)
+printarray(a255[], len)
+a7(a255[], len)
+printarray(a255[], len)
+
+a1(a256[], len)
+printarray(a256[], len)
+a3(a256[], len)
+printarray(a256[], len)
+a5(a256[], len)
+printarray(a256[], len)
+a7(a256[], len)
+printarray(a256[], len)
diff --git a/contrib/bc/tests/bc/scripts/references.txt b/contrib/bc/tests/bc/scripts/references.txt
new file mode 100644
index 000000000000..1e5f65faf75c
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/references.txt
@@ -0,0 +1,1272 @@
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
+0
+0
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+121
+144
+169
+196
+225
+0
diff --git a/contrib/bc/tests/bc/scripts/screen.bc b/contrib/bc/tests/bc/scripts/screen.bc
new file mode 100755
index 000000000000..ea36b5ff4bea
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/screen.bc
@@ -0,0 +1,20 @@
+#! /usr/bin/bc -q
+
+define a(i, j) {
+ scale = 0
+ if(i % 2 == 0) return i;
+ if(j - i >= 0.5) return i + 1;
+ return i - 1;
+}
+
+define x(w, h, n) {
+ scale = 20
+ f = w / n
+ scale = 0
+ i = h / f
+ scale = 1
+ j = h / f
+ return a(i, j);
+}
+
+x(720, 576, 600)
diff --git a/contrib/bc/tests/bc/scripts/screen.txt b/contrib/bc/tests/bc/scripts/screen.txt
new file mode 100644
index 000000000000..36e082614b99
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/screen.txt
@@ -0,0 +1 @@
+480
diff --git a/contrib/bc/tests/bc/scripts/subtract.bc b/contrib/bc/tests/bc/scripts/subtract.bc
new file mode 100644
index 000000000000..81ac895c49ed
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/subtract.bc
@@ -0,0 +1,17 @@
+#! /usr/bin/bc -lq
+
+scale = 20
+x = 1234567890 / scale
+len = length(x) + 1 + scale
+len *= 2
+
+for (i = 0; i <= len; ++i) {
+ a[i] = x * (10^i)
+ a[i]
+}
+
+for (i = 1; i <= 10000; ++i) {
+ for (j = 0; j < len; ++j) {
+ a[0] - a[j]
+ }
+}
diff --git a/contrib/bc/tests/bc/shift.txt b/contrib/bc/tests/bc/shift.txt
new file mode 100644
index 000000000000..40b973358f96
--- /dev/null
+++ b/contrib/bc/tests/bc/shift.txt
@@ -0,0 +1,5341 @@
+0 << 0
+1 << 0
+2 << 0
+0.0023896 << 0
+1.298346 << 0
+2.00000000 << 0
+0.0023896 << 3
+1.298346 << 4
+2.00000000 << 5
+x = 89136.892348976
+x <<= 7
+x
+x = 1892634051829351283289298
+x <<= 24
+x
+0 >> 0
+1 >> 0
+2 >> 0
+0.0023896 >> 0
+1.298346 >> 0
+2.00000000 >> 0
+0.0023896 >> 3
+1.298346 >> 4
+2.00000000 >> 5
+x = 89136.892348976
+x >>= 7
+x
+x = 1892634051829351283289298
+x >>= 24
+x
+-1 << 0
+-2 << 0
+-0.0023896 << 0
+-1.298346 << 0
+-2.00000000 << 0
+-0.0023896 << 3
+-1.298346 << 4
+-2.00000000 << 5
+x = -89136.892348976
+x <<= 7
+x
+x = -1892634051829351283289298
+x <<= 24
+x
+-1 >> 0
+-2 >> 0
+-0.0023896 >> 0
+-1.298346 >> 0
+-2.00000000 >> 0
+-0.0023896 >> 3
+-1.298346 >> 4
+-2.00000000 >> 5
+x = -89136.892348976
+x >>= 7
+x
+-x
+x = -1892634051829351283289298
+x >>= 24
+x
+-x
+(0 >> 12) / 2
+0 << 0
+0 << 1
+0 << 2
+0 << 3
+0 << 4
+0 << 5
+0 << 6
+0 << 7
+0 << 8
+0 << 9
+0 << 10
+0 << 11
+0 << 12
+0 << 13
+0 << 14
+0 << 15
+0 << 16
+0 << 17
+0 << 18
+0 << 19
+0.1 << 0
+0.1 << 1
+0.1 << 2
+0.1 << 3
+0.1 << 4
+0.1 << 5
+0.1 << 6
+0.1 << 7
+0.1 << 8
+0.1 << 9
+0.1 << 10
+0.1 << 11
+0.1 << 12
+0.1 << 13
+0.1 << 14
+0.1 << 15
+0.1 << 16
+0.1 << 17
+0.1 << 18
+0.1 << 19
+0.01 << 0
+0.01 << 1
+0.01 << 2
+0.01 << 3
+0.01 << 4
+0.01 << 5
+0.01 << 6
+0.01 << 7
+0.01 << 8
+0.01 << 9
+0.01 << 10
+0.01 << 11
+0.01 << 12
+0.01 << 13
+0.01 << 14
+0.01 << 15
+0.01 << 16
+0.01 << 17
+0.01 << 18
+0.01 << 19
+0.001 << 0
+0.001 << 1
+0.001 << 2
+0.001 << 3
+0.001 << 4
+0.001 << 5
+0.001 << 6
+0.001 << 7
+0.001 << 8
+0.001 << 9
+0.001 << 10
+0.001 << 11
+0.001 << 12
+0.001 << 13
+0.001 << 14
+0.001 << 15
+0.001 << 16
+0.001 << 17
+0.001 << 18
+0.001 << 19
+0.0001 << 0
+0.0001 << 1
+0.0001 << 2
+0.0001 << 3
+0.0001 << 4
+0.0001 << 5
+0.0001 << 6
+0.0001 << 7
+0.0001 << 8
+0.0001 << 9
+0.0001 << 10
+0.0001 << 11
+0.0001 << 12
+0.0001 << 13
+0.0001 << 14
+0.0001 << 15
+0.0001 << 16
+0.0001 << 17
+0.0001 << 18
+0.0001 << 19
+0.00001 << 0
+0.00001 << 1
+0.00001 << 2
+0.00001 << 3
+0.00001 << 4
+0.00001 << 5
+0.00001 << 6
+0.00001 << 7
+0.00001 << 8
+0.00001 << 9
+0.00001 << 10
+0.00001 << 11
+0.00001 << 12
+0.00001 << 13
+0.00001 << 14
+0.00001 << 15
+0.00001 << 16
+0.00001 << 17
+0.00001 << 18
+0.00001 << 19
+0.000001 << 0
+0.000001 << 1
+0.000001 << 2
+0.000001 << 3
+0.000001 << 4
+0.000001 << 5
+0.000001 << 6
+0.000001 << 7
+0.000001 << 8
+0.000001 << 9
+0.000001 << 10
+0.000001 << 11
+0.000001 << 12
+0.000001 << 13
+0.000001 << 14
+0.000001 << 15
+0.000001 << 16
+0.000001 << 17
+0.000001 << 18
+0.000001 << 19
+0.0000001 << 0
+0.0000001 << 1
+0.0000001 << 2
+0.0000001 << 3
+0.0000001 << 4
+0.0000001 << 5
+0.0000001 << 6
+0.0000001 << 7
+0.0000001 << 8
+0.0000001 << 9
+0.0000001 << 10
+0.0000001 << 11
+0.0000001 << 12
+0.0000001 << 13
+0.0000001 << 14
+0.0000001 << 15
+0.0000001 << 16
+0.0000001 << 17
+0.0000001 << 18
+0.0000001 << 19
+0.00000001 << 0
+0.00000001 << 1
+0.00000001 << 2
+0.00000001 << 3
+0.00000001 << 4
+0.00000001 << 5
+0.00000001 << 6
+0.00000001 << 7
+0.00000001 << 8
+0.00000001 << 9
+0.00000001 << 10
+0.00000001 << 11
+0.00000001 << 12
+0.00000001 << 13
+0.00000001 << 14
+0.00000001 << 15
+0.00000001 << 16
+0.00000001 << 17
+0.00000001 << 18
+0.00000001 << 19
+0.000000001 << 0
+0.000000001 << 1
+0.000000001 << 2
+0.000000001 << 3
+0.000000001 << 4
+0.000000001 << 5
+0.000000001 << 6
+0.000000001 << 7
+0.000000001 << 8
+0.000000001 << 9
+0.000000001 << 10
+0.000000001 << 11
+0.000000001 << 12
+0.000000001 << 13
+0.000000001 << 14
+0.000000001 << 15
+0.000000001 << 16
+0.000000001 << 17
+0.000000001 << 18
+0.000000001 << 19
+0.0000000001 << 0
+0.0000000001 << 1
+0.0000000001 << 2
+0.0000000001 << 3
+0.0000000001 << 4
+0.0000000001 << 5
+0.0000000001 << 6
+0.0000000001 << 7
+0.0000000001 << 8
+0.0000000001 << 9
+0.0000000001 << 10
+0.0000000001 << 11
+0.0000000001 << 12
+0.0000000001 << 13
+0.0000000001 << 14
+0.0000000001 << 15
+0.0000000001 << 16
+0.0000000001 << 17
+0.0000000001 << 18
+0.0000000001 << 19
+1 << 0
+1 << 1
+1 << 2
+1 << 3
+1 << 4
+1 << 5
+1 << 6
+1 << 7
+1 << 8
+1 << 9
+1 << 10
+1 << 11
+1 << 12
+1 << 13
+1 << 14
+1 << 15
+1 << 16
+1 << 17
+1 << 18
+1 << 19
+1.1 << 0
+1.1 << 1
+1.1 << 2
+1.1 << 3
+1.1 << 4
+1.1 << 5
+1.1 << 6
+1.1 << 7
+1.1 << 8
+1.1 << 9
+1.1 << 10
+1.1 << 11
+1.1 << 12
+1.1 << 13
+1.1 << 14
+1.1 << 15
+1.1 << 16
+1.1 << 17
+1.1 << 18
+1.1 << 19
+1.01 << 0
+1.01 << 1
+1.01 << 2
+1.01 << 3
+1.01 << 4
+1.01 << 5
+1.01 << 6
+1.01 << 7
+1.01 << 8
+1.01 << 9
+1.01 << 10
+1.01 << 11
+1.01 << 12
+1.01 << 13
+1.01 << 14
+1.01 << 15
+1.01 << 16
+1.01 << 17
+1.01 << 18
+1.01 << 19
+1.001 << 0
+1.001 << 1
+1.001 << 2
+1.001 << 3
+1.001 << 4
+1.001 << 5
+1.001 << 6
+1.001 << 7
+1.001 << 8
+1.001 << 9
+1.001 << 10
+1.001 << 11
+1.001 << 12
+1.001 << 13
+1.001 << 14
+1.001 << 15
+1.001 << 16
+1.001 << 17
+1.001 << 18
+1.001 << 19
+1.0001 << 0
+1.0001 << 1
+1.0001 << 2
+1.0001 << 3
+1.0001 << 4
+1.0001 << 5
+1.0001 << 6
+1.0001 << 7
+1.0001 << 8
+1.0001 << 9
+1.0001 << 10
+1.0001 << 11
+1.0001 << 12
+1.0001 << 13
+1.0001 << 14
+1.0001 << 15
+1.0001 << 16
+1.0001 << 17
+1.0001 << 18
+1.0001 << 19
+1.00001 << 0
+1.00001 << 1
+1.00001 << 2
+1.00001 << 3
+1.00001 << 4
+1.00001 << 5
+1.00001 << 6
+1.00001 << 7
+1.00001 << 8
+1.00001 << 9
+1.00001 << 10
+1.00001 << 11
+1.00001 << 12
+1.00001 << 13
+1.00001 << 14
+1.00001 << 15
+1.00001 << 16
+1.00001 << 17
+1.00001 << 18
+1.00001 << 19
+1.000001 << 0
+1.000001 << 1
+1.000001 << 2
+1.000001 << 3
+1.000001 << 4
+1.000001 << 5
+1.000001 << 6
+1.000001 << 7
+1.000001 << 8
+1.000001 << 9
+1.000001 << 10
+1.000001 << 11
+1.000001 << 12
+1.000001 << 13
+1.000001 << 14
+1.000001 << 15
+1.000001 << 16
+1.000001 << 17
+1.000001 << 18
+1.000001 << 19
+1.0000001 << 0
+1.0000001 << 1
+1.0000001 << 2
+1.0000001 << 3
+1.0000001 << 4
+1.0000001 << 5
+1.0000001 << 6
+1.0000001 << 7
+1.0000001 << 8
+1.0000001 << 9
+1.0000001 << 10
+1.0000001 << 11
+1.0000001 << 12
+1.0000001 << 13
+1.0000001 << 14
+1.0000001 << 15
+1.0000001 << 16
+1.0000001 << 17
+1.0000001 << 18
+1.0000001 << 19
+1.00000001 << 0
+1.00000001 << 1
+1.00000001 << 2
+1.00000001 << 3
+1.00000001 << 4
+1.00000001 << 5
+1.00000001 << 6
+1.00000001 << 7
+1.00000001 << 8
+1.00000001 << 9
+1.00000001 << 10
+1.00000001 << 11
+1.00000001 << 12
+1.00000001 << 13
+1.00000001 << 14
+1.00000001 << 15
+1.00000001 << 16
+1.00000001 << 17
+1.00000001 << 18
+1.00000001 << 19
+1.000000001 << 0
+1.000000001 << 1
+1.000000001 << 2
+1.000000001 << 3
+1.000000001 << 4
+1.000000001 << 5
+1.000000001 << 6
+1.000000001 << 7
+1.000000001 << 8
+1.000000001 << 9
+1.000000001 << 10
+1.000000001 << 11
+1.000000001 << 12
+1.000000001 << 13
+1.000000001 << 14
+1.000000001 << 15
+1.000000001 << 16
+1.000000001 << 17
+1.000000001 << 18
+1.000000001 << 19
+1.0000000001 << 0
+1.0000000001 << 1
+1.0000000001 << 2
+1.0000000001 << 3
+1.0000000001 << 4
+1.0000000001 << 5
+1.0000000001 << 6
+1.0000000001 << 7
+1.0000000001 << 8
+1.0000000001 << 9
+1.0000000001 << 10
+1.0000000001 << 11
+1.0000000001 << 12
+1.0000000001 << 13
+1.0000000001 << 14
+1.0000000001 << 15
+1.0000000001 << 16
+1.0000000001 << 17
+1.0000000001 << 18
+1.0000000001 << 19
+10 << 0
+10 << 1
+10 << 2
+10 << 3
+10 << 4
+10 << 5
+10 << 6
+10 << 7
+10 << 8
+10 << 9
+10 << 10
+10 << 11
+10 << 12
+10 << 13
+10 << 14
+10 << 15
+10 << 16
+10 << 17
+10 << 18
+10 << 19
+10.1 << 0
+10.1 << 1
+10.1 << 2
+10.1 << 3
+10.1 << 4
+10.1 << 5
+10.1 << 6
+10.1 << 7
+10.1 << 8
+10.1 << 9
+10.1 << 10
+10.1 << 11
+10.1 << 12
+10.1 << 13
+10.1 << 14
+10.1 << 15
+10.1 << 16
+10.1 << 17
+10.1 << 18
+10.1 << 19
+10.01 << 0
+10.01 << 1
+10.01 << 2
+10.01 << 3
+10.01 << 4
+10.01 << 5
+10.01 << 6
+10.01 << 7
+10.01 << 8
+10.01 << 9
+10.01 << 10
+10.01 << 11
+10.01 << 12
+10.01 << 13
+10.01 << 14
+10.01 << 15
+10.01 << 16
+10.01 << 17
+10.01 << 18
+10.01 << 19
+10.001 << 0
+10.001 << 1
+10.001 << 2
+10.001 << 3
+10.001 << 4
+10.001 << 5
+10.001 << 6
+10.001 << 7
+10.001 << 8
+10.001 << 9
+10.001 << 10
+10.001 << 11
+10.001 << 12
+10.001 << 13
+10.001 << 14
+10.001 << 15
+10.001 << 16
+10.001 << 17
+10.001 << 18
+10.001 << 19
+10.0001 << 0
+10.0001 << 1
+10.0001 << 2
+10.0001 << 3
+10.0001 << 4
+10.0001 << 5
+10.0001 << 6
+10.0001 << 7
+10.0001 << 8
+10.0001 << 9
+10.0001 << 10
+10.0001 << 11
+10.0001 << 12
+10.0001 << 13
+10.0001 << 14
+10.0001 << 15
+10.0001 << 16
+10.0001 << 17
+10.0001 << 18
+10.0001 << 19
+10.00001 << 0
+10.00001 << 1
+10.00001 << 2
+10.00001 << 3
+10.00001 << 4
+10.00001 << 5
+10.00001 << 6
+10.00001 << 7
+10.00001 << 8
+10.00001 << 9
+10.00001 << 10
+10.00001 << 11
+10.00001 << 12
+10.00001 << 13
+10.00001 << 14
+10.00001 << 15
+10.00001 << 16
+10.00001 << 17
+10.00001 << 18
+10.00001 << 19
+10.000001 << 0
+10.000001 << 1
+10.000001 << 2
+10.000001 << 3
+10.000001 << 4
+10.000001 << 5
+10.000001 << 6
+10.000001 << 7
+10.000001 << 8
+10.000001 << 9
+10.000001 << 10
+10.000001 << 11
+10.000001 << 12
+10.000001 << 13
+10.000001 << 14
+10.000001 << 15
+10.000001 << 16
+10.000001 << 17
+10.000001 << 18
+10.000001 << 19
+10.0000001 << 0
+10.0000001 << 1
+10.0000001 << 2
+10.0000001 << 3
+10.0000001 << 4
+10.0000001 << 5
+10.0000001 << 6
+10.0000001 << 7
+10.0000001 << 8
+10.0000001 << 9
+10.0000001 << 10
+10.0000001 << 11
+10.0000001 << 12
+10.0000001 << 13
+10.0000001 << 14
+10.0000001 << 15
+10.0000001 << 16
+10.0000001 << 17
+10.0000001 << 18
+10.0000001 << 19
+10.00000001 << 0
+10.00000001 << 1
+10.00000001 << 2
+10.00000001 << 3
+10.00000001 << 4
+10.00000001 << 5
+10.00000001 << 6
+10.00000001 << 7
+10.00000001 << 8
+10.00000001 << 9
+10.00000001 << 10
+10.00000001 << 11
+10.00000001 << 12
+10.00000001 << 13
+10.00000001 << 14
+10.00000001 << 15
+10.00000001 << 16
+10.00000001 << 17
+10.00000001 << 18
+10.00000001 << 19
+10.000000001 << 0
+10.000000001 << 1
+10.000000001 << 2
+10.000000001 << 3
+10.000000001 << 4
+10.000000001 << 5
+10.000000001 << 6
+10.000000001 << 7
+10.000000001 << 8
+10.000000001 << 9
+10.000000001 << 10
+10.000000001 << 11
+10.000000001 << 12
+10.000000001 << 13
+10.000000001 << 14
+10.000000001 << 15
+10.000000001 << 16
+10.000000001 << 17
+10.000000001 << 18
+10.000000001 << 19
+10.0000000001 << 0
+10.0000000001 << 1
+10.0000000001 << 2
+10.0000000001 << 3
+10.0000000001 << 4
+10.0000000001 << 5
+10.0000000001 << 6
+10.0000000001 << 7
+10.0000000001 << 8
+10.0000000001 << 9
+10.0000000001 << 10
+10.0000000001 << 11
+10.0000000001 << 12
+10.0000000001 << 13
+10.0000000001 << 14
+10.0000000001 << 15
+10.0000000001 << 16
+10.0000000001 << 17
+10.0000000001 << 18
+10.0000000001 << 19
+100 << 0
+100 << 1
+100 << 2
+100 << 3
+100 << 4
+100 << 5
+100 << 6
+100 << 7
+100 << 8
+100 << 9
+100 << 10
+100 << 11
+100 << 12
+100 << 13
+100 << 14
+100 << 15
+100 << 16
+100 << 17
+100 << 18
+100 << 19
+100.1 << 0
+100.1 << 1
+100.1 << 2
+100.1 << 3
+100.1 << 4
+100.1 << 5
+100.1 << 6
+100.1 << 7
+100.1 << 8
+100.1 << 9
+100.1 << 10
+100.1 << 11
+100.1 << 12
+100.1 << 13
+100.1 << 14
+100.1 << 15
+100.1 << 16
+100.1 << 17
+100.1 << 18
+100.1 << 19
+100.01 << 0
+100.01 << 1
+100.01 << 2
+100.01 << 3
+100.01 << 4
+100.01 << 5
+100.01 << 6
+100.01 << 7
+100.01 << 8
+100.01 << 9
+100.01 << 10
+100.01 << 11
+100.01 << 12
+100.01 << 13
+100.01 << 14
+100.01 << 15
+100.01 << 16
+100.01 << 17
+100.01 << 18
+100.01 << 19
+100.001 << 0
+100.001 << 1
+100.001 << 2
+100.001 << 3
+100.001 << 4
+100.001 << 5
+100.001 << 6
+100.001 << 7
+100.001 << 8
+100.001 << 9
+100.001 << 10
+100.001 << 11
+100.001 << 12
+100.001 << 13
+100.001 << 14
+100.001 << 15
+100.001 << 16
+100.001 << 17
+100.001 << 18
+100.001 << 19
+100.0001 << 0
+100.0001 << 1
+100.0001 << 2
+100.0001 << 3
+100.0001 << 4
+100.0001 << 5
+100.0001 << 6
+100.0001 << 7
+100.0001 << 8
+100.0001 << 9
+100.0001 << 10
+100.0001 << 11
+100.0001 << 12
+100.0001 << 13
+100.0001 << 14
+100.0001 << 15
+100.0001 << 16
+100.0001 << 17
+100.0001 << 18
+100.0001 << 19
+100.00001 << 0
+100.00001 << 1
+100.00001 << 2
+100.00001 << 3
+100.00001 << 4
+100.00001 << 5
+100.00001 << 6
+100.00001 << 7
+100.00001 << 8
+100.00001 << 9
+100.00001 << 10
+100.00001 << 11
+100.00001 << 12
+100.00001 << 13
+100.00001 << 14
+100.00001 << 15
+100.00001 << 16
+100.00001 << 17
+100.00001 << 18
+100.00001 << 19
+100.000001 << 0
+100.000001 << 1
+100.000001 << 2
+100.000001 << 3
+100.000001 << 4
+100.000001 << 5
+100.000001 << 6
+100.000001 << 7
+100.000001 << 8
+100.000001 << 9
+100.000001 << 10
+100.000001 << 11
+100.000001 << 12
+100.000001 << 13
+100.000001 << 14
+100.000001 << 15
+100.000001 << 16
+100.000001 << 17
+100.000001 << 18
+100.000001 << 19
+100.0000001 << 0
+100.0000001 << 1
+100.0000001 << 2
+100.0000001 << 3
+100.0000001 << 4
+100.0000001 << 5
+100.0000001 << 6
+100.0000001 << 7
+100.0000001 << 8
+100.0000001 << 9
+100.0000001 << 10
+100.0000001 << 11
+100.0000001 << 12
+100.0000001 << 13
+100.0000001 << 14
+100.0000001 << 15
+100.0000001 << 16
+100.0000001 << 17
+100.0000001 << 18
+100.0000001 << 19
+100.00000001 << 0
+100.00000001 << 1
+100.00000001 << 2
+100.00000001 << 3
+100.00000001 << 4
+100.00000001 << 5
+100.00000001 << 6
+100.00000001 << 7
+100.00000001 << 8
+100.00000001 << 9
+100.00000001 << 10
+100.00000001 << 11
+100.00000001 << 12
+100.00000001 << 13
+100.00000001 << 14
+100.00000001 << 15
+100.00000001 << 16
+100.00000001 << 17
+100.00000001 << 18
+100.00000001 << 19
+100.000000001 << 0
+100.000000001 << 1
+100.000000001 << 2
+100.000000001 << 3
+100.000000001 << 4
+100.000000001 << 5
+100.000000001 << 6
+100.000000001 << 7
+100.000000001 << 8
+100.000000001 << 9
+100.000000001 << 10
+100.000000001 << 11
+100.000000001 << 12
+100.000000001 << 13
+100.000000001 << 14
+100.000000001 << 15
+100.000000001 << 16
+100.000000001 << 17
+100.000000001 << 18
+100.000000001 << 19
+100.0000000001 << 0
+100.0000000001 << 1
+100.0000000001 << 2
+100.0000000001 << 3
+100.0000000001 << 4
+100.0000000001 << 5
+100.0000000001 << 6
+100.0000000001 << 7
+100.0000000001 << 8
+100.0000000001 << 9
+100.0000000001 << 10
+100.0000000001 << 11
+100.0000000001 << 12
+100.0000000001 << 13
+100.0000000001 << 14
+100.0000000001 << 15
+100.0000000001 << 16
+100.0000000001 << 17
+100.0000000001 << 18
+100.0000000001 << 19
+1000 << 0
+1000 << 1
+1000 << 2
+1000 << 3
+1000 << 4
+1000 << 5
+1000 << 6
+1000 << 7
+1000 << 8
+1000 << 9
+1000 << 10
+1000 << 11
+1000 << 12
+1000 << 13
+1000 << 14
+1000 << 15
+1000 << 16
+1000 << 17
+1000 << 18
+1000 << 19
+1000.1 << 0
+1000.1 << 1
+1000.1 << 2
+1000.1 << 3
+1000.1 << 4
+1000.1 << 5
+1000.1 << 6
+1000.1 << 7
+1000.1 << 8
+1000.1 << 9
+1000.1 << 10
+1000.1 << 11
+1000.1 << 12
+1000.1 << 13
+1000.1 << 14
+1000.1 << 15
+1000.1 << 16
+1000.1 << 17
+1000.1 << 18
+1000.1 << 19
+1000.01 << 0
+1000.01 << 1
+1000.01 << 2
+1000.01 << 3
+1000.01 << 4
+1000.01 << 5
+1000.01 << 6
+1000.01 << 7
+1000.01 << 8
+1000.01 << 9
+1000.01 << 10
+1000.01 << 11
+1000.01 << 12
+1000.01 << 13
+1000.01 << 14
+1000.01 << 15
+1000.01 << 16
+1000.01 << 17
+1000.01 << 18
+1000.01 << 19
+1000.001 << 0
+1000.001 << 1
+1000.001 << 2
+1000.001 << 3
+1000.001 << 4
+1000.001 << 5
+1000.001 << 6
+1000.001 << 7
+1000.001 << 8
+1000.001 << 9
+1000.001 << 10
+1000.001 << 11
+1000.001 << 12
+1000.001 << 13
+1000.001 << 14
+1000.001 << 15
+1000.001 << 16
+1000.001 << 17
+1000.001 << 18
+1000.001 << 19
+1000.0001 << 0
+1000.0001 << 1
+1000.0001 << 2
+1000.0001 << 3
+1000.0001 << 4
+1000.0001 << 5
+1000.0001 << 6
+1000.0001 << 7
+1000.0001 << 8
+1000.0001 << 9
+1000.0001 << 10
+1000.0001 << 11
+1000.0001 << 12
+1000.0001 << 13
+1000.0001 << 14
+1000.0001 << 15
+1000.0001 << 16
+1000.0001 << 17
+1000.0001 << 18
+1000.0001 << 19
+1000.00001 << 0
+1000.00001 << 1
+1000.00001 << 2
+1000.00001 << 3
+1000.00001 << 4
+1000.00001 << 5
+1000.00001 << 6
+1000.00001 << 7
+1000.00001 << 8
+1000.00001 << 9
+1000.00001 << 10
+1000.00001 << 11
+1000.00001 << 12
+1000.00001 << 13
+1000.00001 << 14
+1000.00001 << 15
+1000.00001 << 16
+1000.00001 << 17
+1000.00001 << 18
+1000.00001 << 19
+1000.000001 << 0
+1000.000001 << 1
+1000.000001 << 2
+1000.000001 << 3
+1000.000001 << 4
+1000.000001 << 5
+1000.000001 << 6
+1000.000001 << 7
+1000.000001 << 8
+1000.000001 << 9
+1000.000001 << 10
+1000.000001 << 11
+1000.000001 << 12
+1000.000001 << 13
+1000.000001 << 14
+1000.000001 << 15
+1000.000001 << 16
+1000.000001 << 17
+1000.000001 << 18
+1000.000001 << 19
+1000.0000001 << 0
+1000.0000001 << 1
+1000.0000001 << 2
+1000.0000001 << 3
+1000.0000001 << 4
+1000.0000001 << 5
+1000.0000001 << 6
+1000.0000001 << 7
+1000.0000001 << 8
+1000.0000001 << 9
+1000.0000001 << 10
+1000.0000001 << 11
+1000.0000001 << 12
+1000.0000001 << 13
+1000.0000001 << 14
+1000.0000001 << 15
+1000.0000001 << 16
+1000.0000001 << 17
+1000.0000001 << 18
+1000.0000001 << 19
+1000.00000001 << 0
+1000.00000001 << 1
+1000.00000001 << 2
+1000.00000001 << 3
+1000.00000001 << 4
+1000.00000001 << 5
+1000.00000001 << 6
+1000.00000001 << 7
+1000.00000001 << 8
+1000.00000001 << 9
+1000.00000001 << 10
+1000.00000001 << 11
+1000.00000001 << 12
+1000.00000001 << 13
+1000.00000001 << 14
+1000.00000001 << 15
+1000.00000001 << 16
+1000.00000001 << 17
+1000.00000001 << 18
+1000.00000001 << 19
+1000.000000001 << 0
+1000.000000001 << 1
+1000.000000001 << 2
+1000.000000001 << 3
+1000.000000001 << 4
+1000.000000001 << 5
+1000.000000001 << 6
+1000.000000001 << 7
+1000.000000001 << 8
+1000.000000001 << 9
+1000.000000001 << 10
+1000.000000001 << 11
+1000.000000001 << 12
+1000.000000001 << 13
+1000.000000001 << 14
+1000.000000001 << 15
+1000.000000001 << 16
+1000.000000001 << 17
+1000.000000001 << 18
+1000.000000001 << 19
+1000.0000000001 << 0
+1000.0000000001 << 1
+1000.0000000001 << 2
+1000.0000000001 << 3
+1000.0000000001 << 4
+1000.0000000001 << 5
+1000.0000000001 << 6
+1000.0000000001 << 7
+1000.0000000001 << 8
+1000.0000000001 << 9
+1000.0000000001 << 10
+1000.0000000001 << 11
+1000.0000000001 << 12
+1000.0000000001 << 13
+1000.0000000001 << 14
+1000.0000000001 << 15
+1000.0000000001 << 16
+1000.0000000001 << 17
+1000.0000000001 << 18
+1000.0000000001 << 19
+10000 << 0
+10000 << 1
+10000 << 2
+10000 << 3
+10000 << 4
+10000 << 5
+10000 << 6
+10000 << 7
+10000 << 8
+10000 << 9
+10000 << 10
+10000 << 11
+10000 << 12
+10000 << 13
+10000 << 14
+10000 << 15
+10000 << 16
+10000 << 17
+10000 << 18
+10000 << 19
+10000.1 << 0
+10000.1 << 1
+10000.1 << 2
+10000.1 << 3
+10000.1 << 4
+10000.1 << 5
+10000.1 << 6
+10000.1 << 7
+10000.1 << 8
+10000.1 << 9
+10000.1 << 10
+10000.1 << 11
+10000.1 << 12
+10000.1 << 13
+10000.1 << 14
+10000.1 << 15
+10000.1 << 16
+10000.1 << 17
+10000.1 << 18
+10000.1 << 19
+10000.01 << 0
+10000.01 << 1
+10000.01 << 2
+10000.01 << 3
+10000.01 << 4
+10000.01 << 5
+10000.01 << 6
+10000.01 << 7
+10000.01 << 8
+10000.01 << 9
+10000.01 << 10
+10000.01 << 11
+10000.01 << 12
+10000.01 << 13
+10000.01 << 14
+10000.01 << 15
+10000.01 << 16
+10000.01 << 17
+10000.01 << 18
+10000.01 << 19
+10000.001 << 0
+10000.001 << 1
+10000.001 << 2
+10000.001 << 3
+10000.001 << 4
+10000.001 << 5
+10000.001 << 6
+10000.001 << 7
+10000.001 << 8
+10000.001 << 9
+10000.001 << 10
+10000.001 << 11
+10000.001 << 12
+10000.001 << 13
+10000.001 << 14
+10000.001 << 15
+10000.001 << 16
+10000.001 << 17
+10000.001 << 18
+10000.001 << 19
+10000.0001 << 0
+10000.0001 << 1
+10000.0001 << 2
+10000.0001 << 3
+10000.0001 << 4
+10000.0001 << 5
+10000.0001 << 6
+10000.0001 << 7
+10000.0001 << 8
+10000.0001 << 9
+10000.0001 << 10
+10000.0001 << 11
+10000.0001 << 12
+10000.0001 << 13
+10000.0001 << 14
+10000.0001 << 15
+10000.0001 << 16
+10000.0001 << 17
+10000.0001 << 18
+10000.0001 << 19
+10000.00001 << 0
+10000.00001 << 1
+10000.00001 << 2
+10000.00001 << 3
+10000.00001 << 4
+10000.00001 << 5
+10000.00001 << 6
+10000.00001 << 7
+10000.00001 << 8
+10000.00001 << 9
+10000.00001 << 10
+10000.00001 << 11
+10000.00001 << 12
+10000.00001 << 13
+10000.00001 << 14
+10000.00001 << 15
+10000.00001 << 16
+10000.00001 << 17
+10000.00001 << 18
+10000.00001 << 19
+10000.000001 << 0
+10000.000001 << 1
+10000.000001 << 2
+10000.000001 << 3
+10000.000001 << 4
+10000.000001 << 5
+10000.000001 << 6
+10000.000001 << 7
+10000.000001 << 8
+10000.000001 << 9
+10000.000001 << 10
+10000.000001 << 11
+10000.000001 << 12
+10000.000001 << 13
+10000.000001 << 14
+10000.000001 << 15
+10000.000001 << 16
+10000.000001 << 17
+10000.000001 << 18
+10000.000001 << 19
+10000.0000001 << 0
+10000.0000001 << 1
+10000.0000001 << 2
+10000.0000001 << 3
+10000.0000001 << 4
+10000.0000001 << 5
+10000.0000001 << 6
+10000.0000001 << 7
+10000.0000001 << 8
+10000.0000001 << 9
+10000.0000001 << 10
+10000.0000001 << 11
+10000.0000001 << 12
+10000.0000001 << 13
+10000.0000001 << 14
+10000.0000001 << 15
+10000.0000001 << 16
+10000.0000001 << 17
+10000.0000001 << 18
+10000.0000001 << 19
+10000.00000001 << 0
+10000.00000001 << 1
+10000.00000001 << 2
+10000.00000001 << 3
+10000.00000001 << 4
+10000.00000001 << 5
+10000.00000001 << 6
+10000.00000001 << 7
+10000.00000001 << 8
+10000.00000001 << 9
+10000.00000001 << 10
+10000.00000001 << 11
+10000.00000001 << 12
+10000.00000001 << 13
+10000.00000001 << 14
+10000.00000001 << 15
+10000.00000001 << 16
+10000.00000001 << 17
+10000.00000001 << 18
+10000.00000001 << 19
+10000.000000001 << 0
+10000.000000001 << 1
+10000.000000001 << 2
+10000.000000001 << 3
+10000.000000001 << 4
+10000.000000001 << 5
+10000.000000001 << 6
+10000.000000001 << 7
+10000.000000001 << 8
+10000.000000001 << 9
+10000.000000001 << 10
+10000.000000001 << 11
+10000.000000001 << 12
+10000.000000001 << 13
+10000.000000001 << 14
+10000.000000001 << 15
+10000.000000001 << 16
+10000.000000001 << 17
+10000.000000001 << 18
+10000.000000001 << 19
+10000.0000000001 << 0
+10000.0000000001 << 1
+10000.0000000001 << 2
+10000.0000000001 << 3
+10000.0000000001 << 4
+10000.0000000001 << 5
+10000.0000000001 << 6
+10000.0000000001 << 7
+10000.0000000001 << 8
+10000.0000000001 << 9
+10000.0000000001 << 10
+10000.0000000001 << 11
+10000.0000000001 << 12
+10000.0000000001 << 13
+10000.0000000001 << 14
+10000.0000000001 << 15
+10000.0000000001 << 16
+10000.0000000001 << 17
+10000.0000000001 << 18
+10000.0000000001 << 19
+100000 << 0
+100000 << 1
+100000 << 2
+100000 << 3
+100000 << 4
+100000 << 5
+100000 << 6
+100000 << 7
+100000 << 8
+100000 << 9
+100000 << 10
+100000 << 11
+100000 << 12
+100000 << 13
+100000 << 14
+100000 << 15
+100000 << 16
+100000 << 17
+100000 << 18
+100000 << 19
+100000.1 << 0
+100000.1 << 1
+100000.1 << 2
+100000.1 << 3
+100000.1 << 4
+100000.1 << 5
+100000.1 << 6
+100000.1 << 7
+100000.1 << 8
+100000.1 << 9
+100000.1 << 10
+100000.1 << 11
+100000.1 << 12
+100000.1 << 13
+100000.1 << 14
+100000.1 << 15
+100000.1 << 16
+100000.1 << 17
+100000.1 << 18
+100000.1 << 19
+100000.01 << 0
+100000.01 << 1
+100000.01 << 2
+100000.01 << 3
+100000.01 << 4
+100000.01 << 5
+100000.01 << 6
+100000.01 << 7
+100000.01 << 8
+100000.01 << 9
+100000.01 << 10
+100000.01 << 11
+100000.01 << 12
+100000.01 << 13
+100000.01 << 14
+100000.01 << 15
+100000.01 << 16
+100000.01 << 17
+100000.01 << 18
+100000.01 << 19
+100000.001 << 0
+100000.001 << 1
+100000.001 << 2
+100000.001 << 3
+100000.001 << 4
+100000.001 << 5
+100000.001 << 6
+100000.001 << 7
+100000.001 << 8
+100000.001 << 9
+100000.001 << 10
+100000.001 << 11
+100000.001 << 12
+100000.001 << 13
+100000.001 << 14
+100000.001 << 15
+100000.001 << 16
+100000.001 << 17
+100000.001 << 18
+100000.001 << 19
+100000.0001 << 0
+100000.0001 << 1
+100000.0001 << 2
+100000.0001 << 3
+100000.0001 << 4
+100000.0001 << 5
+100000.0001 << 6
+100000.0001 << 7
+100000.0001 << 8
+100000.0001 << 9
+100000.0001 << 10
+100000.0001 << 11
+100000.0001 << 12
+100000.0001 << 13
+100000.0001 << 14
+100000.0001 << 15
+100000.0001 << 16
+100000.0001 << 17
+100000.0001 << 18
+100000.0001 << 19
+100000.00001 << 0
+100000.00001 << 1
+100000.00001 << 2
+100000.00001 << 3
+100000.00001 << 4
+100000.00001 << 5
+100000.00001 << 6
+100000.00001 << 7
+100000.00001 << 8
+100000.00001 << 9
+100000.00001 << 10
+100000.00001 << 11
+100000.00001 << 12
+100000.00001 << 13
+100000.00001 << 14
+100000.00001 << 15
+100000.00001 << 16
+100000.00001 << 17
+100000.00001 << 18
+100000.00001 << 19
+100000.000001 << 0
+100000.000001 << 1
+100000.000001 << 2
+100000.000001 << 3
+100000.000001 << 4
+100000.000001 << 5
+100000.000001 << 6
+100000.000001 << 7
+100000.000001 << 8
+100000.000001 << 9
+100000.000001 << 10
+100000.000001 << 11
+100000.000001 << 12
+100000.000001 << 13
+100000.000001 << 14
+100000.000001 << 15
+100000.000001 << 16
+100000.000001 << 17
+100000.000001 << 18
+100000.000001 << 19
+100000.0000001 << 0
+100000.0000001 << 1
+100000.0000001 << 2
+100000.0000001 << 3
+100000.0000001 << 4
+100000.0000001 << 5
+100000.0000001 << 6
+100000.0000001 << 7
+100000.0000001 << 8
+100000.0000001 << 9
+100000.0000001 << 10
+100000.0000001 << 11
+100000.0000001 << 12
+100000.0000001 << 13
+100000.0000001 << 14
+100000.0000001 << 15
+100000.0000001 << 16
+100000.0000001 << 17
+100000.0000001 << 18
+100000.0000001 << 19
+100000.00000001 << 0
+100000.00000001 << 1
+100000.00000001 << 2
+100000.00000001 << 3
+100000.00000001 << 4
+100000.00000001 << 5
+100000.00000001 << 6
+100000.00000001 << 7
+100000.00000001 << 8
+100000.00000001 << 9
+100000.00000001 << 10
+100000.00000001 << 11
+100000.00000001 << 12
+100000.00000001 << 13
+100000.00000001 << 14
+100000.00000001 << 15
+100000.00000001 << 16
+100000.00000001 << 17
+100000.00000001 << 18
+100000.00000001 << 19
+100000.000000001 << 0
+100000.000000001 << 1
+100000.000000001 << 2
+100000.000000001 << 3
+100000.000000001 << 4
+100000.000000001 << 5
+100000.000000001 << 6
+100000.000000001 << 7
+100000.000000001 << 8
+100000.000000001 << 9
+100000.000000001 << 10
+100000.000000001 << 11
+100000.000000001 << 12
+100000.000000001 << 13
+100000.000000001 << 14
+100000.000000001 << 15
+100000.000000001 << 16
+100000.000000001 << 17
+100000.000000001 << 18
+100000.000000001 << 19
+100000.0000000001 << 0
+100000.0000000001 << 1
+100000.0000000001 << 2
+100000.0000000001 << 3
+100000.0000000001 << 4
+100000.0000000001 << 5
+100000.0000000001 << 6
+100000.0000000001 << 7
+100000.0000000001 << 8
+100000.0000000001 << 9
+100000.0000000001 << 10
+100000.0000000001 << 11
+100000.0000000001 << 12
+100000.0000000001 << 13
+100000.0000000001 << 14
+100000.0000000001 << 15
+100000.0000000001 << 16
+100000.0000000001 << 17
+100000.0000000001 << 18
+100000.0000000001 << 19
+1000000 << 0
+1000000 << 1
+1000000 << 2
+1000000 << 3
+1000000 << 4
+1000000 << 5
+1000000 << 6
+1000000 << 7
+1000000 << 8
+1000000 << 9
+1000000 << 10
+1000000 << 11
+1000000 << 12
+1000000 << 13
+1000000 << 14
+1000000 << 15
+1000000 << 16
+1000000 << 17
+1000000 << 18
+1000000 << 19
+1000000.1 << 0
+1000000.1 << 1
+1000000.1 << 2
+1000000.1 << 3
+1000000.1 << 4
+1000000.1 << 5
+1000000.1 << 6
+1000000.1 << 7
+1000000.1 << 8
+1000000.1 << 9
+1000000.1 << 10
+1000000.1 << 11
+1000000.1 << 12
+1000000.1 << 13
+1000000.1 << 14
+1000000.1 << 15
+1000000.1 << 16
+1000000.1 << 17
+1000000.1 << 18
+1000000.1 << 19
+1000000.01 << 0
+1000000.01 << 1
+1000000.01 << 2
+1000000.01 << 3
+1000000.01 << 4
+1000000.01 << 5
+1000000.01 << 6
+1000000.01 << 7
+1000000.01 << 8
+1000000.01 << 9
+1000000.01 << 10
+1000000.01 << 11
+1000000.01 << 12
+1000000.01 << 13
+1000000.01 << 14
+1000000.01 << 15
+1000000.01 << 16
+1000000.01 << 17
+1000000.01 << 18
+1000000.01 << 19
+1000000.001 << 0
+1000000.001 << 1
+1000000.001 << 2
+1000000.001 << 3
+1000000.001 << 4
+1000000.001 << 5
+1000000.001 << 6
+1000000.001 << 7
+1000000.001 << 8
+1000000.001 << 9
+1000000.001 << 10
+1000000.001 << 11
+1000000.001 << 12
+1000000.001 << 13
+1000000.001 << 14
+1000000.001 << 15
+1000000.001 << 16
+1000000.001 << 17
+1000000.001 << 18
+1000000.001 << 19
+1000000.0001 << 0
+1000000.0001 << 1
+1000000.0001 << 2
+1000000.0001 << 3
+1000000.0001 << 4
+1000000.0001 << 5
+1000000.0001 << 6
+1000000.0001 << 7
+1000000.0001 << 8
+1000000.0001 << 9
+1000000.0001 << 10
+1000000.0001 << 11
+1000000.0001 << 12
+1000000.0001 << 13
+1000000.0001 << 14
+1000000.0001 << 15
+1000000.0001 << 16
+1000000.0001 << 17
+1000000.0001 << 18
+1000000.0001 << 19
+1000000.00001 << 0
+1000000.00001 << 1
+1000000.00001 << 2
+1000000.00001 << 3
+1000000.00001 << 4
+1000000.00001 << 5
+1000000.00001 << 6
+1000000.00001 << 7
+1000000.00001 << 8
+1000000.00001 << 9
+1000000.00001 << 10
+1000000.00001 << 11
+1000000.00001 << 12
+1000000.00001 << 13
+1000000.00001 << 14
+1000000.00001 << 15
+1000000.00001 << 16
+1000000.00001 << 17
+1000000.00001 << 18
+1000000.00001 << 19
+1000000.000001 << 0
+1000000.000001 << 1
+1000000.000001 << 2
+1000000.000001 << 3
+1000000.000001 << 4
+1000000.000001 << 5
+1000000.000001 << 6
+1000000.000001 << 7
+1000000.000001 << 8
+1000000.000001 << 9
+1000000.000001 << 10
+1000000.000001 << 11
+1000000.000001 << 12
+1000000.000001 << 13
+1000000.000001 << 14
+1000000.000001 << 15
+1000000.000001 << 16
+1000000.000001 << 17
+1000000.000001 << 18
+1000000.000001 << 19
+1000000.0000001 << 0
+1000000.0000001 << 1
+1000000.0000001 << 2
+1000000.0000001 << 3
+1000000.0000001 << 4
+1000000.0000001 << 5
+1000000.0000001 << 6
+1000000.0000001 << 7
+1000000.0000001 << 8
+1000000.0000001 << 9
+1000000.0000001 << 10
+1000000.0000001 << 11
+1000000.0000001 << 12
+1000000.0000001 << 13
+1000000.0000001 << 14
+1000000.0000001 << 15
+1000000.0000001 << 16
+1000000.0000001 << 17
+1000000.0000001 << 18
+1000000.0000001 << 19
+1000000.00000001 << 0
+1000000.00000001 << 1
+1000000.00000001 << 2
+1000000.00000001 << 3
+1000000.00000001 << 4
+1000000.00000001 << 5
+1000000.00000001 << 6
+1000000.00000001 << 7
+1000000.00000001 << 8
+1000000.00000001 << 9
+1000000.00000001 << 10
+1000000.00000001 << 11
+1000000.00000001 << 12
+1000000.00000001 << 13
+1000000.00000001 << 14
+1000000.00000001 << 15
+1000000.00000001 << 16
+1000000.00000001 << 17
+1000000.00000001 << 18
+1000000.00000001 << 19
+1000000.000000001 << 0
+1000000.000000001 << 1
+1000000.000000001 << 2
+1000000.000000001 << 3
+1000000.000000001 << 4
+1000000.000000001 << 5
+1000000.000000001 << 6
+1000000.000000001 << 7
+1000000.000000001 << 8
+1000000.000000001 << 9
+1000000.000000001 << 10
+1000000.000000001 << 11
+1000000.000000001 << 12
+1000000.000000001 << 13
+1000000.000000001 << 14
+1000000.000000001 << 15
+1000000.000000001 << 16
+1000000.000000001 << 17
+1000000.000000001 << 18
+1000000.000000001 << 19
+1000000.0000000001 << 0
+1000000.0000000001 << 1
+1000000.0000000001 << 2
+1000000.0000000001 << 3
+1000000.0000000001 << 4
+1000000.0000000001 << 5
+1000000.0000000001 << 6
+1000000.0000000001 << 7
+1000000.0000000001 << 8
+1000000.0000000001 << 9
+1000000.0000000001 << 10
+1000000.0000000001 << 11
+1000000.0000000001 << 12
+1000000.0000000001 << 13
+1000000.0000000001 << 14
+1000000.0000000001 << 15
+1000000.0000000001 << 16
+1000000.0000000001 << 17
+1000000.0000000001 << 18
+1000000.0000000001 << 19
+10000000 << 0
+10000000 << 1
+10000000 << 2
+10000000 << 3
+10000000 << 4
+10000000 << 5
+10000000 << 6
+10000000 << 7
+10000000 << 8
+10000000 << 9
+10000000 << 10
+10000000 << 11
+10000000 << 12
+10000000 << 13
+10000000 << 14
+10000000 << 15
+10000000 << 16
+10000000 << 17
+10000000 << 18
+10000000 << 19
+10000000.1 << 0
+10000000.1 << 1
+10000000.1 << 2
+10000000.1 << 3
+10000000.1 << 4
+10000000.1 << 5
+10000000.1 << 6
+10000000.1 << 7
+10000000.1 << 8
+10000000.1 << 9
+10000000.1 << 10
+10000000.1 << 11
+10000000.1 << 12
+10000000.1 << 13
+10000000.1 << 14
+10000000.1 << 15
+10000000.1 << 16
+10000000.1 << 17
+10000000.1 << 18
+10000000.1 << 19
+10000000.01 << 0
+10000000.01 << 1
+10000000.01 << 2
+10000000.01 << 3
+10000000.01 << 4
+10000000.01 << 5
+10000000.01 << 6
+10000000.01 << 7
+10000000.01 << 8
+10000000.01 << 9
+10000000.01 << 10
+10000000.01 << 11
+10000000.01 << 12
+10000000.01 << 13
+10000000.01 << 14
+10000000.01 << 15
+10000000.01 << 16
+10000000.01 << 17
+10000000.01 << 18
+10000000.01 << 19
+10000000.001 << 0
+10000000.001 << 1
+10000000.001 << 2
+10000000.001 << 3
+10000000.001 << 4
+10000000.001 << 5
+10000000.001 << 6
+10000000.001 << 7
+10000000.001 << 8
+10000000.001 << 9
+10000000.001 << 10
+10000000.001 << 11
+10000000.001 << 12
+10000000.001 << 13
+10000000.001 << 14
+10000000.001 << 15
+10000000.001 << 16
+10000000.001 << 17
+10000000.001 << 18
+10000000.001 << 19
+10000000.0001 << 0
+10000000.0001 << 1
+10000000.0001 << 2
+10000000.0001 << 3
+10000000.0001 << 4
+10000000.0001 << 5
+10000000.0001 << 6
+10000000.0001 << 7
+10000000.0001 << 8
+10000000.0001 << 9
+10000000.0001 << 10
+10000000.0001 << 11
+10000000.0001 << 12
+10000000.0001 << 13
+10000000.0001 << 14
+10000000.0001 << 15
+10000000.0001 << 16
+10000000.0001 << 17
+10000000.0001 << 18
+10000000.0001 << 19
+10000000.00001 << 0
+10000000.00001 << 1
+10000000.00001 << 2
+10000000.00001 << 3
+10000000.00001 << 4
+10000000.00001 << 5
+10000000.00001 << 6
+10000000.00001 << 7
+10000000.00001 << 8
+10000000.00001 << 9
+10000000.00001 << 10
+10000000.00001 << 11
+10000000.00001 << 12
+10000000.00001 << 13
+10000000.00001 << 14
+10000000.00001 << 15
+10000000.00001 << 16
+10000000.00001 << 17
+10000000.00001 << 18
+10000000.00001 << 19
+10000000.000001 << 0
+10000000.000001 << 1
+10000000.000001 << 2
+10000000.000001 << 3
+10000000.000001 << 4
+10000000.000001 << 5
+10000000.000001 << 6
+10000000.000001 << 7
+10000000.000001 << 8
+10000000.000001 << 9
+10000000.000001 << 10
+10000000.000001 << 11
+10000000.000001 << 12
+10000000.000001 << 13
+10000000.000001 << 14
+10000000.000001 << 15
+10000000.000001 << 16
+10000000.000001 << 17
+10000000.000001 << 18
+10000000.000001 << 19
+10000000.0000001 << 0
+10000000.0000001 << 1
+10000000.0000001 << 2
+10000000.0000001 << 3
+10000000.0000001 << 4
+10000000.0000001 << 5
+10000000.0000001 << 6
+10000000.0000001 << 7
+10000000.0000001 << 8
+10000000.0000001 << 9
+10000000.0000001 << 10
+10000000.0000001 << 11
+10000000.0000001 << 12
+10000000.0000001 << 13
+10000000.0000001 << 14
+10000000.0000001 << 15
+10000000.0000001 << 16
+10000000.0000001 << 17
+10000000.0000001 << 18
+10000000.0000001 << 19
+10000000.00000001 << 0
+10000000.00000001 << 1
+10000000.00000001 << 2
+10000000.00000001 << 3
+10000000.00000001 << 4
+10000000.00000001 << 5
+10000000.00000001 << 6
+10000000.00000001 << 7
+10000000.00000001 << 8
+10000000.00000001 << 9
+10000000.00000001 << 10
+10000000.00000001 << 11
+10000000.00000001 << 12
+10000000.00000001 << 13
+10000000.00000001 << 14
+10000000.00000001 << 15
+10000000.00000001 << 16
+10000000.00000001 << 17
+10000000.00000001 << 18
+10000000.00000001 << 19
+10000000.000000001 << 0
+10000000.000000001 << 1
+10000000.000000001 << 2
+10000000.000000001 << 3
+10000000.000000001 << 4
+10000000.000000001 << 5
+10000000.000000001 << 6
+10000000.000000001 << 7
+10000000.000000001 << 8
+10000000.000000001 << 9
+10000000.000000001 << 10
+10000000.000000001 << 11
+10000000.000000001 << 12
+10000000.000000001 << 13
+10000000.000000001 << 14
+10000000.000000001 << 15
+10000000.000000001 << 16
+10000000.000000001 << 17
+10000000.000000001 << 18
+10000000.000000001 << 19
+10000000.0000000001 << 0
+10000000.0000000001 << 1
+10000000.0000000001 << 2
+10000000.0000000001 << 3
+10000000.0000000001 << 4
+10000000.0000000001 << 5
+10000000.0000000001 << 6
+10000000.0000000001 << 7
+10000000.0000000001 << 8
+10000000.0000000001 << 9
+10000000.0000000001 << 10
+10000000.0000000001 << 11
+10000000.0000000001 << 12
+10000000.0000000001 << 13
+10000000.0000000001 << 14
+10000000.0000000001 << 15
+10000000.0000000001 << 16
+10000000.0000000001 << 17
+10000000.0000000001 << 18
+10000000.0000000001 << 19
+100000000 << 0
+100000000 << 1
+100000000 << 2
+100000000 << 3
+100000000 << 4
+100000000 << 5
+100000000 << 6
+100000000 << 7
+100000000 << 8
+100000000 << 9
+100000000 << 10
+100000000 << 11
+100000000 << 12
+100000000 << 13
+100000000 << 14
+100000000 << 15
+100000000 << 16
+100000000 << 17
+100000000 << 18
+100000000 << 19
+100000000.1 << 0
+100000000.1 << 1
+100000000.1 << 2
+100000000.1 << 3
+100000000.1 << 4
+100000000.1 << 5
+100000000.1 << 6
+100000000.1 << 7
+100000000.1 << 8
+100000000.1 << 9
+100000000.1 << 10
+100000000.1 << 11
+100000000.1 << 12
+100000000.1 << 13
+100000000.1 << 14
+100000000.1 << 15
+100000000.1 << 16
+100000000.1 << 17
+100000000.1 << 18
+100000000.1 << 19
+100000000.01 << 0
+100000000.01 << 1
+100000000.01 << 2
+100000000.01 << 3
+100000000.01 << 4
+100000000.01 << 5
+100000000.01 << 6
+100000000.01 << 7
+100000000.01 << 8
+100000000.01 << 9
+100000000.01 << 10
+100000000.01 << 11
+100000000.01 << 12
+100000000.01 << 13
+100000000.01 << 14
+100000000.01 << 15
+100000000.01 << 16
+100000000.01 << 17
+100000000.01 << 18
+100000000.01 << 19
+100000000.001 << 0
+100000000.001 << 1
+100000000.001 << 2
+100000000.001 << 3
+100000000.001 << 4
+100000000.001 << 5
+100000000.001 << 6
+100000000.001 << 7
+100000000.001 << 8
+100000000.001 << 9
+100000000.001 << 10
+100000000.001 << 11
+100000000.001 << 12
+100000000.001 << 13
+100000000.001 << 14
+100000000.001 << 15
+100000000.001 << 16
+100000000.001 << 17
+100000000.001 << 18
+100000000.001 << 19
+100000000.0001 << 0
+100000000.0001 << 1
+100000000.0001 << 2
+100000000.0001 << 3
+100000000.0001 << 4
+100000000.0001 << 5
+100000000.0001 << 6
+100000000.0001 << 7
+100000000.0001 << 8
+100000000.0001 << 9
+100000000.0001 << 10
+100000000.0001 << 11
+100000000.0001 << 12
+100000000.0001 << 13
+100000000.0001 << 14
+100000000.0001 << 15
+100000000.0001 << 16
+100000000.0001 << 17
+100000000.0001 << 18
+100000000.0001 << 19
+100000000.00001 << 0
+100000000.00001 << 1
+100000000.00001 << 2
+100000000.00001 << 3
+100000000.00001 << 4
+100000000.00001 << 5
+100000000.00001 << 6
+100000000.00001 << 7
+100000000.00001 << 8
+100000000.00001 << 9
+100000000.00001 << 10
+100000000.00001 << 11
+100000000.00001 << 12
+100000000.00001 << 13
+100000000.00001 << 14
+100000000.00001 << 15
+100000000.00001 << 16
+100000000.00001 << 17
+100000000.00001 << 18
+100000000.00001 << 19
+100000000.000001 << 0
+100000000.000001 << 1
+100000000.000001 << 2
+100000000.000001 << 3
+100000000.000001 << 4
+100000000.000001 << 5
+100000000.000001 << 6
+100000000.000001 << 7
+100000000.000001 << 8
+100000000.000001 << 9
+100000000.000001 << 10
+100000000.000001 << 11
+100000000.000001 << 12
+100000000.000001 << 13
+100000000.000001 << 14
+100000000.000001 << 15
+100000000.000001 << 16
+100000000.000001 << 17
+100000000.000001 << 18
+100000000.000001 << 19
+100000000.0000001 << 0
+100000000.0000001 << 1
+100000000.0000001 << 2
+100000000.0000001 << 3
+100000000.0000001 << 4
+100000000.0000001 << 5
+100000000.0000001 << 6
+100000000.0000001 << 7
+100000000.0000001 << 8
+100000000.0000001 << 9
+100000000.0000001 << 10
+100000000.0000001 << 11
+100000000.0000001 << 12
+100000000.0000001 << 13
+100000000.0000001 << 14
+100000000.0000001 << 15
+100000000.0000001 << 16
+100000000.0000001 << 17
+100000000.0000001 << 18
+100000000.0000001 << 19
+100000000.00000001 << 0
+100000000.00000001 << 1
+100000000.00000001 << 2
+100000000.00000001 << 3
+100000000.00000001 << 4
+100000000.00000001 << 5
+100000000.00000001 << 6
+100000000.00000001 << 7
+100000000.00000001 << 8
+100000000.00000001 << 9
+100000000.00000001 << 10
+100000000.00000001 << 11
+100000000.00000001 << 12
+100000000.00000001 << 13
+100000000.00000001 << 14
+100000000.00000001 << 15
+100000000.00000001 << 16
+100000000.00000001 << 17
+100000000.00000001 << 18
+100000000.00000001 << 19
+100000000.000000001 << 0
+100000000.000000001 << 1
+100000000.000000001 << 2
+100000000.000000001 << 3
+100000000.000000001 << 4
+100000000.000000001 << 5
+100000000.000000001 << 6
+100000000.000000001 << 7
+100000000.000000001 << 8
+100000000.000000001 << 9
+100000000.000000001 << 10
+100000000.000000001 << 11
+100000000.000000001 << 12
+100000000.000000001 << 13
+100000000.000000001 << 14
+100000000.000000001 << 15
+100000000.000000001 << 16
+100000000.000000001 << 17
+100000000.000000001 << 18
+100000000.000000001 << 19
+100000000.0000000001 << 0
+100000000.0000000001 << 1
+100000000.0000000001 << 2
+100000000.0000000001 << 3
+100000000.0000000001 << 4
+100000000.0000000001 << 5
+100000000.0000000001 << 6
+100000000.0000000001 << 7
+100000000.0000000001 << 8
+100000000.0000000001 << 9
+100000000.0000000001 << 10
+100000000.0000000001 << 11
+100000000.0000000001 << 12
+100000000.0000000001 << 13
+100000000.0000000001 << 14
+100000000.0000000001 << 15
+100000000.0000000001 << 16
+100000000.0000000001 << 17
+100000000.0000000001 << 18
+100000000.0000000001 << 19
+1000000000 << 0
+1000000000 << 1
+1000000000 << 2
+1000000000 << 3
+1000000000 << 4
+1000000000 << 5
+1000000000 << 6
+1000000000 << 7
+1000000000 << 8
+1000000000 << 9
+1000000000 << 10
+1000000000 << 11
+1000000000 << 12
+1000000000 << 13
+1000000000 << 14
+1000000000 << 15
+1000000000 << 16
+1000000000 << 17
+1000000000 << 18
+1000000000 << 19
+1000000000.1 << 0
+1000000000.1 << 1
+1000000000.1 << 2
+1000000000.1 << 3
+1000000000.1 << 4
+1000000000.1 << 5
+1000000000.1 << 6
+1000000000.1 << 7
+1000000000.1 << 8
+1000000000.1 << 9
+1000000000.1 << 10
+1000000000.1 << 11
+1000000000.1 << 12
+1000000000.1 << 13
+1000000000.1 << 14
+1000000000.1 << 15
+1000000000.1 << 16
+1000000000.1 << 17
+1000000000.1 << 18
+1000000000.1 << 19
+1000000000.01 << 0
+1000000000.01 << 1
+1000000000.01 << 2
+1000000000.01 << 3
+1000000000.01 << 4
+1000000000.01 << 5
+1000000000.01 << 6
+1000000000.01 << 7
+1000000000.01 << 8
+1000000000.01 << 9
+1000000000.01 << 10
+1000000000.01 << 11
+1000000000.01 << 12
+1000000000.01 << 13
+1000000000.01 << 14
+1000000000.01 << 15
+1000000000.01 << 16
+1000000000.01 << 17
+1000000000.01 << 18
+1000000000.01 << 19
+1000000000.001 << 0
+1000000000.001 << 1
+1000000000.001 << 2
+1000000000.001 << 3
+1000000000.001 << 4
+1000000000.001 << 5
+1000000000.001 << 6
+1000000000.001 << 7
+1000000000.001 << 8
+1000000000.001 << 9
+1000000000.001 << 10
+1000000000.001 << 11
+1000000000.001 << 12
+1000000000.001 << 13
+1000000000.001 << 14
+1000000000.001 << 15
+1000000000.001 << 16
+1000000000.001 << 17
+1000000000.001 << 18
+1000000000.001 << 19
+1000000000.0001 << 0
+1000000000.0001 << 1
+1000000000.0001 << 2
+1000000000.0001 << 3
+1000000000.0001 << 4
+1000000000.0001 << 5
+1000000000.0001 << 6
+1000000000.0001 << 7
+1000000000.0001 << 8
+1000000000.0001 << 9
+1000000000.0001 << 10
+1000000000.0001 << 11
+1000000000.0001 << 12
+1000000000.0001 << 13
+1000000000.0001 << 14
+1000000000.0001 << 15
+1000000000.0001 << 16
+1000000000.0001 << 17
+1000000000.0001 << 18
+1000000000.0001 << 19
+1000000000.00001 << 0
+1000000000.00001 << 1
+1000000000.00001 << 2
+1000000000.00001 << 3
+1000000000.00001 << 4
+1000000000.00001 << 5
+1000000000.00001 << 6
+1000000000.00001 << 7
+1000000000.00001 << 8
+1000000000.00001 << 9
+1000000000.00001 << 10
+1000000000.00001 << 11
+1000000000.00001 << 12
+1000000000.00001 << 13
+1000000000.00001 << 14
+1000000000.00001 << 15
+1000000000.00001 << 16
+1000000000.00001 << 17
+1000000000.00001 << 18
+1000000000.00001 << 19
+1000000000.000001 << 0
+1000000000.000001 << 1
+1000000000.000001 << 2
+1000000000.000001 << 3
+1000000000.000001 << 4
+1000000000.000001 << 5
+1000000000.000001 << 6
+1000000000.000001 << 7
+1000000000.000001 << 8
+1000000000.000001 << 9
+1000000000.000001 << 10
+1000000000.000001 << 11
+1000000000.000001 << 12
+1000000000.000001 << 13
+1000000000.000001 << 14
+1000000000.000001 << 15
+1000000000.000001 << 16
+1000000000.000001 << 17
+1000000000.000001 << 18
+1000000000.000001 << 19
+1000000000.0000001 << 0
+1000000000.0000001 << 1
+1000000000.0000001 << 2
+1000000000.0000001 << 3
+1000000000.0000001 << 4
+1000000000.0000001 << 5
+1000000000.0000001 << 6
+1000000000.0000001 << 7
+1000000000.0000001 << 8
+1000000000.0000001 << 9
+1000000000.0000001 << 10
+1000000000.0000001 << 11
+1000000000.0000001 << 12
+1000000000.0000001 << 13
+1000000000.0000001 << 14
+1000000000.0000001 << 15
+1000000000.0000001 << 16
+1000000000.0000001 << 17
+1000000000.0000001 << 18
+1000000000.0000001 << 19
+1000000000.00000001 << 0
+1000000000.00000001 << 1
+1000000000.00000001 << 2
+1000000000.00000001 << 3
+1000000000.00000001 << 4
+1000000000.00000001 << 5
+1000000000.00000001 << 6
+1000000000.00000001 << 7
+1000000000.00000001 << 8
+1000000000.00000001 << 9
+1000000000.00000001 << 10
+1000000000.00000001 << 11
+1000000000.00000001 << 12
+1000000000.00000001 << 13
+1000000000.00000001 << 14
+1000000000.00000001 << 15
+1000000000.00000001 << 16
+1000000000.00000001 << 17
+1000000000.00000001 << 18
+1000000000.00000001 << 19
+1000000000.000000001 << 0
+1000000000.000000001 << 1
+1000000000.000000001 << 2
+1000000000.000000001 << 3
+1000000000.000000001 << 4
+1000000000.000000001 << 5
+1000000000.000000001 << 6
+1000000000.000000001 << 7
+1000000000.000000001 << 8
+1000000000.000000001 << 9
+1000000000.000000001 << 10
+1000000000.000000001 << 11
+1000000000.000000001 << 12
+1000000000.000000001 << 13
+1000000000.000000001 << 14
+1000000000.000000001 << 15
+1000000000.000000001 << 16
+1000000000.000000001 << 17
+1000000000.000000001 << 18
+1000000000.000000001 << 19
+1000000000.0000000001 << 0
+1000000000.0000000001 << 1
+1000000000.0000000001 << 2
+1000000000.0000000001 << 3
+1000000000.0000000001 << 4
+1000000000.0000000001 << 5
+1000000000.0000000001 << 6
+1000000000.0000000001 << 7
+1000000000.0000000001 << 8
+1000000000.0000000001 << 9
+1000000000.0000000001 << 10
+1000000000.0000000001 << 11
+1000000000.0000000001 << 12
+1000000000.0000000001 << 13
+1000000000.0000000001 << 14
+1000000000.0000000001 << 15
+1000000000.0000000001 << 16
+1000000000.0000000001 << 17
+1000000000.0000000001 << 18
+1000000000.0000000001 << 19
+10000000000 << 0
+10000000000 << 1
+10000000000 << 2
+10000000000 << 3
+10000000000 << 4
+10000000000 << 5
+10000000000 << 6
+10000000000 << 7
+10000000000 << 8
+10000000000 << 9
+10000000000 << 10
+10000000000 << 11
+10000000000 << 12
+10000000000 << 13
+10000000000 << 14
+10000000000 << 15
+10000000000 << 16
+10000000000 << 17
+10000000000 << 18
+10000000000 << 19
+10000000000.1 << 0
+10000000000.1 << 1
+10000000000.1 << 2
+10000000000.1 << 3
+10000000000.1 << 4
+10000000000.1 << 5
+10000000000.1 << 6
+10000000000.1 << 7
+10000000000.1 << 8
+10000000000.1 << 9
+10000000000.1 << 10
+10000000000.1 << 11
+10000000000.1 << 12
+10000000000.1 << 13
+10000000000.1 << 14
+10000000000.1 << 15
+10000000000.1 << 16
+10000000000.1 << 17
+10000000000.1 << 18
+10000000000.1 << 19
+10000000000.01 << 0
+10000000000.01 << 1
+10000000000.01 << 2
+10000000000.01 << 3
+10000000000.01 << 4
+10000000000.01 << 5
+10000000000.01 << 6
+10000000000.01 << 7
+10000000000.01 << 8
+10000000000.01 << 9
+10000000000.01 << 10
+10000000000.01 << 11
+10000000000.01 << 12
+10000000000.01 << 13
+10000000000.01 << 14
+10000000000.01 << 15
+10000000000.01 << 16
+10000000000.01 << 17
+10000000000.01 << 18
+10000000000.01 << 19
+10000000000.001 << 0
+10000000000.001 << 1
+10000000000.001 << 2
+10000000000.001 << 3
+10000000000.001 << 4
+10000000000.001 << 5
+10000000000.001 << 6
+10000000000.001 << 7
+10000000000.001 << 8
+10000000000.001 << 9
+10000000000.001 << 10
+10000000000.001 << 11
+10000000000.001 << 12
+10000000000.001 << 13
+10000000000.001 << 14
+10000000000.001 << 15
+10000000000.001 << 16
+10000000000.001 << 17
+10000000000.001 << 18
+10000000000.001 << 19
+10000000000.0001 << 0
+10000000000.0001 << 1
+10000000000.0001 << 2
+10000000000.0001 << 3
+10000000000.0001 << 4
+10000000000.0001 << 5
+10000000000.0001 << 6
+10000000000.0001 << 7
+10000000000.0001 << 8
+10000000000.0001 << 9
+10000000000.0001 << 10
+10000000000.0001 << 11
+10000000000.0001 << 12
+10000000000.0001 << 13
+10000000000.0001 << 14
+10000000000.0001 << 15
+10000000000.0001 << 16
+10000000000.0001 << 17
+10000000000.0001 << 18
+10000000000.0001 << 19
+10000000000.00001 << 0
+10000000000.00001 << 1
+10000000000.00001 << 2
+10000000000.00001 << 3
+10000000000.00001 << 4
+10000000000.00001 << 5
+10000000000.00001 << 6
+10000000000.00001 << 7
+10000000000.00001 << 8
+10000000000.00001 << 9
+10000000000.00001 << 10
+10000000000.00001 << 11
+10000000000.00001 << 12
+10000000000.00001 << 13
+10000000000.00001 << 14
+10000000000.00001 << 15
+10000000000.00001 << 16
+10000000000.00001 << 17
+10000000000.00001 << 18
+10000000000.00001 << 19
+10000000000.000001 << 0
+10000000000.000001 << 1
+10000000000.000001 << 2
+10000000000.000001 << 3
+10000000000.000001 << 4
+10000000000.000001 << 5
+10000000000.000001 << 6
+10000000000.000001 << 7
+10000000000.000001 << 8
+10000000000.000001 << 9
+10000000000.000001 << 10
+10000000000.000001 << 11
+10000000000.000001 << 12
+10000000000.000001 << 13
+10000000000.000001 << 14
+10000000000.000001 << 15
+10000000000.000001 << 16
+10000000000.000001 << 17
+10000000000.000001 << 18
+10000000000.000001 << 19
+10000000000.0000001 << 0
+10000000000.0000001 << 1
+10000000000.0000001 << 2
+10000000000.0000001 << 3
+10000000000.0000001 << 4
+10000000000.0000001 << 5
+10000000000.0000001 << 6
+10000000000.0000001 << 7
+10000000000.0000001 << 8
+10000000000.0000001 << 9
+10000000000.0000001 << 10
+10000000000.0000001 << 11
+10000000000.0000001 << 12
+10000000000.0000001 << 13
+10000000000.0000001 << 14
+10000000000.0000001 << 15
+10000000000.0000001 << 16
+10000000000.0000001 << 17
+10000000000.0000001 << 18
+10000000000.0000001 << 19
+10000000000.00000001 << 0
+10000000000.00000001 << 1
+10000000000.00000001 << 2
+10000000000.00000001 << 3
+10000000000.00000001 << 4
+10000000000.00000001 << 5
+10000000000.00000001 << 6
+10000000000.00000001 << 7
+10000000000.00000001 << 8
+10000000000.00000001 << 9
+10000000000.00000001 << 10
+10000000000.00000001 << 11
+10000000000.00000001 << 12
+10000000000.00000001 << 13
+10000000000.00000001 << 14
+10000000000.00000001 << 15
+10000000000.00000001 << 16
+10000000000.00000001 << 17
+10000000000.00000001 << 18
+10000000000.00000001 << 19
+10000000000.000000001 << 0
+10000000000.000000001 << 1
+10000000000.000000001 << 2
+10000000000.000000001 << 3
+10000000000.000000001 << 4
+10000000000.000000001 << 5
+10000000000.000000001 << 6
+10000000000.000000001 << 7
+10000000000.000000001 << 8
+10000000000.000000001 << 9
+10000000000.000000001 << 10
+10000000000.000000001 << 11
+10000000000.000000001 << 12
+10000000000.000000001 << 13
+10000000000.000000001 << 14
+10000000000.000000001 << 15
+10000000000.000000001 << 16
+10000000000.000000001 << 17
+10000000000.000000001 << 18
+10000000000.000000001 << 19
+10000000000.0000000001 << 0
+10000000000.0000000001 << 1
+10000000000.0000000001 << 2
+10000000000.0000000001 << 3
+10000000000.0000000001 << 4
+10000000000.0000000001 << 5
+10000000000.0000000001 << 6
+10000000000.0000000001 << 7
+10000000000.0000000001 << 8
+10000000000.0000000001 << 9
+10000000000.0000000001 << 10
+10000000000.0000000001 << 11
+10000000000.0000000001 << 12
+10000000000.0000000001 << 13
+10000000000.0000000001 << 14
+10000000000.0000000001 << 15
+10000000000.0000000001 << 16
+10000000000.0000000001 << 17
+10000000000.0000000001 << 18
+10000000000.0000000001 << 19
+0 >> 0
+0 >> 1
+0 >> 2
+0 >> 3
+0 >> 4
+0 >> 5
+0 >> 6
+0 >> 7
+0 >> 8
+0 >> 9
+0 >> 10
+0 >> 11
+0 >> 12
+0 >> 13
+0 >> 14
+0 >> 15
+0 >> 16
+0 >> 17
+0 >> 18
+0 >> 19
+0.1 >> 0
+0.1 >> 1
+0.1 >> 2
+0.1 >> 3
+0.1 >> 4
+0.1 >> 5
+0.1 >> 6
+0.1 >> 7
+0.1 >> 8
+0.1 >> 9
+0.1 >> 10
+0.1 >> 11
+0.1 >> 12
+0.1 >> 13
+0.1 >> 14
+0.1 >> 15
+0.1 >> 16
+0.1 >> 17
+0.1 >> 18
+0.1 >> 19
+0.01 >> 0
+0.01 >> 1
+0.01 >> 2
+0.01 >> 3
+0.01 >> 4
+0.01 >> 5
+0.01 >> 6
+0.01 >> 7
+0.01 >> 8
+0.01 >> 9
+0.01 >> 10
+0.01 >> 11
+0.01 >> 12
+0.01 >> 13
+0.01 >> 14
+0.01 >> 15
+0.01 >> 16
+0.01 >> 17
+0.01 >> 18
+0.01 >> 19
+0.001 >> 0
+0.001 >> 1
+0.001 >> 2
+0.001 >> 3
+0.001 >> 4
+0.001 >> 5
+0.001 >> 6
+0.001 >> 7
+0.001 >> 8
+0.001 >> 9
+0.001 >> 10
+0.001 >> 11
+0.001 >> 12
+0.001 >> 13
+0.001 >> 14
+0.001 >> 15
+0.001 >> 16
+0.001 >> 17
+0.001 >> 18
+0.001 >> 19
+0.0001 >> 0
+0.0001 >> 1
+0.0001 >> 2
+0.0001 >> 3
+0.0001 >> 4
+0.0001 >> 5
+0.0001 >> 6
+0.0001 >> 7
+0.0001 >> 8
+0.0001 >> 9
+0.0001 >> 10
+0.0001 >> 11
+0.0001 >> 12
+0.0001 >> 13
+0.0001 >> 14
+0.0001 >> 15
+0.0001 >> 16
+0.0001 >> 17
+0.0001 >> 18
+0.0001 >> 19
+0.00001 >> 0
+0.00001 >> 1
+0.00001 >> 2
+0.00001 >> 3
+0.00001 >> 4
+0.00001 >> 5
+0.00001 >> 6
+0.00001 >> 7
+0.00001 >> 8
+0.00001 >> 9
+0.00001 >> 10
+0.00001 >> 11
+0.00001 >> 12
+0.00001 >> 13
+0.00001 >> 14
+0.00001 >> 15
+0.00001 >> 16
+0.00001 >> 17
+0.00001 >> 18
+0.00001 >> 19
+0.000001 >> 0
+0.000001 >> 1
+0.000001 >> 2
+0.000001 >> 3
+0.000001 >> 4
+0.000001 >> 5
+0.000001 >> 6
+0.000001 >> 7
+0.000001 >> 8
+0.000001 >> 9
+0.000001 >> 10
+0.000001 >> 11
+0.000001 >> 12
+0.000001 >> 13
+0.000001 >> 14
+0.000001 >> 15
+0.000001 >> 16
+0.000001 >> 17
+0.000001 >> 18
+0.000001 >> 19
+0.0000001 >> 0
+0.0000001 >> 1
+0.0000001 >> 2
+0.0000001 >> 3
+0.0000001 >> 4
+0.0000001 >> 5
+0.0000001 >> 6
+0.0000001 >> 7
+0.0000001 >> 8
+0.0000001 >> 9
+0.0000001 >> 10
+0.0000001 >> 11
+0.0000001 >> 12
+0.0000001 >> 13
+0.0000001 >> 14
+0.0000001 >> 15
+0.0000001 >> 16
+0.0000001 >> 17
+0.0000001 >> 18
+0.0000001 >> 19
+0.00000001 >> 0
+0.00000001 >> 1
+0.00000001 >> 2
+0.00000001 >> 3
+0.00000001 >> 4
+0.00000001 >> 5
+0.00000001 >> 6
+0.00000001 >> 7
+0.00000001 >> 8
+0.00000001 >> 9
+0.00000001 >> 10
+0.00000001 >> 11
+0.00000001 >> 12
+0.00000001 >> 13
+0.00000001 >> 14
+0.00000001 >> 15
+0.00000001 >> 16
+0.00000001 >> 17
+0.00000001 >> 18
+0.00000001 >> 19
+0.000000001 >> 0
+0.000000001 >> 1
+0.000000001 >> 2
+0.000000001 >> 3
+0.000000001 >> 4
+0.000000001 >> 5
+0.000000001 >> 6
+0.000000001 >> 7
+0.000000001 >> 8
+0.000000001 >> 9
+0.000000001 >> 10
+0.000000001 >> 11
+0.000000001 >> 12
+0.000000001 >> 13
+0.000000001 >> 14
+0.000000001 >> 15
+0.000000001 >> 16
+0.000000001 >> 17
+0.000000001 >> 18
+0.000000001 >> 19
+0.0000000001 >> 0
+0.0000000001 >> 1
+0.0000000001 >> 2
+0.0000000001 >> 3
+0.0000000001 >> 4
+0.0000000001 >> 5
+0.0000000001 >> 6
+0.0000000001 >> 7
+0.0000000001 >> 8
+0.0000000001 >> 9
+0.0000000001 >> 10
+0.0000000001 >> 11
+0.0000000001 >> 12
+0.0000000001 >> 13
+0.0000000001 >> 14
+0.0000000001 >> 15
+0.0000000001 >> 16
+0.0000000001 >> 17
+0.0000000001 >> 18
+0.0000000001 >> 19
+1 >> 0
+1 >> 1
+1 >> 2
+1 >> 3
+1 >> 4
+1 >> 5
+1 >> 6
+1 >> 7
+1 >> 8
+1 >> 9
+1 >> 10
+1 >> 11
+1 >> 12
+1 >> 13
+1 >> 14
+1 >> 15
+1 >> 16
+1 >> 17
+1 >> 18
+1 >> 19
+1.1 >> 0
+1.1 >> 1
+1.1 >> 2
+1.1 >> 3
+1.1 >> 4
+1.1 >> 5
+1.1 >> 6
+1.1 >> 7
+1.1 >> 8
+1.1 >> 9
+1.1 >> 10
+1.1 >> 11
+1.1 >> 12
+1.1 >> 13
+1.1 >> 14
+1.1 >> 15
+1.1 >> 16
+1.1 >> 17
+1.1 >> 18
+1.1 >> 19
+1.01 >> 0
+1.01 >> 1
+1.01 >> 2
+1.01 >> 3
+1.01 >> 4
+1.01 >> 5
+1.01 >> 6
+1.01 >> 7
+1.01 >> 8
+1.01 >> 9
+1.01 >> 10
+1.01 >> 11
+1.01 >> 12
+1.01 >> 13
+1.01 >> 14
+1.01 >> 15
+1.01 >> 16
+1.01 >> 17
+1.01 >> 18
+1.01 >> 19
+1.001 >> 0
+1.001 >> 1
+1.001 >> 2
+1.001 >> 3
+1.001 >> 4
+1.001 >> 5
+1.001 >> 6
+1.001 >> 7
+1.001 >> 8
+1.001 >> 9
+1.001 >> 10
+1.001 >> 11
+1.001 >> 12
+1.001 >> 13
+1.001 >> 14
+1.001 >> 15
+1.001 >> 16
+1.001 >> 17
+1.001 >> 18
+1.001 >> 19
+1.0001 >> 0
+1.0001 >> 1
+1.0001 >> 2
+1.0001 >> 3
+1.0001 >> 4
+1.0001 >> 5
+1.0001 >> 6
+1.0001 >> 7
+1.0001 >> 8
+1.0001 >> 9
+1.0001 >> 10
+1.0001 >> 11
+1.0001 >> 12
+1.0001 >> 13
+1.0001 >> 14
+1.0001 >> 15
+1.0001 >> 16
+1.0001 >> 17
+1.0001 >> 18
+1.0001 >> 19
+1.00001 >> 0
+1.00001 >> 1
+1.00001 >> 2
+1.00001 >> 3
+1.00001 >> 4
+1.00001 >> 5
+1.00001 >> 6
+1.00001 >> 7
+1.00001 >> 8
+1.00001 >> 9
+1.00001 >> 10
+1.00001 >> 11
+1.00001 >> 12
+1.00001 >> 13
+1.00001 >> 14
+1.00001 >> 15
+1.00001 >> 16
+1.00001 >> 17
+1.00001 >> 18
+1.00001 >> 19
+1.000001 >> 0
+1.000001 >> 1
+1.000001 >> 2
+1.000001 >> 3
+1.000001 >> 4
+1.000001 >> 5
+1.000001 >> 6
+1.000001 >> 7
+1.000001 >> 8
+1.000001 >> 9
+1.000001 >> 10
+1.000001 >> 11
+1.000001 >> 12
+1.000001 >> 13
+1.000001 >> 14
+1.000001 >> 15
+1.000001 >> 16
+1.000001 >> 17
+1.000001 >> 18
+1.000001 >> 19
+1.0000001 >> 0
+1.0000001 >> 1
+1.0000001 >> 2
+1.0000001 >> 3
+1.0000001 >> 4
+1.0000001 >> 5
+1.0000001 >> 6
+1.0000001 >> 7
+1.0000001 >> 8
+1.0000001 >> 9
+1.0000001 >> 10
+1.0000001 >> 11
+1.0000001 >> 12
+1.0000001 >> 13
+1.0000001 >> 14
+1.0000001 >> 15
+1.0000001 >> 16
+1.0000001 >> 17
+1.0000001 >> 18
+1.0000001 >> 19
+1.00000001 >> 0
+1.00000001 >> 1
+1.00000001 >> 2
+1.00000001 >> 3
+1.00000001 >> 4
+1.00000001 >> 5
+1.00000001 >> 6
+1.00000001 >> 7
+1.00000001 >> 8
+1.00000001 >> 9
+1.00000001 >> 10
+1.00000001 >> 11
+1.00000001 >> 12
+1.00000001 >> 13
+1.00000001 >> 14
+1.00000001 >> 15
+1.00000001 >> 16
+1.00000001 >> 17
+1.00000001 >> 18
+1.00000001 >> 19
+1.000000001 >> 0
+1.000000001 >> 1
+1.000000001 >> 2
+1.000000001 >> 3
+1.000000001 >> 4
+1.000000001 >> 5
+1.000000001 >> 6
+1.000000001 >> 7
+1.000000001 >> 8
+1.000000001 >> 9
+1.000000001 >> 10
+1.000000001 >> 11
+1.000000001 >> 12
+1.000000001 >> 13
+1.000000001 >> 14
+1.000000001 >> 15
+1.000000001 >> 16
+1.000000001 >> 17
+1.000000001 >> 18
+1.000000001 >> 19
+1.0000000001 >> 0
+1.0000000001 >> 1
+1.0000000001 >> 2
+1.0000000001 >> 3
+1.0000000001 >> 4
+1.0000000001 >> 5
+1.0000000001 >> 6
+1.0000000001 >> 7
+1.0000000001 >> 8
+1.0000000001 >> 9
+1.0000000001 >> 10
+1.0000000001 >> 11
+1.0000000001 >> 12
+1.0000000001 >> 13
+1.0000000001 >> 14
+1.0000000001 >> 15
+1.0000000001 >> 16
+1.0000000001 >> 17
+1.0000000001 >> 18
+1.0000000001 >> 19
+10 >> 0
+10 >> 1
+10 >> 2
+10 >> 3
+10 >> 4
+10 >> 5
+10 >> 6
+10 >> 7
+10 >> 8
+10 >> 9
+10 >> 10
+10 >> 11
+10 >> 12
+10 >> 13
+10 >> 14
+10 >> 15
+10 >> 16
+10 >> 17
+10 >> 18
+10 >> 19
+10.1 >> 0
+10.1 >> 1
+10.1 >> 2
+10.1 >> 3
+10.1 >> 4
+10.1 >> 5
+10.1 >> 6
+10.1 >> 7
+10.1 >> 8
+10.1 >> 9
+10.1 >> 10
+10.1 >> 11
+10.1 >> 12
+10.1 >> 13
+10.1 >> 14
+10.1 >> 15
+10.1 >> 16
+10.1 >> 17
+10.1 >> 18
+10.1 >> 19
+10.01 >> 0
+10.01 >> 1
+10.01 >> 2
+10.01 >> 3
+10.01 >> 4
+10.01 >> 5
+10.01 >> 6
+10.01 >> 7
+10.01 >> 8
+10.01 >> 9
+10.01 >> 10
+10.01 >> 11
+10.01 >> 12
+10.01 >> 13
+10.01 >> 14
+10.01 >> 15
+10.01 >> 16
+10.01 >> 17
+10.01 >> 18
+10.01 >> 19
+10.001 >> 0
+10.001 >> 1
+10.001 >> 2
+10.001 >> 3
+10.001 >> 4
+10.001 >> 5
+10.001 >> 6
+10.001 >> 7
+10.001 >> 8
+10.001 >> 9
+10.001 >> 10
+10.001 >> 11
+10.001 >> 12
+10.001 >> 13
+10.001 >> 14
+10.001 >> 15
+10.001 >> 16
+10.001 >> 17
+10.001 >> 18
+10.001 >> 19
+10.0001 >> 0
+10.0001 >> 1
+10.0001 >> 2
+10.0001 >> 3
+10.0001 >> 4
+10.0001 >> 5
+10.0001 >> 6
+10.0001 >> 7
+10.0001 >> 8
+10.0001 >> 9
+10.0001 >> 10
+10.0001 >> 11
+10.0001 >> 12
+10.0001 >> 13
+10.0001 >> 14
+10.0001 >> 15
+10.0001 >> 16
+10.0001 >> 17
+10.0001 >> 18
+10.0001 >> 19
+10.00001 >> 0
+10.00001 >> 1
+10.00001 >> 2
+10.00001 >> 3
+10.00001 >> 4
+10.00001 >> 5
+10.00001 >> 6
+10.00001 >> 7
+10.00001 >> 8
+10.00001 >> 9
+10.00001 >> 10
+10.00001 >> 11
+10.00001 >> 12
+10.00001 >> 13
+10.00001 >> 14
+10.00001 >> 15
+10.00001 >> 16
+10.00001 >> 17
+10.00001 >> 18
+10.00001 >> 19
+10.000001 >> 0
+10.000001 >> 1
+10.000001 >> 2
+10.000001 >> 3
+10.000001 >> 4
+10.000001 >> 5
+10.000001 >> 6
+10.000001 >> 7
+10.000001 >> 8
+10.000001 >> 9
+10.000001 >> 10
+10.000001 >> 11
+10.000001 >> 12
+10.000001 >> 13
+10.000001 >> 14
+10.000001 >> 15
+10.000001 >> 16
+10.000001 >> 17
+10.000001 >> 18
+10.000001 >> 19
+10.0000001 >> 0
+10.0000001 >> 1
+10.0000001 >> 2
+10.0000001 >> 3
+10.0000001 >> 4
+10.0000001 >> 5
+10.0000001 >> 6
+10.0000001 >> 7
+10.0000001 >> 8
+10.0000001 >> 9
+10.0000001 >> 10
+10.0000001 >> 11
+10.0000001 >> 12
+10.0000001 >> 13
+10.0000001 >> 14
+10.0000001 >> 15
+10.0000001 >> 16
+10.0000001 >> 17
+10.0000001 >> 18
+10.0000001 >> 19
+10.00000001 >> 0
+10.00000001 >> 1
+10.00000001 >> 2
+10.00000001 >> 3
+10.00000001 >> 4
+10.00000001 >> 5
+10.00000001 >> 6
+10.00000001 >> 7
+10.00000001 >> 8
+10.00000001 >> 9
+10.00000001 >> 10
+10.00000001 >> 11
+10.00000001 >> 12
+10.00000001 >> 13
+10.00000001 >> 14
+10.00000001 >> 15
+10.00000001 >> 16
+10.00000001 >> 17
+10.00000001 >> 18
+10.00000001 >> 19
+10.000000001 >> 0
+10.000000001 >> 1
+10.000000001 >> 2
+10.000000001 >> 3
+10.000000001 >> 4
+10.000000001 >> 5
+10.000000001 >> 6
+10.000000001 >> 7
+10.000000001 >> 8
+10.000000001 >> 9
+10.000000001 >> 10
+10.000000001 >> 11
+10.000000001 >> 12
+10.000000001 >> 13
+10.000000001 >> 14
+10.000000001 >> 15
+10.000000001 >> 16
+10.000000001 >> 17
+10.000000001 >> 18
+10.000000001 >> 19
+10.0000000001 >> 0
+10.0000000001 >> 1
+10.0000000001 >> 2
+10.0000000001 >> 3
+10.0000000001 >> 4
+10.0000000001 >> 5
+10.0000000001 >> 6
+10.0000000001 >> 7
+10.0000000001 >> 8
+10.0000000001 >> 9
+10.0000000001 >> 10
+10.0000000001 >> 11
+10.0000000001 >> 12
+10.0000000001 >> 13
+10.0000000001 >> 14
+10.0000000001 >> 15
+10.0000000001 >> 16
+10.0000000001 >> 17
+10.0000000001 >> 18
+10.0000000001 >> 19
+100 >> 0
+100 >> 1
+100 >> 2
+100 >> 3
+100 >> 4
+100 >> 5
+100 >> 6
+100 >> 7
+100 >> 8
+100 >> 9
+100 >> 10
+100 >> 11
+100 >> 12
+100 >> 13
+100 >> 14
+100 >> 15
+100 >> 16
+100 >> 17
+100 >> 18
+100 >> 19
+100.1 >> 0
+100.1 >> 1
+100.1 >> 2
+100.1 >> 3
+100.1 >> 4
+100.1 >> 5
+100.1 >> 6
+100.1 >> 7
+100.1 >> 8
+100.1 >> 9
+100.1 >> 10
+100.1 >> 11
+100.1 >> 12
+100.1 >> 13
+100.1 >> 14
+100.1 >> 15
+100.1 >> 16
+100.1 >> 17
+100.1 >> 18
+100.1 >> 19
+100.01 >> 0
+100.01 >> 1
+100.01 >> 2
+100.01 >> 3
+100.01 >> 4
+100.01 >> 5
+100.01 >> 6
+100.01 >> 7
+100.01 >> 8
+100.01 >> 9
+100.01 >> 10
+100.01 >> 11
+100.01 >> 12
+100.01 >> 13
+100.01 >> 14
+100.01 >> 15
+100.01 >> 16
+100.01 >> 17
+100.01 >> 18
+100.01 >> 19
+100.001 >> 0
+100.001 >> 1
+100.001 >> 2
+100.001 >> 3
+100.001 >> 4
+100.001 >> 5
+100.001 >> 6
+100.001 >> 7
+100.001 >> 8
+100.001 >> 9
+100.001 >> 10
+100.001 >> 11
+100.001 >> 12
+100.001 >> 13
+100.001 >> 14
+100.001 >> 15
+100.001 >> 16
+100.001 >> 17
+100.001 >> 18
+100.001 >> 19
+100.0001 >> 0
+100.0001 >> 1
+100.0001 >> 2
+100.0001 >> 3
+100.0001 >> 4
+100.0001 >> 5
+100.0001 >> 6
+100.0001 >> 7
+100.0001 >> 8
+100.0001 >> 9
+100.0001 >> 10
+100.0001 >> 11
+100.0001 >> 12
+100.0001 >> 13
+100.0001 >> 14
+100.0001 >> 15
+100.0001 >> 16
+100.0001 >> 17
+100.0001 >> 18
+100.0001 >> 19
+100.00001 >> 0
+100.00001 >> 1
+100.00001 >> 2
+100.00001 >> 3
+100.00001 >> 4
+100.00001 >> 5
+100.00001 >> 6
+100.00001 >> 7
+100.00001 >> 8
+100.00001 >> 9
+100.00001 >> 10
+100.00001 >> 11
+100.00001 >> 12
+100.00001 >> 13
+100.00001 >> 14
+100.00001 >> 15
+100.00001 >> 16
+100.00001 >> 17
+100.00001 >> 18
+100.00001 >> 19
+100.000001 >> 0
+100.000001 >> 1
+100.000001 >> 2
+100.000001 >> 3
+100.000001 >> 4
+100.000001 >> 5
+100.000001 >> 6
+100.000001 >> 7
+100.000001 >> 8
+100.000001 >> 9
+100.000001 >> 10
+100.000001 >> 11
+100.000001 >> 12
+100.000001 >> 13
+100.000001 >> 14
+100.000001 >> 15
+100.000001 >> 16
+100.000001 >> 17
+100.000001 >> 18
+100.000001 >> 19
+100.0000001 >> 0
+100.0000001 >> 1
+100.0000001 >> 2
+100.0000001 >> 3
+100.0000001 >> 4
+100.0000001 >> 5
+100.0000001 >> 6
+100.0000001 >> 7
+100.0000001 >> 8
+100.0000001 >> 9
+100.0000001 >> 10
+100.0000001 >> 11
+100.0000001 >> 12
+100.0000001 >> 13
+100.0000001 >> 14
+100.0000001 >> 15
+100.0000001 >> 16
+100.0000001 >> 17
+100.0000001 >> 18
+100.0000001 >> 19
+100.00000001 >> 0
+100.00000001 >> 1
+100.00000001 >> 2
+100.00000001 >> 3
+100.00000001 >> 4
+100.00000001 >> 5
+100.00000001 >> 6
+100.00000001 >> 7
+100.00000001 >> 8
+100.00000001 >> 9
+100.00000001 >> 10
+100.00000001 >> 11
+100.00000001 >> 12
+100.00000001 >> 13
+100.00000001 >> 14
+100.00000001 >> 15
+100.00000001 >> 16
+100.00000001 >> 17
+100.00000001 >> 18
+100.00000001 >> 19
+100.000000001 >> 0
+100.000000001 >> 1
+100.000000001 >> 2
+100.000000001 >> 3
+100.000000001 >> 4
+100.000000001 >> 5
+100.000000001 >> 6
+100.000000001 >> 7
+100.000000001 >> 8
+100.000000001 >> 9
+100.000000001 >> 10
+100.000000001 >> 11
+100.000000001 >> 12
+100.000000001 >> 13
+100.000000001 >> 14
+100.000000001 >> 15
+100.000000001 >> 16
+100.000000001 >> 17
+100.000000001 >> 18
+100.000000001 >> 19
+100.0000000001 >> 0
+100.0000000001 >> 1
+100.0000000001 >> 2
+100.0000000001 >> 3
+100.0000000001 >> 4
+100.0000000001 >> 5
+100.0000000001 >> 6
+100.0000000001 >> 7
+100.0000000001 >> 8
+100.0000000001 >> 9
+100.0000000001 >> 10
+100.0000000001 >> 11
+100.0000000001 >> 12
+100.0000000001 >> 13
+100.0000000001 >> 14
+100.0000000001 >> 15
+100.0000000001 >> 16
+100.0000000001 >> 17
+100.0000000001 >> 18
+100.0000000001 >> 19
+1000 >> 0
+1000 >> 1
+1000 >> 2
+1000 >> 3
+1000 >> 4
+1000 >> 5
+1000 >> 6
+1000 >> 7
+1000 >> 8
+1000 >> 9
+1000 >> 10
+1000 >> 11
+1000 >> 12
+1000 >> 13
+1000 >> 14
+1000 >> 15
+1000 >> 16
+1000 >> 17
+1000 >> 18
+1000 >> 19
+1000.1 >> 0
+1000.1 >> 1
+1000.1 >> 2
+1000.1 >> 3
+1000.1 >> 4
+1000.1 >> 5
+1000.1 >> 6
+1000.1 >> 7
+1000.1 >> 8
+1000.1 >> 9
+1000.1 >> 10
+1000.1 >> 11
+1000.1 >> 12
+1000.1 >> 13
+1000.1 >> 14
+1000.1 >> 15
+1000.1 >> 16
+1000.1 >> 17
+1000.1 >> 18
+1000.1 >> 19
+1000.01 >> 0
+1000.01 >> 1
+1000.01 >> 2
+1000.01 >> 3
+1000.01 >> 4
+1000.01 >> 5
+1000.01 >> 6
+1000.01 >> 7
+1000.01 >> 8
+1000.01 >> 9
+1000.01 >> 10
+1000.01 >> 11
+1000.01 >> 12
+1000.01 >> 13
+1000.01 >> 14
+1000.01 >> 15
+1000.01 >> 16
+1000.01 >> 17
+1000.01 >> 18
+1000.01 >> 19
+1000.001 >> 0
+1000.001 >> 1
+1000.001 >> 2
+1000.001 >> 3
+1000.001 >> 4
+1000.001 >> 5
+1000.001 >> 6
+1000.001 >> 7
+1000.001 >> 8
+1000.001 >> 9
+1000.001 >> 10
+1000.001 >> 11
+1000.001 >> 12
+1000.001 >> 13
+1000.001 >> 14
+1000.001 >> 15
+1000.001 >> 16
+1000.001 >> 17
+1000.001 >> 18
+1000.001 >> 19
+1000.0001 >> 0
+1000.0001 >> 1
+1000.0001 >> 2
+1000.0001 >> 3
+1000.0001 >> 4
+1000.0001 >> 5
+1000.0001 >> 6
+1000.0001 >> 7
+1000.0001 >> 8
+1000.0001 >> 9
+1000.0001 >> 10
+1000.0001 >> 11
+1000.0001 >> 12
+1000.0001 >> 13
+1000.0001 >> 14
+1000.0001 >> 15
+1000.0001 >> 16
+1000.0001 >> 17
+1000.0001 >> 18
+1000.0001 >> 19
+1000.00001 >> 0
+1000.00001 >> 1
+1000.00001 >> 2
+1000.00001 >> 3
+1000.00001 >> 4
+1000.00001 >> 5
+1000.00001 >> 6
+1000.00001 >> 7
+1000.00001 >> 8
+1000.00001 >> 9
+1000.00001 >> 10
+1000.00001 >> 11
+1000.00001 >> 12
+1000.00001 >> 13
+1000.00001 >> 14
+1000.00001 >> 15
+1000.00001 >> 16
+1000.00001 >> 17
+1000.00001 >> 18
+1000.00001 >> 19
+1000.000001 >> 0
+1000.000001 >> 1
+1000.000001 >> 2
+1000.000001 >> 3
+1000.000001 >> 4
+1000.000001 >> 5
+1000.000001 >> 6
+1000.000001 >> 7
+1000.000001 >> 8
+1000.000001 >> 9
+1000.000001 >> 10
+1000.000001 >> 11
+1000.000001 >> 12
+1000.000001 >> 13
+1000.000001 >> 14
+1000.000001 >> 15
+1000.000001 >> 16
+1000.000001 >> 17
+1000.000001 >> 18
+1000.000001 >> 19
+1000.0000001 >> 0
+1000.0000001 >> 1
+1000.0000001 >> 2
+1000.0000001 >> 3
+1000.0000001 >> 4
+1000.0000001 >> 5
+1000.0000001 >> 6
+1000.0000001 >> 7
+1000.0000001 >> 8
+1000.0000001 >> 9
+1000.0000001 >> 10
+1000.0000001 >> 11
+1000.0000001 >> 12
+1000.0000001 >> 13
+1000.0000001 >> 14
+1000.0000001 >> 15
+1000.0000001 >> 16
+1000.0000001 >> 17
+1000.0000001 >> 18
+1000.0000001 >> 19
+1000.00000001 >> 0
+1000.00000001 >> 1
+1000.00000001 >> 2
+1000.00000001 >> 3
+1000.00000001 >> 4
+1000.00000001 >> 5
+1000.00000001 >> 6
+1000.00000001 >> 7
+1000.00000001 >> 8
+1000.00000001 >> 9
+1000.00000001 >> 10
+1000.00000001 >> 11
+1000.00000001 >> 12
+1000.00000001 >> 13
+1000.00000001 >> 14
+1000.00000001 >> 15
+1000.00000001 >> 16
+1000.00000001 >> 17
+1000.00000001 >> 18
+1000.00000001 >> 19
+1000.000000001 >> 0
+1000.000000001 >> 1
+1000.000000001 >> 2
+1000.000000001 >> 3
+1000.000000001 >> 4
+1000.000000001 >> 5
+1000.000000001 >> 6
+1000.000000001 >> 7
+1000.000000001 >> 8
+1000.000000001 >> 9
+1000.000000001 >> 10
+1000.000000001 >> 11
+1000.000000001 >> 12
+1000.000000001 >> 13
+1000.000000001 >> 14
+1000.000000001 >> 15
+1000.000000001 >> 16
+1000.000000001 >> 17
+1000.000000001 >> 18
+1000.000000001 >> 19
+1000.0000000001 >> 0
+1000.0000000001 >> 1
+1000.0000000001 >> 2
+1000.0000000001 >> 3
+1000.0000000001 >> 4
+1000.0000000001 >> 5
+1000.0000000001 >> 6
+1000.0000000001 >> 7
+1000.0000000001 >> 8
+1000.0000000001 >> 9
+1000.0000000001 >> 10
+1000.0000000001 >> 11
+1000.0000000001 >> 12
+1000.0000000001 >> 13
+1000.0000000001 >> 14
+1000.0000000001 >> 15
+1000.0000000001 >> 16
+1000.0000000001 >> 17
+1000.0000000001 >> 18
+1000.0000000001 >> 19
+10000 >> 0
+10000 >> 1
+10000 >> 2
+10000 >> 3
+10000 >> 4
+10000 >> 5
+10000 >> 6
+10000 >> 7
+10000 >> 8
+10000 >> 9
+10000 >> 10
+10000 >> 11
+10000 >> 12
+10000 >> 13
+10000 >> 14
+10000 >> 15
+10000 >> 16
+10000 >> 17
+10000 >> 18
+10000 >> 19
+10000.1 >> 0
+10000.1 >> 1
+10000.1 >> 2
+10000.1 >> 3
+10000.1 >> 4
+10000.1 >> 5
+10000.1 >> 6
+10000.1 >> 7
+10000.1 >> 8
+10000.1 >> 9
+10000.1 >> 10
+10000.1 >> 11
+10000.1 >> 12
+10000.1 >> 13
+10000.1 >> 14
+10000.1 >> 15
+10000.1 >> 16
+10000.1 >> 17
+10000.1 >> 18
+10000.1 >> 19
+10000.01 >> 0
+10000.01 >> 1
+10000.01 >> 2
+10000.01 >> 3
+10000.01 >> 4
+10000.01 >> 5
+10000.01 >> 6
+10000.01 >> 7
+10000.01 >> 8
+10000.01 >> 9
+10000.01 >> 10
+10000.01 >> 11
+10000.01 >> 12
+10000.01 >> 13
+10000.01 >> 14
+10000.01 >> 15
+10000.01 >> 16
+10000.01 >> 17
+10000.01 >> 18
+10000.01 >> 19
+10000.001 >> 0
+10000.001 >> 1
+10000.001 >> 2
+10000.001 >> 3
+10000.001 >> 4
+10000.001 >> 5
+10000.001 >> 6
+10000.001 >> 7
+10000.001 >> 8
+10000.001 >> 9
+10000.001 >> 10
+10000.001 >> 11
+10000.001 >> 12
+10000.001 >> 13
+10000.001 >> 14
+10000.001 >> 15
+10000.001 >> 16
+10000.001 >> 17
+10000.001 >> 18
+10000.001 >> 19
+10000.0001 >> 0
+10000.0001 >> 1
+10000.0001 >> 2
+10000.0001 >> 3
+10000.0001 >> 4
+10000.0001 >> 5
+10000.0001 >> 6
+10000.0001 >> 7
+10000.0001 >> 8
+10000.0001 >> 9
+10000.0001 >> 10
+10000.0001 >> 11
+10000.0001 >> 12
+10000.0001 >> 13
+10000.0001 >> 14
+10000.0001 >> 15
+10000.0001 >> 16
+10000.0001 >> 17
+10000.0001 >> 18
+10000.0001 >> 19
+10000.00001 >> 0
+10000.00001 >> 1
+10000.00001 >> 2
+10000.00001 >> 3
+10000.00001 >> 4
+10000.00001 >> 5
+10000.00001 >> 6
+10000.00001 >> 7
+10000.00001 >> 8
+10000.00001 >> 9
+10000.00001 >> 10
+10000.00001 >> 11
+10000.00001 >> 12
+10000.00001 >> 13
+10000.00001 >> 14
+10000.00001 >> 15
+10000.00001 >> 16
+10000.00001 >> 17
+10000.00001 >> 18
+10000.00001 >> 19
+10000.000001 >> 0
+10000.000001 >> 1
+10000.000001 >> 2
+10000.000001 >> 3
+10000.000001 >> 4
+10000.000001 >> 5
+10000.000001 >> 6
+10000.000001 >> 7
+10000.000001 >> 8
+10000.000001 >> 9
+10000.000001 >> 10
+10000.000001 >> 11
+10000.000001 >> 12
+10000.000001 >> 13
+10000.000001 >> 14
+10000.000001 >> 15
+10000.000001 >> 16
+10000.000001 >> 17
+10000.000001 >> 18
+10000.000001 >> 19
+10000.0000001 >> 0
+10000.0000001 >> 1
+10000.0000001 >> 2
+10000.0000001 >> 3
+10000.0000001 >> 4
+10000.0000001 >> 5
+10000.0000001 >> 6
+10000.0000001 >> 7
+10000.0000001 >> 8
+10000.0000001 >> 9
+10000.0000001 >> 10
+10000.0000001 >> 11
+10000.0000001 >> 12
+10000.0000001 >> 13
+10000.0000001 >> 14
+10000.0000001 >> 15
+10000.0000001 >> 16
+10000.0000001 >> 17
+10000.0000001 >> 18
+10000.0000001 >> 19
+10000.00000001 >> 0
+10000.00000001 >> 1
+10000.00000001 >> 2
+10000.00000001 >> 3
+10000.00000001 >> 4
+10000.00000001 >> 5
+10000.00000001 >> 6
+10000.00000001 >> 7
+10000.00000001 >> 8
+10000.00000001 >> 9
+10000.00000001 >> 10
+10000.00000001 >> 11
+10000.00000001 >> 12
+10000.00000001 >> 13
+10000.00000001 >> 14
+10000.00000001 >> 15
+10000.00000001 >> 16
+10000.00000001 >> 17
+10000.00000001 >> 18
+10000.00000001 >> 19
+10000.000000001 >> 0
+10000.000000001 >> 1
+10000.000000001 >> 2
+10000.000000001 >> 3
+10000.000000001 >> 4
+10000.000000001 >> 5
+10000.000000001 >> 6
+10000.000000001 >> 7
+10000.000000001 >> 8
+10000.000000001 >> 9
+10000.000000001 >> 10
+10000.000000001 >> 11
+10000.000000001 >> 12
+10000.000000001 >> 13
+10000.000000001 >> 14
+10000.000000001 >> 15
+10000.000000001 >> 16
+10000.000000001 >> 17
+10000.000000001 >> 18
+10000.000000001 >> 19
+10000.0000000001 >> 0
+10000.0000000001 >> 1
+10000.0000000001 >> 2
+10000.0000000001 >> 3
+10000.0000000001 >> 4
+10000.0000000001 >> 5
+10000.0000000001 >> 6
+10000.0000000001 >> 7
+10000.0000000001 >> 8
+10000.0000000001 >> 9
+10000.0000000001 >> 10
+10000.0000000001 >> 11
+10000.0000000001 >> 12
+10000.0000000001 >> 13
+10000.0000000001 >> 14
+10000.0000000001 >> 15
+10000.0000000001 >> 16
+10000.0000000001 >> 17
+10000.0000000001 >> 18
+10000.0000000001 >> 19
+100000 >> 0
+100000 >> 1
+100000 >> 2
+100000 >> 3
+100000 >> 4
+100000 >> 5
+100000 >> 6
+100000 >> 7
+100000 >> 8
+100000 >> 9
+100000 >> 10
+100000 >> 11
+100000 >> 12
+100000 >> 13
+100000 >> 14
+100000 >> 15
+100000 >> 16
+100000 >> 17
+100000 >> 18
+100000 >> 19
+100000.1 >> 0
+100000.1 >> 1
+100000.1 >> 2
+100000.1 >> 3
+100000.1 >> 4
+100000.1 >> 5
+100000.1 >> 6
+100000.1 >> 7
+100000.1 >> 8
+100000.1 >> 9
+100000.1 >> 10
+100000.1 >> 11
+100000.1 >> 12
+100000.1 >> 13
+100000.1 >> 14
+100000.1 >> 15
+100000.1 >> 16
+100000.1 >> 17
+100000.1 >> 18
+100000.1 >> 19
+100000.01 >> 0
+100000.01 >> 1
+100000.01 >> 2
+100000.01 >> 3
+100000.01 >> 4
+100000.01 >> 5
+100000.01 >> 6
+100000.01 >> 7
+100000.01 >> 8
+100000.01 >> 9
+100000.01 >> 10
+100000.01 >> 11
+100000.01 >> 12
+100000.01 >> 13
+100000.01 >> 14
+100000.01 >> 15
+100000.01 >> 16
+100000.01 >> 17
+100000.01 >> 18
+100000.01 >> 19
+100000.001 >> 0
+100000.001 >> 1
+100000.001 >> 2
+100000.001 >> 3
+100000.001 >> 4
+100000.001 >> 5
+100000.001 >> 6
+100000.001 >> 7
+100000.001 >> 8
+100000.001 >> 9
+100000.001 >> 10
+100000.001 >> 11
+100000.001 >> 12
+100000.001 >> 13
+100000.001 >> 14
+100000.001 >> 15
+100000.001 >> 16
+100000.001 >> 17
+100000.001 >> 18
+100000.001 >> 19
+100000.0001 >> 0
+100000.0001 >> 1
+100000.0001 >> 2
+100000.0001 >> 3
+100000.0001 >> 4
+100000.0001 >> 5
+100000.0001 >> 6
+100000.0001 >> 7
+100000.0001 >> 8
+100000.0001 >> 9
+100000.0001 >> 10
+100000.0001 >> 11
+100000.0001 >> 12
+100000.0001 >> 13
+100000.0001 >> 14
+100000.0001 >> 15
+100000.0001 >> 16
+100000.0001 >> 17
+100000.0001 >> 18
+100000.0001 >> 19
+100000.00001 >> 0
+100000.00001 >> 1
+100000.00001 >> 2
+100000.00001 >> 3
+100000.00001 >> 4
+100000.00001 >> 5
+100000.00001 >> 6
+100000.00001 >> 7
+100000.00001 >> 8
+100000.00001 >> 9
+100000.00001 >> 10
+100000.00001 >> 11
+100000.00001 >> 12
+100000.00001 >> 13
+100000.00001 >> 14
+100000.00001 >> 15
+100000.00001 >> 16
+100000.00001 >> 17
+100000.00001 >> 18
+100000.00001 >> 19
+100000.000001 >> 0
+100000.000001 >> 1
+100000.000001 >> 2
+100000.000001 >> 3
+100000.000001 >> 4
+100000.000001 >> 5
+100000.000001 >> 6
+100000.000001 >> 7
+100000.000001 >> 8
+100000.000001 >> 9
+100000.000001 >> 10
+100000.000001 >> 11
+100000.000001 >> 12
+100000.000001 >> 13
+100000.000001 >> 14
+100000.000001 >> 15
+100000.000001 >> 16
+100000.000001 >> 17
+100000.000001 >> 18
+100000.000001 >> 19
+100000.0000001 >> 0
+100000.0000001 >> 1
+100000.0000001 >> 2
+100000.0000001 >> 3
+100000.0000001 >> 4
+100000.0000001 >> 5
+100000.0000001 >> 6
+100000.0000001 >> 7
+100000.0000001 >> 8
+100000.0000001 >> 9
+100000.0000001 >> 10
+100000.0000001 >> 11
+100000.0000001 >> 12
+100000.0000001 >> 13
+100000.0000001 >> 14
+100000.0000001 >> 15
+100000.0000001 >> 16
+100000.0000001 >> 17
+100000.0000001 >> 18
+100000.0000001 >> 19
+100000.00000001 >> 0
+100000.00000001 >> 1
+100000.00000001 >> 2
+100000.00000001 >> 3
+100000.00000001 >> 4
+100000.00000001 >> 5
+100000.00000001 >> 6
+100000.00000001 >> 7
+100000.00000001 >> 8
+100000.00000001 >> 9
+100000.00000001 >> 10
+100000.00000001 >> 11
+100000.00000001 >> 12
+100000.00000001 >> 13
+100000.00000001 >> 14
+100000.00000001 >> 15
+100000.00000001 >> 16
+100000.00000001 >> 17
+100000.00000001 >> 18
+100000.00000001 >> 19
+100000.000000001 >> 0
+100000.000000001 >> 1
+100000.000000001 >> 2
+100000.000000001 >> 3
+100000.000000001 >> 4
+100000.000000001 >> 5
+100000.000000001 >> 6
+100000.000000001 >> 7
+100000.000000001 >> 8
+100000.000000001 >> 9
+100000.000000001 >> 10
+100000.000000001 >> 11
+100000.000000001 >> 12
+100000.000000001 >> 13
+100000.000000001 >> 14
+100000.000000001 >> 15
+100000.000000001 >> 16
+100000.000000001 >> 17
+100000.000000001 >> 18
+100000.000000001 >> 19
+100000.0000000001 >> 0
+100000.0000000001 >> 1
+100000.0000000001 >> 2
+100000.0000000001 >> 3
+100000.0000000001 >> 4
+100000.0000000001 >> 5
+100000.0000000001 >> 6
+100000.0000000001 >> 7
+100000.0000000001 >> 8
+100000.0000000001 >> 9
+100000.0000000001 >> 10
+100000.0000000001 >> 11
+100000.0000000001 >> 12
+100000.0000000001 >> 13
+100000.0000000001 >> 14
+100000.0000000001 >> 15
+100000.0000000001 >> 16
+100000.0000000001 >> 17
+100000.0000000001 >> 18
+100000.0000000001 >> 19
+1000000 >> 0
+1000000 >> 1
+1000000 >> 2
+1000000 >> 3
+1000000 >> 4
+1000000 >> 5
+1000000 >> 6
+1000000 >> 7
+1000000 >> 8
+1000000 >> 9
+1000000 >> 10
+1000000 >> 11
+1000000 >> 12
+1000000 >> 13
+1000000 >> 14
+1000000 >> 15
+1000000 >> 16
+1000000 >> 17
+1000000 >> 18
+1000000 >> 19
+1000000.1 >> 0
+1000000.1 >> 1
+1000000.1 >> 2
+1000000.1 >> 3
+1000000.1 >> 4
+1000000.1 >> 5
+1000000.1 >> 6
+1000000.1 >> 7
+1000000.1 >> 8
+1000000.1 >> 9
+1000000.1 >> 10
+1000000.1 >> 11
+1000000.1 >> 12
+1000000.1 >> 13
+1000000.1 >> 14
+1000000.1 >> 15
+1000000.1 >> 16
+1000000.1 >> 17
+1000000.1 >> 18
+1000000.1 >> 19
+1000000.01 >> 0
+1000000.01 >> 1
+1000000.01 >> 2
+1000000.01 >> 3
+1000000.01 >> 4
+1000000.01 >> 5
+1000000.01 >> 6
+1000000.01 >> 7
+1000000.01 >> 8
+1000000.01 >> 9
+1000000.01 >> 10
+1000000.01 >> 11
+1000000.01 >> 12
+1000000.01 >> 13
+1000000.01 >> 14
+1000000.01 >> 15
+1000000.01 >> 16
+1000000.01 >> 17
+1000000.01 >> 18
+1000000.01 >> 19
+1000000.001 >> 0
+1000000.001 >> 1
+1000000.001 >> 2
+1000000.001 >> 3
+1000000.001 >> 4
+1000000.001 >> 5
+1000000.001 >> 6
+1000000.001 >> 7
+1000000.001 >> 8
+1000000.001 >> 9
+1000000.001 >> 10
+1000000.001 >> 11
+1000000.001 >> 12
+1000000.001 >> 13
+1000000.001 >> 14
+1000000.001 >> 15
+1000000.001 >> 16
+1000000.001 >> 17
+1000000.001 >> 18
+1000000.001 >> 19
+1000000.0001 >> 0
+1000000.0001 >> 1
+1000000.0001 >> 2
+1000000.0001 >> 3
+1000000.0001 >> 4
+1000000.0001 >> 5
+1000000.0001 >> 6
+1000000.0001 >> 7
+1000000.0001 >> 8
+1000000.0001 >> 9
+1000000.0001 >> 10
+1000000.0001 >> 11
+1000000.0001 >> 12
+1000000.0001 >> 13
+1000000.0001 >> 14
+1000000.0001 >> 15
+1000000.0001 >> 16
+1000000.0001 >> 17
+1000000.0001 >> 18
+1000000.0001 >> 19
+1000000.00001 >> 0
+1000000.00001 >> 1
+1000000.00001 >> 2
+1000000.00001 >> 3
+1000000.00001 >> 4
+1000000.00001 >> 5
+1000000.00001 >> 6
+1000000.00001 >> 7
+1000000.00001 >> 8
+1000000.00001 >> 9
+1000000.00001 >> 10
+1000000.00001 >> 11
+1000000.00001 >> 12
+1000000.00001 >> 13
+1000000.00001 >> 14
+1000000.00001 >> 15
+1000000.00001 >> 16
+1000000.00001 >> 17
+1000000.00001 >> 18
+1000000.00001 >> 19
+1000000.000001 >> 0
+1000000.000001 >> 1
+1000000.000001 >> 2
+1000000.000001 >> 3
+1000000.000001 >> 4
+1000000.000001 >> 5
+1000000.000001 >> 6
+1000000.000001 >> 7
+1000000.000001 >> 8
+1000000.000001 >> 9
+1000000.000001 >> 10
+1000000.000001 >> 11
+1000000.000001 >> 12
+1000000.000001 >> 13
+1000000.000001 >> 14
+1000000.000001 >> 15
+1000000.000001 >> 16
+1000000.000001 >> 17
+1000000.000001 >> 18
+1000000.000001 >> 19
+1000000.0000001 >> 0
+1000000.0000001 >> 1
+1000000.0000001 >> 2
+1000000.0000001 >> 3
+1000000.0000001 >> 4
+1000000.0000001 >> 5
+1000000.0000001 >> 6
+1000000.0000001 >> 7
+1000000.0000001 >> 8
+1000000.0000001 >> 9
+1000000.0000001 >> 10
+1000000.0000001 >> 11
+1000000.0000001 >> 12
+1000000.0000001 >> 13
+1000000.0000001 >> 14
+1000000.0000001 >> 15
+1000000.0000001 >> 16
+1000000.0000001 >> 17
+1000000.0000001 >> 18
+1000000.0000001 >> 19
+1000000.00000001 >> 0
+1000000.00000001 >> 1
+1000000.00000001 >> 2
+1000000.00000001 >> 3
+1000000.00000001 >> 4
+1000000.00000001 >> 5
+1000000.00000001 >> 6
+1000000.00000001 >> 7
+1000000.00000001 >> 8
+1000000.00000001 >> 9
+1000000.00000001 >> 10
+1000000.00000001 >> 11
+1000000.00000001 >> 12
+1000000.00000001 >> 13
+1000000.00000001 >> 14
+1000000.00000001 >> 15
+1000000.00000001 >> 16
+1000000.00000001 >> 17
+1000000.00000001 >> 18
+1000000.00000001 >> 19
+1000000.000000001 >> 0
+1000000.000000001 >> 1
+1000000.000000001 >> 2
+1000000.000000001 >> 3
+1000000.000000001 >> 4
+1000000.000000001 >> 5
+1000000.000000001 >> 6
+1000000.000000001 >> 7
+1000000.000000001 >> 8
+1000000.000000001 >> 9
+1000000.000000001 >> 10
+1000000.000000001 >> 11
+1000000.000000001 >> 12
+1000000.000000001 >> 13
+1000000.000000001 >> 14
+1000000.000000001 >> 15
+1000000.000000001 >> 16
+1000000.000000001 >> 17
+1000000.000000001 >> 18
+1000000.000000001 >> 19
+1000000.0000000001 >> 0
+1000000.0000000001 >> 1
+1000000.0000000001 >> 2
+1000000.0000000001 >> 3
+1000000.0000000001 >> 4
+1000000.0000000001 >> 5
+1000000.0000000001 >> 6
+1000000.0000000001 >> 7
+1000000.0000000001 >> 8
+1000000.0000000001 >> 9
+1000000.0000000001 >> 10
+1000000.0000000001 >> 11
+1000000.0000000001 >> 12
+1000000.0000000001 >> 13
+1000000.0000000001 >> 14
+1000000.0000000001 >> 15
+1000000.0000000001 >> 16
+1000000.0000000001 >> 17
+1000000.0000000001 >> 18
+1000000.0000000001 >> 19
+10000000 >> 0
+10000000 >> 1
+10000000 >> 2
+10000000 >> 3
+10000000 >> 4
+10000000 >> 5
+10000000 >> 6
+10000000 >> 7
+10000000 >> 8
+10000000 >> 9
+10000000 >> 10
+10000000 >> 11
+10000000 >> 12
+10000000 >> 13
+10000000 >> 14
+10000000 >> 15
+10000000 >> 16
+10000000 >> 17
+10000000 >> 18
+10000000 >> 19
+10000000.1 >> 0
+10000000.1 >> 1
+10000000.1 >> 2
+10000000.1 >> 3
+10000000.1 >> 4
+10000000.1 >> 5
+10000000.1 >> 6
+10000000.1 >> 7
+10000000.1 >> 8
+10000000.1 >> 9
+10000000.1 >> 10
+10000000.1 >> 11
+10000000.1 >> 12
+10000000.1 >> 13
+10000000.1 >> 14
+10000000.1 >> 15
+10000000.1 >> 16
+10000000.1 >> 17
+10000000.1 >> 18
+10000000.1 >> 19
+10000000.01 >> 0
+10000000.01 >> 1
+10000000.01 >> 2
+10000000.01 >> 3
+10000000.01 >> 4
+10000000.01 >> 5
+10000000.01 >> 6
+10000000.01 >> 7
+10000000.01 >> 8
+10000000.01 >> 9
+10000000.01 >> 10
+10000000.01 >> 11
+10000000.01 >> 12
+10000000.01 >> 13
+10000000.01 >> 14
+10000000.01 >> 15
+10000000.01 >> 16
+10000000.01 >> 17
+10000000.01 >> 18
+10000000.01 >> 19
+10000000.001 >> 0
+10000000.001 >> 1
+10000000.001 >> 2
+10000000.001 >> 3
+10000000.001 >> 4
+10000000.001 >> 5
+10000000.001 >> 6
+10000000.001 >> 7
+10000000.001 >> 8
+10000000.001 >> 9
+10000000.001 >> 10
+10000000.001 >> 11
+10000000.001 >> 12
+10000000.001 >> 13
+10000000.001 >> 14
+10000000.001 >> 15
+10000000.001 >> 16
+10000000.001 >> 17
+10000000.001 >> 18
+10000000.001 >> 19
+10000000.0001 >> 0
+10000000.0001 >> 1
+10000000.0001 >> 2
+10000000.0001 >> 3
+10000000.0001 >> 4
+10000000.0001 >> 5
+10000000.0001 >> 6
+10000000.0001 >> 7
+10000000.0001 >> 8
+10000000.0001 >> 9
+10000000.0001 >> 10
+10000000.0001 >> 11
+10000000.0001 >> 12
+10000000.0001 >> 13
+10000000.0001 >> 14
+10000000.0001 >> 15
+10000000.0001 >> 16
+10000000.0001 >> 17
+10000000.0001 >> 18
+10000000.0001 >> 19
+10000000.00001 >> 0
+10000000.00001 >> 1
+10000000.00001 >> 2
+10000000.00001 >> 3
+10000000.00001 >> 4
+10000000.00001 >> 5
+10000000.00001 >> 6
+10000000.00001 >> 7
+10000000.00001 >> 8
+10000000.00001 >> 9
+10000000.00001 >> 10
+10000000.00001 >> 11
+10000000.00001 >> 12
+10000000.00001 >> 13
+10000000.00001 >> 14
+10000000.00001 >> 15
+10000000.00001 >> 16
+10000000.00001 >> 17
+10000000.00001 >> 18
+10000000.00001 >> 19
+10000000.000001 >> 0
+10000000.000001 >> 1
+10000000.000001 >> 2
+10000000.000001 >> 3
+10000000.000001 >> 4
+10000000.000001 >> 5
+10000000.000001 >> 6
+10000000.000001 >> 7
+10000000.000001 >> 8
+10000000.000001 >> 9
+10000000.000001 >> 10
+10000000.000001 >> 11
+10000000.000001 >> 12
+10000000.000001 >> 13
+10000000.000001 >> 14
+10000000.000001 >> 15
+10000000.000001 >> 16
+10000000.000001 >> 17
+10000000.000001 >> 18
+10000000.000001 >> 19
+10000000.0000001 >> 0
+10000000.0000001 >> 1
+10000000.0000001 >> 2
+10000000.0000001 >> 3
+10000000.0000001 >> 4
+10000000.0000001 >> 5
+10000000.0000001 >> 6
+10000000.0000001 >> 7
+10000000.0000001 >> 8
+10000000.0000001 >> 9
+10000000.0000001 >> 10
+10000000.0000001 >> 11
+10000000.0000001 >> 12
+10000000.0000001 >> 13
+10000000.0000001 >> 14
+10000000.0000001 >> 15
+10000000.0000001 >> 16
+10000000.0000001 >> 17
+10000000.0000001 >> 18
+10000000.0000001 >> 19
+10000000.00000001 >> 0
+10000000.00000001 >> 1
+10000000.00000001 >> 2
+10000000.00000001 >> 3
+10000000.00000001 >> 4
+10000000.00000001 >> 5
+10000000.00000001 >> 6
+10000000.00000001 >> 7
+10000000.00000001 >> 8
+10000000.00000001 >> 9
+10000000.00000001 >> 10
+10000000.00000001 >> 11
+10000000.00000001 >> 12
+10000000.00000001 >> 13
+10000000.00000001 >> 14
+10000000.00000001 >> 15
+10000000.00000001 >> 16
+10000000.00000001 >> 17
+10000000.00000001 >> 18
+10000000.00000001 >> 19
+10000000.000000001 >> 0
+10000000.000000001 >> 1
+10000000.000000001 >> 2
+10000000.000000001 >> 3
+10000000.000000001 >> 4
+10000000.000000001 >> 5
+10000000.000000001 >> 6
+10000000.000000001 >> 7
+10000000.000000001 >> 8
+10000000.000000001 >> 9
+10000000.000000001 >> 10
+10000000.000000001 >> 11
+10000000.000000001 >> 12
+10000000.000000001 >> 13
+10000000.000000001 >> 14
+10000000.000000001 >> 15
+10000000.000000001 >> 16
+10000000.000000001 >> 17
+10000000.000000001 >> 18
+10000000.000000001 >> 19
+10000000.0000000001 >> 0
+10000000.0000000001 >> 1
+10000000.0000000001 >> 2
+10000000.0000000001 >> 3
+10000000.0000000001 >> 4
+10000000.0000000001 >> 5
+10000000.0000000001 >> 6
+10000000.0000000001 >> 7
+10000000.0000000001 >> 8
+10000000.0000000001 >> 9
+10000000.0000000001 >> 10
+10000000.0000000001 >> 11
+10000000.0000000001 >> 12
+10000000.0000000001 >> 13
+10000000.0000000001 >> 14
+10000000.0000000001 >> 15
+10000000.0000000001 >> 16
+10000000.0000000001 >> 17
+10000000.0000000001 >> 18
+10000000.0000000001 >> 19
+100000000 >> 0
+100000000 >> 1
+100000000 >> 2
+100000000 >> 3
+100000000 >> 4
+100000000 >> 5
+100000000 >> 6
+100000000 >> 7
+100000000 >> 8
+100000000 >> 9
+100000000 >> 10
+100000000 >> 11
+100000000 >> 12
+100000000 >> 13
+100000000 >> 14
+100000000 >> 15
+100000000 >> 16
+100000000 >> 17
+100000000 >> 18
+100000000 >> 19
+100000000.1 >> 0
+100000000.1 >> 1
+100000000.1 >> 2
+100000000.1 >> 3
+100000000.1 >> 4
+100000000.1 >> 5
+100000000.1 >> 6
+100000000.1 >> 7
+100000000.1 >> 8
+100000000.1 >> 9
+100000000.1 >> 10
+100000000.1 >> 11
+100000000.1 >> 12
+100000000.1 >> 13
+100000000.1 >> 14
+100000000.1 >> 15
+100000000.1 >> 16
+100000000.1 >> 17
+100000000.1 >> 18
+100000000.1 >> 19
+100000000.01 >> 0
+100000000.01 >> 1
+100000000.01 >> 2
+100000000.01 >> 3
+100000000.01 >> 4
+100000000.01 >> 5
+100000000.01 >> 6
+100000000.01 >> 7
+100000000.01 >> 8
+100000000.01 >> 9
+100000000.01 >> 10
+100000000.01 >> 11
+100000000.01 >> 12
+100000000.01 >> 13
+100000000.01 >> 14
+100000000.01 >> 15
+100000000.01 >> 16
+100000000.01 >> 17
+100000000.01 >> 18
+100000000.01 >> 19
+100000000.001 >> 0
+100000000.001 >> 1
+100000000.001 >> 2
+100000000.001 >> 3
+100000000.001 >> 4
+100000000.001 >> 5
+100000000.001 >> 6
+100000000.001 >> 7
+100000000.001 >> 8
+100000000.001 >> 9
+100000000.001 >> 10
+100000000.001 >> 11
+100000000.001 >> 12
+100000000.001 >> 13
+100000000.001 >> 14
+100000000.001 >> 15
+100000000.001 >> 16
+100000000.001 >> 17
+100000000.001 >> 18
+100000000.001 >> 19
+100000000.0001 >> 0
+100000000.0001 >> 1
+100000000.0001 >> 2
+100000000.0001 >> 3
+100000000.0001 >> 4
+100000000.0001 >> 5
+100000000.0001 >> 6
+100000000.0001 >> 7
+100000000.0001 >> 8
+100000000.0001 >> 9
+100000000.0001 >> 10
+100000000.0001 >> 11
+100000000.0001 >> 12
+100000000.0001 >> 13
+100000000.0001 >> 14
+100000000.0001 >> 15
+100000000.0001 >> 16
+100000000.0001 >> 17
+100000000.0001 >> 18
+100000000.0001 >> 19
+100000000.00001 >> 0
+100000000.00001 >> 1
+100000000.00001 >> 2
+100000000.00001 >> 3
+100000000.00001 >> 4
+100000000.00001 >> 5
+100000000.00001 >> 6
+100000000.00001 >> 7
+100000000.00001 >> 8
+100000000.00001 >> 9
+100000000.00001 >> 10
+100000000.00001 >> 11
+100000000.00001 >> 12
+100000000.00001 >> 13
+100000000.00001 >> 14
+100000000.00001 >> 15
+100000000.00001 >> 16
+100000000.00001 >> 17
+100000000.00001 >> 18
+100000000.00001 >> 19
+100000000.000001 >> 0
+100000000.000001 >> 1
+100000000.000001 >> 2
+100000000.000001 >> 3
+100000000.000001 >> 4
+100000000.000001 >> 5
+100000000.000001 >> 6
+100000000.000001 >> 7
+100000000.000001 >> 8
+100000000.000001 >> 9
+100000000.000001 >> 10
+100000000.000001 >> 11
+100000000.000001 >> 12
+100000000.000001 >> 13
+100000000.000001 >> 14
+100000000.000001 >> 15
+100000000.000001 >> 16
+100000000.000001 >> 17
+100000000.000001 >> 18
+100000000.000001 >> 19
+100000000.0000001 >> 0
+100000000.0000001 >> 1
+100000000.0000001 >> 2
+100000000.0000001 >> 3
+100000000.0000001 >> 4
+100000000.0000001 >> 5
+100000000.0000001 >> 6
+100000000.0000001 >> 7
+100000000.0000001 >> 8
+100000000.0000001 >> 9
+100000000.0000001 >> 10
+100000000.0000001 >> 11
+100000000.0000001 >> 12
+100000000.0000001 >> 13
+100000000.0000001 >> 14
+100000000.0000001 >> 15
+100000000.0000001 >> 16
+100000000.0000001 >> 17
+100000000.0000001 >> 18
+100000000.0000001 >> 19
+100000000.00000001 >> 0
+100000000.00000001 >> 1
+100000000.00000001 >> 2
+100000000.00000001 >> 3
+100000000.00000001 >> 4
+100000000.00000001 >> 5
+100000000.00000001 >> 6
+100000000.00000001 >> 7
+100000000.00000001 >> 8
+100000000.00000001 >> 9
+100000000.00000001 >> 10
+100000000.00000001 >> 11
+100000000.00000001 >> 12
+100000000.00000001 >> 13
+100000000.00000001 >> 14
+100000000.00000001 >> 15
+100000000.00000001 >> 16
+100000000.00000001 >> 17
+100000000.00000001 >> 18
+100000000.00000001 >> 19
+100000000.000000001 >> 0
+100000000.000000001 >> 1
+100000000.000000001 >> 2
+100000000.000000001 >> 3
+100000000.000000001 >> 4
+100000000.000000001 >> 5
+100000000.000000001 >> 6
+100000000.000000001 >> 7
+100000000.000000001 >> 8
+100000000.000000001 >> 9
+100000000.000000001 >> 10
+100000000.000000001 >> 11
+100000000.000000001 >> 12
+100000000.000000001 >> 13
+100000000.000000001 >> 14
+100000000.000000001 >> 15
+100000000.000000001 >> 16
+100000000.000000001 >> 17
+100000000.000000001 >> 18
+100000000.000000001 >> 19
+100000000.0000000001 >> 0
+100000000.0000000001 >> 1
+100000000.0000000001 >> 2
+100000000.0000000001 >> 3
+100000000.0000000001 >> 4
+100000000.0000000001 >> 5
+100000000.0000000001 >> 6
+100000000.0000000001 >> 7
+100000000.0000000001 >> 8
+100000000.0000000001 >> 9
+100000000.0000000001 >> 10
+100000000.0000000001 >> 11
+100000000.0000000001 >> 12
+100000000.0000000001 >> 13
+100000000.0000000001 >> 14
+100000000.0000000001 >> 15
+100000000.0000000001 >> 16
+100000000.0000000001 >> 17
+100000000.0000000001 >> 18
+100000000.0000000001 >> 19
+1000000000 >> 0
+1000000000 >> 1
+1000000000 >> 2
+1000000000 >> 3
+1000000000 >> 4
+1000000000 >> 5
+1000000000 >> 6
+1000000000 >> 7
+1000000000 >> 8
+1000000000 >> 9
+1000000000 >> 10
+1000000000 >> 11
+1000000000 >> 12
+1000000000 >> 13
+1000000000 >> 14
+1000000000 >> 15
+1000000000 >> 16
+1000000000 >> 17
+1000000000 >> 18
+1000000000 >> 19
+1000000000.1 >> 0
+1000000000.1 >> 1
+1000000000.1 >> 2
+1000000000.1 >> 3
+1000000000.1 >> 4
+1000000000.1 >> 5
+1000000000.1 >> 6
+1000000000.1 >> 7
+1000000000.1 >> 8
+1000000000.1 >> 9
+1000000000.1 >> 10
+1000000000.1 >> 11
+1000000000.1 >> 12
+1000000000.1 >> 13
+1000000000.1 >> 14
+1000000000.1 >> 15
+1000000000.1 >> 16
+1000000000.1 >> 17
+1000000000.1 >> 18
+1000000000.1 >> 19
+1000000000.01 >> 0
+1000000000.01 >> 1
+1000000000.01 >> 2
+1000000000.01 >> 3
+1000000000.01 >> 4
+1000000000.01 >> 5
+1000000000.01 >> 6
+1000000000.01 >> 7
+1000000000.01 >> 8
+1000000000.01 >> 9
+1000000000.01 >> 10
+1000000000.01 >> 11
+1000000000.01 >> 12
+1000000000.01 >> 13
+1000000000.01 >> 14
+1000000000.01 >> 15
+1000000000.01 >> 16
+1000000000.01 >> 17
+1000000000.01 >> 18
+1000000000.01 >> 19
+1000000000.001 >> 0
+1000000000.001 >> 1
+1000000000.001 >> 2
+1000000000.001 >> 3
+1000000000.001 >> 4
+1000000000.001 >> 5
+1000000000.001 >> 6
+1000000000.001 >> 7
+1000000000.001 >> 8
+1000000000.001 >> 9
+1000000000.001 >> 10
+1000000000.001 >> 11
+1000000000.001 >> 12
+1000000000.001 >> 13
+1000000000.001 >> 14
+1000000000.001 >> 15
+1000000000.001 >> 16
+1000000000.001 >> 17
+1000000000.001 >> 18
+1000000000.001 >> 19
+1000000000.0001 >> 0
+1000000000.0001 >> 1
+1000000000.0001 >> 2
+1000000000.0001 >> 3
+1000000000.0001 >> 4
+1000000000.0001 >> 5
+1000000000.0001 >> 6
+1000000000.0001 >> 7
+1000000000.0001 >> 8
+1000000000.0001 >> 9
+1000000000.0001 >> 10
+1000000000.0001 >> 11
+1000000000.0001 >> 12
+1000000000.0001 >> 13
+1000000000.0001 >> 14
+1000000000.0001 >> 15
+1000000000.0001 >> 16
+1000000000.0001 >> 17
+1000000000.0001 >> 18
+1000000000.0001 >> 19
+1000000000.00001 >> 0
+1000000000.00001 >> 1
+1000000000.00001 >> 2
+1000000000.00001 >> 3
+1000000000.00001 >> 4
+1000000000.00001 >> 5
+1000000000.00001 >> 6
+1000000000.00001 >> 7
+1000000000.00001 >> 8
+1000000000.00001 >> 9
+1000000000.00001 >> 10
+1000000000.00001 >> 11
+1000000000.00001 >> 12
+1000000000.00001 >> 13
+1000000000.00001 >> 14
+1000000000.00001 >> 15
+1000000000.00001 >> 16
+1000000000.00001 >> 17
+1000000000.00001 >> 18
+1000000000.00001 >> 19
+1000000000.000001 >> 0
+1000000000.000001 >> 1
+1000000000.000001 >> 2
+1000000000.000001 >> 3
+1000000000.000001 >> 4
+1000000000.000001 >> 5
+1000000000.000001 >> 6
+1000000000.000001 >> 7
+1000000000.000001 >> 8
+1000000000.000001 >> 9
+1000000000.000001 >> 10
+1000000000.000001 >> 11
+1000000000.000001 >> 12
+1000000000.000001 >> 13
+1000000000.000001 >> 14
+1000000000.000001 >> 15
+1000000000.000001 >> 16
+1000000000.000001 >> 17
+1000000000.000001 >> 18
+1000000000.000001 >> 19
+1000000000.0000001 >> 0
+1000000000.0000001 >> 1
+1000000000.0000001 >> 2
+1000000000.0000001 >> 3
+1000000000.0000001 >> 4
+1000000000.0000001 >> 5
+1000000000.0000001 >> 6
+1000000000.0000001 >> 7
+1000000000.0000001 >> 8
+1000000000.0000001 >> 9
+1000000000.0000001 >> 10
+1000000000.0000001 >> 11
+1000000000.0000001 >> 12
+1000000000.0000001 >> 13
+1000000000.0000001 >> 14
+1000000000.0000001 >> 15
+1000000000.0000001 >> 16
+1000000000.0000001 >> 17
+1000000000.0000001 >> 18
+1000000000.0000001 >> 19
+1000000000.00000001 >> 0
+1000000000.00000001 >> 1
+1000000000.00000001 >> 2
+1000000000.00000001 >> 3
+1000000000.00000001 >> 4
+1000000000.00000001 >> 5
+1000000000.00000001 >> 6
+1000000000.00000001 >> 7
+1000000000.00000001 >> 8
+1000000000.00000001 >> 9
+1000000000.00000001 >> 10
+1000000000.00000001 >> 11
+1000000000.00000001 >> 12
+1000000000.00000001 >> 13
+1000000000.00000001 >> 14
+1000000000.00000001 >> 15
+1000000000.00000001 >> 16
+1000000000.00000001 >> 17
+1000000000.00000001 >> 18
+1000000000.00000001 >> 19
+1000000000.000000001 >> 0
+1000000000.000000001 >> 1
+1000000000.000000001 >> 2
+1000000000.000000001 >> 3
+1000000000.000000001 >> 4
+1000000000.000000001 >> 5
+1000000000.000000001 >> 6
+1000000000.000000001 >> 7
+1000000000.000000001 >> 8
+1000000000.000000001 >> 9
+1000000000.000000001 >> 10
+1000000000.000000001 >> 11
+1000000000.000000001 >> 12
+1000000000.000000001 >> 13
+1000000000.000000001 >> 14
+1000000000.000000001 >> 15
+1000000000.000000001 >> 16
+1000000000.000000001 >> 17
+1000000000.000000001 >> 18
+1000000000.000000001 >> 19
+1000000000.0000000001 >> 0
+1000000000.0000000001 >> 1
+1000000000.0000000001 >> 2
+1000000000.0000000001 >> 3
+1000000000.0000000001 >> 4
+1000000000.0000000001 >> 5
+1000000000.0000000001 >> 6
+1000000000.0000000001 >> 7
+1000000000.0000000001 >> 8
+1000000000.0000000001 >> 9
+1000000000.0000000001 >> 10
+1000000000.0000000001 >> 11
+1000000000.0000000001 >> 12
+1000000000.0000000001 >> 13
+1000000000.0000000001 >> 14
+1000000000.0000000001 >> 15
+1000000000.0000000001 >> 16
+1000000000.0000000001 >> 17
+1000000000.0000000001 >> 18
+1000000000.0000000001 >> 19
+10000000000 >> 0
+10000000000 >> 1
+10000000000 >> 2
+10000000000 >> 3
+10000000000 >> 4
+10000000000 >> 5
+10000000000 >> 6
+10000000000 >> 7
+10000000000 >> 8
+10000000000 >> 9
+10000000000 >> 10
+10000000000 >> 11
+10000000000 >> 12
+10000000000 >> 13
+10000000000 >> 14
+10000000000 >> 15
+10000000000 >> 16
+10000000000 >> 17
+10000000000 >> 18
+10000000000 >> 19
+10000000000.1 >> 0
+10000000000.1 >> 1
+10000000000.1 >> 2
+10000000000.1 >> 3
+10000000000.1 >> 4
+10000000000.1 >> 5
+10000000000.1 >> 6
+10000000000.1 >> 7
+10000000000.1 >> 8
+10000000000.1 >> 9
+10000000000.1 >> 10
+10000000000.1 >> 11
+10000000000.1 >> 12
+10000000000.1 >> 13
+10000000000.1 >> 14
+10000000000.1 >> 15
+10000000000.1 >> 16
+10000000000.1 >> 17
+10000000000.1 >> 18
+10000000000.1 >> 19
+10000000000.01 >> 0
+10000000000.01 >> 1
+10000000000.01 >> 2
+10000000000.01 >> 3
+10000000000.01 >> 4
+10000000000.01 >> 5
+10000000000.01 >> 6
+10000000000.01 >> 7
+10000000000.01 >> 8
+10000000000.01 >> 9
+10000000000.01 >> 10
+10000000000.01 >> 11
+10000000000.01 >> 12
+10000000000.01 >> 13
+10000000000.01 >> 14
+10000000000.01 >> 15
+10000000000.01 >> 16
+10000000000.01 >> 17
+10000000000.01 >> 18
+10000000000.01 >> 19
+10000000000.001 >> 0
+10000000000.001 >> 1
+10000000000.001 >> 2
+10000000000.001 >> 3
+10000000000.001 >> 4
+10000000000.001 >> 5
+10000000000.001 >> 6
+10000000000.001 >> 7
+10000000000.001 >> 8
+10000000000.001 >> 9
+10000000000.001 >> 10
+10000000000.001 >> 11
+10000000000.001 >> 12
+10000000000.001 >> 13
+10000000000.001 >> 14
+10000000000.001 >> 15
+10000000000.001 >> 16
+10000000000.001 >> 17
+10000000000.001 >> 18
+10000000000.001 >> 19
+10000000000.0001 >> 0
+10000000000.0001 >> 1
+10000000000.0001 >> 2
+10000000000.0001 >> 3
+10000000000.0001 >> 4
+10000000000.0001 >> 5
+10000000000.0001 >> 6
+10000000000.0001 >> 7
+10000000000.0001 >> 8
+10000000000.0001 >> 9
+10000000000.0001 >> 10
+10000000000.0001 >> 11
+10000000000.0001 >> 12
+10000000000.0001 >> 13
+10000000000.0001 >> 14
+10000000000.0001 >> 15
+10000000000.0001 >> 16
+10000000000.0001 >> 17
+10000000000.0001 >> 18
+10000000000.0001 >> 19
+10000000000.00001 >> 0
+10000000000.00001 >> 1
+10000000000.00001 >> 2
+10000000000.00001 >> 3
+10000000000.00001 >> 4
+10000000000.00001 >> 5
+10000000000.00001 >> 6
+10000000000.00001 >> 7
+10000000000.00001 >> 8
+10000000000.00001 >> 9
+10000000000.00001 >> 10
+10000000000.00001 >> 11
+10000000000.00001 >> 12
+10000000000.00001 >> 13
+10000000000.00001 >> 14
+10000000000.00001 >> 15
+10000000000.00001 >> 16
+10000000000.00001 >> 17
+10000000000.00001 >> 18
+10000000000.00001 >> 19
+10000000000.000001 >> 0
+10000000000.000001 >> 1
+10000000000.000001 >> 2
+10000000000.000001 >> 3
+10000000000.000001 >> 4
+10000000000.000001 >> 5
+10000000000.000001 >> 6
+10000000000.000001 >> 7
+10000000000.000001 >> 8
+10000000000.000001 >> 9
+10000000000.000001 >> 10
+10000000000.000001 >> 11
+10000000000.000001 >> 12
+10000000000.000001 >> 13
+10000000000.000001 >> 14
+10000000000.000001 >> 15
+10000000000.000001 >> 16
+10000000000.000001 >> 17
+10000000000.000001 >> 18
+10000000000.000001 >> 19
+10000000000.0000001 >> 0
+10000000000.0000001 >> 1
+10000000000.0000001 >> 2
+10000000000.0000001 >> 3
+10000000000.0000001 >> 4
+10000000000.0000001 >> 5
+10000000000.0000001 >> 6
+10000000000.0000001 >> 7
+10000000000.0000001 >> 8
+10000000000.0000001 >> 9
+10000000000.0000001 >> 10
+10000000000.0000001 >> 11
+10000000000.0000001 >> 12
+10000000000.0000001 >> 13
+10000000000.0000001 >> 14
+10000000000.0000001 >> 15
+10000000000.0000001 >> 16
+10000000000.0000001 >> 17
+10000000000.0000001 >> 18
+10000000000.0000001 >> 19
+10000000000.00000001 >> 0
+10000000000.00000001 >> 1
+10000000000.00000001 >> 2
+10000000000.00000001 >> 3
+10000000000.00000001 >> 4
+10000000000.00000001 >> 5
+10000000000.00000001 >> 6
+10000000000.00000001 >> 7
+10000000000.00000001 >> 8
+10000000000.00000001 >> 9
+10000000000.00000001 >> 10
+10000000000.00000001 >> 11
+10000000000.00000001 >> 12
+10000000000.00000001 >> 13
+10000000000.00000001 >> 14
+10000000000.00000001 >> 15
+10000000000.00000001 >> 16
+10000000000.00000001 >> 17
+10000000000.00000001 >> 18
+10000000000.00000001 >> 19
+10000000000.000000001 >> 0
+10000000000.000000001 >> 1
+10000000000.000000001 >> 2
+10000000000.000000001 >> 3
+10000000000.000000001 >> 4
+10000000000.000000001 >> 5
+10000000000.000000001 >> 6
+10000000000.000000001 >> 7
+10000000000.000000001 >> 8
+10000000000.000000001 >> 9
+10000000000.000000001 >> 10
+10000000000.000000001 >> 11
+10000000000.000000001 >> 12
+10000000000.000000001 >> 13
+10000000000.000000001 >> 14
+10000000000.000000001 >> 15
+10000000000.000000001 >> 16
+10000000000.000000001 >> 17
+10000000000.000000001 >> 18
+10000000000.000000001 >> 19
+10000000000.0000000001 >> 0
+10000000000.0000000001 >> 1
+10000000000.0000000001 >> 2
+10000000000.0000000001 >> 3
+10000000000.0000000001 >> 4
+10000000000.0000000001 >> 5
+10000000000.0000000001 >> 6
+10000000000.0000000001 >> 7
+10000000000.0000000001 >> 8
+10000000000.0000000001 >> 9
+10000000000.0000000001 >> 10
+10000000000.0000000001 >> 11
+10000000000.0000000001 >> 12
+10000000000.0000000001 >> 13
+10000000000.0000000001 >> 14
+10000000000.0000000001 >> 15
+10000000000.0000000001 >> 16
+10000000000.0000000001 >> 17
+10000000000.0000000001 >> 18
+10000000000.0000000001 >> 19
diff --git a/contrib/bc/tests/bc/shift_results.txt b/contrib/bc/tests/bc/shift_results.txt
new file mode 100644
index 000000000000..a567e713c1aa
--- /dev/null
+++ b/contrib/bc/tests/bc/shift_results.txt
@@ -0,0 +1,5325 @@
+0
+1
+2
+.0023896
+1.298346
+2.00000000
+2.3896
+12983.46
+200000.000
+891368923489.76
+1892634051829351283289298000000000000000000000000
+0
+1
+2
+.0023896
+1.298346
+2.00000000
+.0000023896
+.0001298346
+.0000200000000
+.0089136892348976
+1.892634051829351283289298
+-1
+-2
+-.0023896
+-1.298346
+-2.00000000
+-2.3896
+-12983.46
+-200000.000
+-891368923489.76
+-1892634051829351283289298000000000000000000000000
+-1
+-2
+-.0023896
+-1.298346
+-2.00000000
+-.0000023896
+-.0001298346
+-.0000200000000
+-.0089136892348976
+.0089136892348976
+-1.892634051829351283289298
+1.892634051829351283289298
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+.0001
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+.00001
+.0001
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+.000001
+.00001
+.0001
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+.0000001
+.000001
+.00001
+.0001
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+.00000001
+.0000001
+.000001
+.00001
+.0001
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+.000000001
+.00000001
+.0000001
+.000001
+.00001
+.0001
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+.0000000001
+.000000001
+.00000001
+.0000001
+.000001
+.00001
+.0001
+.001
+.01
+.1
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+1
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+1.1
+11
+110
+1100
+11000
+110000
+1100000
+11000000
+110000000
+1100000000
+11000000000
+110000000000
+1100000000000
+11000000000000
+110000000000000
+1100000000000000
+11000000000000000
+110000000000000000
+1100000000000000000
+11000000000000000000
+1.01
+10.1
+101
+1010
+10100
+101000
+1010000
+10100000
+101000000
+1010000000
+10100000000
+101000000000
+1010000000000
+10100000000000
+101000000000000
+1010000000000000
+10100000000000000
+101000000000000000
+1010000000000000000
+10100000000000000000
+1.001
+10.01
+100.1
+1001
+10010
+100100
+1001000
+10010000
+100100000
+1001000000
+10010000000
+100100000000
+1001000000000
+10010000000000
+100100000000000
+1001000000000000
+10010000000000000
+100100000000000000
+1001000000000000000
+10010000000000000000
+1.0001
+10.001
+100.01
+1000.1
+10001
+100010
+1000100
+10001000
+100010000
+1000100000
+10001000000
+100010000000
+1000100000000
+10001000000000
+100010000000000
+1000100000000000
+10001000000000000
+100010000000000000
+1000100000000000000
+10001000000000000000
+1.00001
+10.0001
+100.001
+1000.01
+10000.1
+100001
+1000010
+10000100
+100001000
+1000010000
+10000100000
+100001000000
+1000010000000
+10000100000000
+100001000000000
+1000010000000000
+10000100000000000
+100001000000000000
+1000010000000000000
+10000100000000000000
+1.000001
+10.00001
+100.0001
+1000.001
+10000.01
+100000.1
+1000001
+10000010
+100000100
+1000001000
+10000010000
+100000100000
+1000001000000
+10000010000000
+100000100000000
+1000001000000000
+10000010000000000
+100000100000000000
+1000001000000000000
+10000010000000000000
+1.0000001
+10.000001
+100.00001
+1000.0001
+10000.001
+100000.01
+1000000.1
+10000001
+100000010
+1000000100
+10000001000
+100000010000
+1000000100000
+10000001000000
+100000010000000
+1000000100000000
+10000001000000000
+100000010000000000
+1000000100000000000
+10000001000000000000
+1.00000001
+10.0000001
+100.000001
+1000.00001
+10000.0001
+100000.001
+1000000.01
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+1.000000001
+10.00000001
+100.0000001
+1000.000001
+10000.00001
+100000.0001
+1000000.001
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+1.0000000001
+10.000000001
+100.00000001
+1000.0000001
+10000.000001
+100000.00001
+1000000.0001
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+10
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+10.1
+101
+1010
+10100
+101000
+1010000
+10100000
+101000000
+1010000000
+10100000000
+101000000000
+1010000000000
+10100000000000
+101000000000000
+1010000000000000
+10100000000000000
+101000000000000000
+1010000000000000000
+10100000000000000000
+101000000000000000000
+10.01
+100.1
+1001
+10010
+100100
+1001000
+10010000
+100100000
+1001000000
+10010000000
+100100000000
+1001000000000
+10010000000000
+100100000000000
+1001000000000000
+10010000000000000
+100100000000000000
+1001000000000000000
+10010000000000000000
+100100000000000000000
+10.001
+100.01
+1000.1
+10001
+100010
+1000100
+10001000
+100010000
+1000100000
+10001000000
+100010000000
+1000100000000
+10001000000000
+100010000000000
+1000100000000000
+10001000000000000
+100010000000000000
+1000100000000000000
+10001000000000000000
+100010000000000000000
+10.0001
+100.001
+1000.01
+10000.1
+100001
+1000010
+10000100
+100001000
+1000010000
+10000100000
+100001000000
+1000010000000
+10000100000000
+100001000000000
+1000010000000000
+10000100000000000
+100001000000000000
+1000010000000000000
+10000100000000000000
+100001000000000000000
+10.00001
+100.0001
+1000.001
+10000.01
+100000.1
+1000001
+10000010
+100000100
+1000001000
+10000010000
+100000100000
+1000001000000
+10000010000000
+100000100000000
+1000001000000000
+10000010000000000
+100000100000000000
+1000001000000000000
+10000010000000000000
+100000100000000000000
+10.000001
+100.00001
+1000.0001
+10000.001
+100000.01
+1000000.1
+10000001
+100000010
+1000000100
+10000001000
+100000010000
+1000000100000
+10000001000000
+100000010000000
+1000000100000000
+10000001000000000
+100000010000000000
+1000000100000000000
+10000001000000000000
+100000010000000000000
+10.0000001
+100.000001
+1000.00001
+10000.0001
+100000.001
+1000000.01
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+100000001000000000000
+10.00000001
+100.0000001
+1000.000001
+10000.00001
+100000.0001
+1000000.001
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+10.000000001
+100.00000001
+1000.0000001
+10000.000001
+100000.00001
+1000000.0001
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+10.0000000001
+100.000000001
+1000.00000001
+10000.0000001
+100000.000001
+1000000.00001
+10000000.0001
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+100
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+100.1
+1001
+10010
+100100
+1001000
+10010000
+100100000
+1001000000
+10010000000
+100100000000
+1001000000000
+10010000000000
+100100000000000
+1001000000000000
+10010000000000000
+100100000000000000
+1001000000000000000
+10010000000000000000
+100100000000000000000
+1001000000000000000000
+100.01
+1000.1
+10001
+100010
+1000100
+10001000
+100010000
+1000100000
+10001000000
+100010000000
+1000100000000
+10001000000000
+100010000000000
+1000100000000000
+10001000000000000
+100010000000000000
+1000100000000000000
+10001000000000000000
+100010000000000000000
+1000100000000000000000
+100.001
+1000.01
+10000.1
+100001
+1000010
+10000100
+100001000
+1000010000
+10000100000
+100001000000
+1000010000000
+10000100000000
+100001000000000
+1000010000000000
+10000100000000000
+100001000000000000
+1000010000000000000
+10000100000000000000
+100001000000000000000
+1000010000000000000000
+100.0001
+1000.001
+10000.01
+100000.1
+1000001
+10000010
+100000100
+1000001000
+10000010000
+100000100000
+1000001000000
+10000010000000
+100000100000000
+1000001000000000
+10000010000000000
+100000100000000000
+1000001000000000000
+10000010000000000000
+100000100000000000000
+1000001000000000000000
+100.00001
+1000.0001
+10000.001
+100000.01
+1000000.1
+10000001
+100000010
+1000000100
+10000001000
+100000010000
+1000000100000
+10000001000000
+100000010000000
+1000000100000000
+10000001000000000
+100000010000000000
+1000000100000000000
+10000001000000000000
+100000010000000000000
+1000000100000000000000
+100.000001
+1000.00001
+10000.0001
+100000.001
+1000000.01
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+100000001000000000000
+1000000010000000000000
+100.0000001
+1000.000001
+10000.00001
+100000.0001
+1000000.001
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+1000000001000000000000
+100.00000001
+1000.0000001
+10000.000001
+100000.00001
+1000000.0001
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+100.000000001
+1000.00000001
+10000.0000001
+100000.000001
+1000000.00001
+10000000.0001
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+100.0000000001
+1000.000000001
+10000.00000001
+100000.0000001
+1000000.000001
+10000000.00001
+100000000.0001
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+1000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+1000.1
+10001
+100010
+1000100
+10001000
+100010000
+1000100000
+10001000000
+100010000000
+1000100000000
+10001000000000
+100010000000000
+1000100000000000
+10001000000000000
+100010000000000000
+1000100000000000000
+10001000000000000000
+100010000000000000000
+1000100000000000000000
+10001000000000000000000
+1000.01
+10000.1
+100001
+1000010
+10000100
+100001000
+1000010000
+10000100000
+100001000000
+1000010000000
+10000100000000
+100001000000000
+1000010000000000
+10000100000000000
+100001000000000000
+1000010000000000000
+10000100000000000000
+100001000000000000000
+1000010000000000000000
+10000100000000000000000
+1000.001
+10000.01
+100000.1
+1000001
+10000010
+100000100
+1000001000
+10000010000
+100000100000
+1000001000000
+10000010000000
+100000100000000
+1000001000000000
+10000010000000000
+100000100000000000
+1000001000000000000
+10000010000000000000
+100000100000000000000
+1000001000000000000000
+10000010000000000000000
+1000.0001
+10000.001
+100000.01
+1000000.1
+10000001
+100000010
+1000000100
+10000001000
+100000010000
+1000000100000
+10000001000000
+100000010000000
+1000000100000000
+10000001000000000
+100000010000000000
+1000000100000000000
+10000001000000000000
+100000010000000000000
+1000000100000000000000
+10000001000000000000000
+1000.00001
+10000.0001
+100000.001
+1000000.01
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+100000001000000000000
+1000000010000000000000
+10000000100000000000000
+1000.000001
+10000.00001
+100000.0001
+1000000.001
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+1000000001000000000000
+10000000010000000000000
+1000.0000001
+10000.000001
+100000.00001
+1000000.0001
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+10000000001000000000000
+1000.00000001
+10000.0000001
+100000.000001
+1000000.00001
+10000000.0001
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+1000.000000001
+10000.00000001
+100000.0000001
+1000000.000001
+10000000.00001
+100000000.0001
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+1000.0000000001
+10000.000000001
+100000.00000001
+1000000.0000001
+10000000.000001
+100000000.00001
+1000000000.0001
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+10000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+100000000000000000000000
+10000.1
+100001
+1000010
+10000100
+100001000
+1000010000
+10000100000
+100001000000
+1000010000000
+10000100000000
+100001000000000
+1000010000000000
+10000100000000000
+100001000000000000
+1000010000000000000
+10000100000000000000
+100001000000000000000
+1000010000000000000000
+10000100000000000000000
+100001000000000000000000
+10000.01
+100000.1
+1000001
+10000010
+100000100
+1000001000
+10000010000
+100000100000
+1000001000000
+10000010000000
+100000100000000
+1000001000000000
+10000010000000000
+100000100000000000
+1000001000000000000
+10000010000000000000
+100000100000000000000
+1000001000000000000000
+10000010000000000000000
+100000100000000000000000
+10000.001
+100000.01
+1000000.1
+10000001
+100000010
+1000000100
+10000001000
+100000010000
+1000000100000
+10000001000000
+100000010000000
+1000000100000000
+10000001000000000
+100000010000000000
+1000000100000000000
+10000001000000000000
+100000010000000000000
+1000000100000000000000
+10000001000000000000000
+100000010000000000000000
+10000.0001
+100000.001
+1000000.01
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+100000001000000000000
+1000000010000000000000
+10000000100000000000000
+100000001000000000000000
+10000.00001
+100000.0001
+1000000.001
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+1000000001000000000000
+10000000010000000000000
+100000000100000000000000
+10000.000001
+100000.00001
+1000000.0001
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+10000000001000000000000
+100000000010000000000000
+10000.0000001
+100000.000001
+1000000.00001
+10000000.0001
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+100000000001000000000000
+10000.00000001
+100000.0000001
+1000000.000001
+10000000.00001
+100000000.0001
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+100000000000100000000000
+10000.000000001
+100000.00000001
+1000000.0000001
+10000000.000001
+100000000.00001
+1000000000.0001
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+100000000000010000000000
+10000.0000000001
+100000.000000001
+1000000.00000001
+10000000.0000001
+100000000.000001
+1000000000.00001
+10000000000.0001
+100000000000.001
+1000000000000.01
+10000000000000.1
+100000000000001
+1000000000000010
+10000000000000100
+100000000000001000
+1000000000000010000
+10000000000000100000
+100000000000001000000
+1000000000000010000000
+10000000000000100000000
+100000000000001000000000
+100000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+100000000000000000000000
+1000000000000000000000000
+100000.1
+1000001
+10000010
+100000100
+1000001000
+10000010000
+100000100000
+1000001000000
+10000010000000
+100000100000000
+1000001000000000
+10000010000000000
+100000100000000000
+1000001000000000000
+10000010000000000000
+100000100000000000000
+1000001000000000000000
+10000010000000000000000
+100000100000000000000000
+1000001000000000000000000
+100000.01
+1000000.1
+10000001
+100000010
+1000000100
+10000001000
+100000010000
+1000000100000
+10000001000000
+100000010000000
+1000000100000000
+10000001000000000
+100000010000000000
+1000000100000000000
+10000001000000000000
+100000010000000000000
+1000000100000000000000
+10000001000000000000000
+100000010000000000000000
+1000000100000000000000000
+100000.001
+1000000.01
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+100000001000000000000
+1000000010000000000000
+10000000100000000000000
+100000001000000000000000
+1000000010000000000000000
+100000.0001
+1000000.001
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+1000000001000000000000
+10000000010000000000000
+100000000100000000000000
+1000000001000000000000000
+100000.00001
+1000000.0001
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+10000000001000000000000
+100000000010000000000000
+1000000000100000000000000
+100000.000001
+1000000.00001
+10000000.0001
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+100000000001000000000000
+1000000000010000000000000
+100000.0000001
+1000000.000001
+10000000.00001
+100000000.0001
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+100000000000100000000000
+1000000000001000000000000
+100000.00000001
+1000000.0000001
+10000000.000001
+100000000.00001
+1000000000.0001
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+100000000000010000000000
+1000000000000100000000000
+100000.000000001
+1000000.00000001
+10000000.0000001
+100000000.000001
+1000000000.00001
+10000000000.0001
+100000000000.001
+1000000000000.01
+10000000000000.1
+100000000000001
+1000000000000010
+10000000000000100
+100000000000001000
+1000000000000010000
+10000000000000100000
+100000000000001000000
+1000000000000010000000
+10000000000000100000000
+100000000000001000000000
+1000000000000010000000000
+100000.0000000001
+1000000.000000001
+10000000.00000001
+100000000.0000001
+1000000000.000001
+10000000000.00001
+100000000000.0001
+1000000000000.001
+10000000000000.01
+100000000000000.1
+1000000000000001
+10000000000000010
+100000000000000100
+1000000000000001000
+10000000000000010000
+100000000000000100000
+1000000000000001000000
+10000000000000010000000
+100000000000000100000000
+1000000000000001000000000
+1000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+100000000000000000000000
+1000000000000000000000000
+10000000000000000000000000
+1000000.1
+10000001
+100000010
+1000000100
+10000001000
+100000010000
+1000000100000
+10000001000000
+100000010000000
+1000000100000000
+10000001000000000
+100000010000000000
+1000000100000000000
+10000001000000000000
+100000010000000000000
+1000000100000000000000
+10000001000000000000000
+100000010000000000000000
+1000000100000000000000000
+10000001000000000000000000
+1000000.01
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+100000001000000000000
+1000000010000000000000
+10000000100000000000000
+100000001000000000000000
+1000000010000000000000000
+10000000100000000000000000
+1000000.001
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+1000000001000000000000
+10000000010000000000000
+100000000100000000000000
+1000000001000000000000000
+10000000010000000000000000
+1000000.0001
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+10000000001000000000000
+100000000010000000000000
+1000000000100000000000000
+10000000001000000000000000
+1000000.00001
+10000000.0001
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+100000000001000000000000
+1000000000010000000000000
+10000000000100000000000000
+1000000.000001
+10000000.00001
+100000000.0001
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+100000000000100000000000
+1000000000001000000000000
+10000000000010000000000000
+1000000.0000001
+10000000.000001
+100000000.00001
+1000000000.0001
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+100000000000010000000000
+1000000000000100000000000
+10000000000001000000000000
+1000000.00000001
+10000000.0000001
+100000000.000001
+1000000000.00001
+10000000000.0001
+100000000000.001
+1000000000000.01
+10000000000000.1
+100000000000001
+1000000000000010
+10000000000000100
+100000000000001000
+1000000000000010000
+10000000000000100000
+100000000000001000000
+1000000000000010000000
+10000000000000100000000
+100000000000001000000000
+1000000000000010000000000
+10000000000000100000000000
+1000000.000000001
+10000000.00000001
+100000000.0000001
+1000000000.000001
+10000000000.00001
+100000000000.0001
+1000000000000.001
+10000000000000.01
+100000000000000.1
+1000000000000001
+10000000000000010
+100000000000000100
+1000000000000001000
+10000000000000010000
+100000000000000100000
+1000000000000001000000
+10000000000000010000000
+100000000000000100000000
+1000000000000001000000000
+10000000000000010000000000
+1000000.0000000001
+10000000.000000001
+100000000.00000001
+1000000000.0000001
+10000000000.000001
+100000000000.00001
+1000000000000.0001
+10000000000000.001
+100000000000000.01
+1000000000000000.1
+10000000000000001
+100000000000000010
+1000000000000000100
+10000000000000001000
+100000000000000010000
+1000000000000000100000
+10000000000000001000000
+100000000000000010000000
+1000000000000000100000000
+10000000000000001000000000
+10000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+100000000000000000000000
+1000000000000000000000000
+10000000000000000000000000
+100000000000000000000000000
+10000000.1
+100000001
+1000000010
+10000000100
+100000001000
+1000000010000
+10000000100000
+100000001000000
+1000000010000000
+10000000100000000
+100000001000000000
+1000000010000000000
+10000000100000000000
+100000001000000000000
+1000000010000000000000
+10000000100000000000000
+100000001000000000000000
+1000000010000000000000000
+10000000100000000000000000
+100000001000000000000000000
+10000000.01
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+1000000001000000000000
+10000000010000000000000
+100000000100000000000000
+1000000001000000000000000
+10000000010000000000000000
+100000000100000000000000000
+10000000.001
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+10000000001000000000000
+100000000010000000000000
+1000000000100000000000000
+10000000001000000000000000
+100000000010000000000000000
+10000000.0001
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+100000000001000000000000
+1000000000010000000000000
+10000000000100000000000000
+100000000001000000000000000
+10000000.00001
+100000000.0001
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+100000000000100000000000
+1000000000001000000000000
+10000000000010000000000000
+100000000000100000000000000
+10000000.000001
+100000000.00001
+1000000000.0001
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+100000000000010000000000
+1000000000000100000000000
+10000000000001000000000000
+100000000000010000000000000
+10000000.0000001
+100000000.000001
+1000000000.00001
+10000000000.0001
+100000000000.001
+1000000000000.01
+10000000000000.1
+100000000000001
+1000000000000010
+10000000000000100
+100000000000001000
+1000000000000010000
+10000000000000100000
+100000000000001000000
+1000000000000010000000
+10000000000000100000000
+100000000000001000000000
+1000000000000010000000000
+10000000000000100000000000
+100000000000001000000000000
+10000000.00000001
+100000000.0000001
+1000000000.000001
+10000000000.00001
+100000000000.0001
+1000000000000.001
+10000000000000.01
+100000000000000.1
+1000000000000001
+10000000000000010
+100000000000000100
+1000000000000001000
+10000000000000010000
+100000000000000100000
+1000000000000001000000
+10000000000000010000000
+100000000000000100000000
+1000000000000001000000000
+10000000000000010000000000
+100000000000000100000000000
+10000000.000000001
+100000000.00000001
+1000000000.0000001
+10000000000.000001
+100000000000.00001
+1000000000000.0001
+10000000000000.001
+100000000000000.01
+1000000000000000.1
+10000000000000001
+100000000000000010
+1000000000000000100
+10000000000000001000
+100000000000000010000
+1000000000000000100000
+10000000000000001000000
+100000000000000010000000
+1000000000000000100000000
+10000000000000001000000000
+100000000000000010000000000
+10000000.0000000001
+100000000.000000001
+1000000000.00000001
+10000000000.0000001
+100000000000.000001
+1000000000000.00001
+10000000000000.0001
+100000000000000.001
+1000000000000000.01
+10000000000000000.1
+100000000000000001
+1000000000000000010
+10000000000000000100
+100000000000000001000
+1000000000000000010000
+10000000000000000100000
+100000000000000001000000
+1000000000000000010000000
+10000000000000000100000000
+100000000000000001000000000
+100000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+100000000000000000000000
+1000000000000000000000000
+10000000000000000000000000
+100000000000000000000000000
+1000000000000000000000000000
+100000000.1
+1000000001
+10000000010
+100000000100
+1000000001000
+10000000010000
+100000000100000
+1000000001000000
+10000000010000000
+100000000100000000
+1000000001000000000
+10000000010000000000
+100000000100000000000
+1000000001000000000000
+10000000010000000000000
+100000000100000000000000
+1000000001000000000000000
+10000000010000000000000000
+100000000100000000000000000
+1000000001000000000000000000
+100000000.01
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+10000000001000000000000
+100000000010000000000000
+1000000000100000000000000
+10000000001000000000000000
+100000000010000000000000000
+1000000000100000000000000000
+100000000.001
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+100000000001000000000000
+1000000000010000000000000
+10000000000100000000000000
+100000000001000000000000000
+1000000000010000000000000000
+100000000.0001
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+100000000000100000000000
+1000000000001000000000000
+10000000000010000000000000
+100000000000100000000000000
+1000000000001000000000000000
+100000000.00001
+1000000000.0001
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+100000000000010000000000
+1000000000000100000000000
+10000000000001000000000000
+100000000000010000000000000
+1000000000000100000000000000
+100000000.000001
+1000000000.00001
+10000000000.0001
+100000000000.001
+1000000000000.01
+10000000000000.1
+100000000000001
+1000000000000010
+10000000000000100
+100000000000001000
+1000000000000010000
+10000000000000100000
+100000000000001000000
+1000000000000010000000
+10000000000000100000000
+100000000000001000000000
+1000000000000010000000000
+10000000000000100000000000
+100000000000001000000000000
+1000000000000010000000000000
+100000000.0000001
+1000000000.000001
+10000000000.00001
+100000000000.0001
+1000000000000.001
+10000000000000.01
+100000000000000.1
+1000000000000001
+10000000000000010
+100000000000000100
+1000000000000001000
+10000000000000010000
+100000000000000100000
+1000000000000001000000
+10000000000000010000000
+100000000000000100000000
+1000000000000001000000000
+10000000000000010000000000
+100000000000000100000000000
+1000000000000001000000000000
+100000000.00000001
+1000000000.0000001
+10000000000.000001
+100000000000.00001
+1000000000000.0001
+10000000000000.001
+100000000000000.01
+1000000000000000.1
+10000000000000001
+100000000000000010
+1000000000000000100
+10000000000000001000
+100000000000000010000
+1000000000000000100000
+10000000000000001000000
+100000000000000010000000
+1000000000000000100000000
+10000000000000001000000000
+100000000000000010000000000
+1000000000000000100000000000
+100000000.000000001
+1000000000.00000001
+10000000000.0000001
+100000000000.000001
+1000000000000.00001
+10000000000000.0001
+100000000000000.001
+1000000000000000.01
+10000000000000000.1
+100000000000000001
+1000000000000000010
+10000000000000000100
+100000000000000001000
+1000000000000000010000
+10000000000000000100000
+100000000000000001000000
+1000000000000000010000000
+10000000000000000100000000
+100000000000000001000000000
+1000000000000000010000000000
+100000000.0000000001
+1000000000.000000001
+10000000000.00000001
+100000000000.0000001
+1000000000000.000001
+10000000000000.00001
+100000000000000.0001
+1000000000000000.001
+10000000000000000.01
+100000000000000000.1
+1000000000000000001
+10000000000000000010
+100000000000000000100
+1000000000000000001000
+10000000000000000010000
+100000000000000000100000
+1000000000000000001000000
+10000000000000000010000000
+100000000000000000100000000
+1000000000000000001000000000
+1000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+100000000000000000000000
+1000000000000000000000000
+10000000000000000000000000
+100000000000000000000000000
+1000000000000000000000000000
+10000000000000000000000000000
+1000000000.1
+10000000001
+100000000010
+1000000000100
+10000000001000
+100000000010000
+1000000000100000
+10000000001000000
+100000000010000000
+1000000000100000000
+10000000001000000000
+100000000010000000000
+1000000000100000000000
+10000000001000000000000
+100000000010000000000000
+1000000000100000000000000
+10000000001000000000000000
+100000000010000000000000000
+1000000000100000000000000000
+10000000001000000000000000000
+1000000000.01
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+100000000001000000000000
+1000000000010000000000000
+10000000000100000000000000
+100000000001000000000000000
+1000000000010000000000000000
+10000000000100000000000000000
+1000000000.001
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+100000000000100000000000
+1000000000001000000000000
+10000000000010000000000000
+100000000000100000000000000
+1000000000001000000000000000
+10000000000010000000000000000
+1000000000.0001
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+100000000000010000000000
+1000000000000100000000000
+10000000000001000000000000
+100000000000010000000000000
+1000000000000100000000000000
+10000000000001000000000000000
+1000000000.00001
+10000000000.0001
+100000000000.001
+1000000000000.01
+10000000000000.1
+100000000000001
+1000000000000010
+10000000000000100
+100000000000001000
+1000000000000010000
+10000000000000100000
+100000000000001000000
+1000000000000010000000
+10000000000000100000000
+100000000000001000000000
+1000000000000010000000000
+10000000000000100000000000
+100000000000001000000000000
+1000000000000010000000000000
+10000000000000100000000000000
+1000000000.000001
+10000000000.00001
+100000000000.0001
+1000000000000.001
+10000000000000.01
+100000000000000.1
+1000000000000001
+10000000000000010
+100000000000000100
+1000000000000001000
+10000000000000010000
+100000000000000100000
+1000000000000001000000
+10000000000000010000000
+100000000000000100000000
+1000000000000001000000000
+10000000000000010000000000
+100000000000000100000000000
+1000000000000001000000000000
+10000000000000010000000000000
+1000000000.0000001
+10000000000.000001
+100000000000.00001
+1000000000000.0001
+10000000000000.001
+100000000000000.01
+1000000000000000.1
+10000000000000001
+100000000000000010
+1000000000000000100
+10000000000000001000
+100000000000000010000
+1000000000000000100000
+10000000000000001000000
+100000000000000010000000
+1000000000000000100000000
+10000000000000001000000000
+100000000000000010000000000
+1000000000000000100000000000
+10000000000000001000000000000
+1000000000.00000001
+10000000000.0000001
+100000000000.000001
+1000000000000.00001
+10000000000000.0001
+100000000000000.001
+1000000000000000.01
+10000000000000000.1
+100000000000000001
+1000000000000000010
+10000000000000000100
+100000000000000001000
+1000000000000000010000
+10000000000000000100000
+100000000000000001000000
+1000000000000000010000000
+10000000000000000100000000
+100000000000000001000000000
+1000000000000000010000000000
+10000000000000000100000000000
+1000000000.000000001
+10000000000.00000001
+100000000000.0000001
+1000000000000.000001
+10000000000000.00001
+100000000000000.0001
+1000000000000000.001
+10000000000000000.01
+100000000000000000.1
+1000000000000000001
+10000000000000000010
+100000000000000000100
+1000000000000000001000
+10000000000000000010000
+100000000000000000100000
+1000000000000000001000000
+10000000000000000010000000
+100000000000000000100000000
+1000000000000000001000000000
+10000000000000000010000000000
+1000000000.0000000001
+10000000000.000000001
+100000000000.00000001
+1000000000000.0000001
+10000000000000.000001
+100000000000000.00001
+1000000000000000.0001
+10000000000000000.001
+100000000000000000.01
+1000000000000000000.1
+10000000000000000001
+100000000000000000010
+1000000000000000000100
+10000000000000000001000
+100000000000000000010000
+1000000000000000000100000
+10000000000000000001000000
+100000000000000000010000000
+1000000000000000000100000000
+10000000000000000001000000000
+10000000000
+100000000000
+1000000000000
+10000000000000
+100000000000000
+1000000000000000
+10000000000000000
+100000000000000000
+1000000000000000000
+10000000000000000000
+100000000000000000000
+1000000000000000000000
+10000000000000000000000
+100000000000000000000000
+1000000000000000000000000
+10000000000000000000000000
+100000000000000000000000000
+1000000000000000000000000000
+10000000000000000000000000000
+100000000000000000000000000000
+10000000000.1
+100000000001
+1000000000010
+10000000000100
+100000000001000
+1000000000010000
+10000000000100000
+100000000001000000
+1000000000010000000
+10000000000100000000
+100000000001000000000
+1000000000010000000000
+10000000000100000000000
+100000000001000000000000
+1000000000010000000000000
+10000000000100000000000000
+100000000001000000000000000
+1000000000010000000000000000
+10000000000100000000000000000
+100000000001000000000000000000
+10000000000.01
+100000000000.1
+1000000000001
+10000000000010
+100000000000100
+1000000000001000
+10000000000010000
+100000000000100000
+1000000000001000000
+10000000000010000000
+100000000000100000000
+1000000000001000000000
+10000000000010000000000
+100000000000100000000000
+1000000000001000000000000
+10000000000010000000000000
+100000000000100000000000000
+1000000000001000000000000000
+10000000000010000000000000000
+100000000000100000000000000000
+10000000000.001
+100000000000.01
+1000000000000.1
+10000000000001
+100000000000010
+1000000000000100
+10000000000001000
+100000000000010000
+1000000000000100000
+10000000000001000000
+100000000000010000000
+1000000000000100000000
+10000000000001000000000
+100000000000010000000000
+1000000000000100000000000
+10000000000001000000000000
+100000000000010000000000000
+1000000000000100000000000000
+10000000000001000000000000000
+100000000000010000000000000000
+10000000000.0001
+100000000000.001
+1000000000000.01
+10000000000000.1
+100000000000001
+1000000000000010
+10000000000000100
+100000000000001000
+1000000000000010000
+10000000000000100000
+100000000000001000000
+1000000000000010000000
+10000000000000100000000
+100000000000001000000000
+1000000000000010000000000
+10000000000000100000000000
+100000000000001000000000000
+1000000000000010000000000000
+10000000000000100000000000000
+100000000000001000000000000000
+10000000000.00001
+100000000000.0001
+1000000000000.001
+10000000000000.01
+100000000000000.1
+1000000000000001
+10000000000000010
+100000000000000100
+1000000000000001000
+10000000000000010000
+100000000000000100000
+1000000000000001000000
+10000000000000010000000
+100000000000000100000000
+1000000000000001000000000
+10000000000000010000000000
+100000000000000100000000000
+1000000000000001000000000000
+10000000000000010000000000000
+100000000000000100000000000000
+10000000000.000001
+100000000000.00001
+1000000000000.0001
+10000000000000.001
+100000000000000.01
+1000000000000000.1
+10000000000000001
+100000000000000010
+1000000000000000100
+10000000000000001000
+100000000000000010000
+1000000000000000100000
+10000000000000001000000
+100000000000000010000000
+1000000000000000100000000
+10000000000000001000000000
+100000000000000010000000000
+1000000000000000100000000000
+10000000000000001000000000000
+100000000000000010000000000000
+10000000000.0000001
+100000000000.000001
+1000000000000.00001
+10000000000000.0001
+100000000000000.001
+1000000000000000.01
+10000000000000000.1
+100000000000000001
+1000000000000000010
+10000000000000000100
+100000000000000001000
+1000000000000000010000
+10000000000000000100000
+100000000000000001000000
+1000000000000000010000000
+10000000000000000100000000
+100000000000000001000000000
+1000000000000000010000000000
+10000000000000000100000000000
+100000000000000001000000000000
+10000000000.00000001
+100000000000.0000001
+1000000000000.000001
+10000000000000.00001
+100000000000000.0001
+1000000000000000.001
+10000000000000000.01
+100000000000000000.1
+1000000000000000001
+10000000000000000010
+100000000000000000100
+1000000000000000001000
+10000000000000000010000
+100000000000000000100000
+1000000000000000001000000
+10000000000000000010000000
+100000000000000000100000000
+1000000000000000001000000000
+10000000000000000010000000000
+100000000000000000100000000000
+10000000000.000000001
+100000000000.00000001
+1000000000000.0000001
+10000000000000.000001
+100000000000000.00001
+1000000000000000.0001
+10000000000000000.001
+100000000000000000.01
+1000000000000000000.1
+10000000000000000001
+100000000000000000010
+1000000000000000000100
+10000000000000000001000
+100000000000000000010000
+1000000000000000000100000
+10000000000000000001000000
+100000000000000000010000000
+1000000000000000000100000000
+10000000000000000001000000000
+100000000000000000010000000000
+10000000000.0000000001
+100000000000.000000001
+1000000000000.00000001
+10000000000000.0000001
+100000000000000.000001
+1000000000000000.00001
+10000000000000000.0001
+100000000000000000.001
+1000000000000000000.01
+10000000000000000000.1
+100000000000000000001
+1000000000000000000010
+10000000000000000000100
+100000000000000000001000
+1000000000000000000010000
+10000000000000000000100000
+100000000000000000001000000
+1000000000000000000010000000
+10000000000000000000100000000
+100000000000000000001000000000
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+.1
+.01
+.001
+.0001
+.00001
+.000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.01
+.001
+.0001
+.00001
+.000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.001
+.0001
+.00001
+.000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.0001
+.00001
+.000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.00000000000000000000001
+.00001
+.000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.00000000000000000000001
+.000000000000000000000001
+.000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.00000000000000000000001
+.000000000000000000000001
+.0000000000000000000000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.00000000000000000000001
+.000000000000000000000001
+.0000000000000000000000001
+.00000000000000000000000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.00000000000000000000001
+.000000000000000000000001
+.0000000000000000000000001
+.00000000000000000000000001
+.000000000000000000000000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.00000000000000000000001
+.000000000000000000000001
+.0000000000000000000000001
+.00000000000000000000000001
+.000000000000000000000000001
+.0000000000000000000000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+.00000000000000000001
+.000000000000000000001
+.0000000000000000000001
+.00000000000000000000001
+.000000000000000000000001
+.0000000000000000000000001
+.00000000000000000000000001
+.000000000000000000000000001
+.0000000000000000000000000001
+.00000000000000000000000000001
+1
+.1
+.01
+.001
+.0001
+.00001
+.000001
+.0000001
+.00000001
+.000000001
+.0000000001
+.00000000001
+.000000000001
+.0000000000001
+.00000000000001
+.000000000000001
+.0000000000000001
+.00000000000000001
+.000000000000000001
+.0000000000000000001
+1.1
+.11
+.011
+.0011
+.00011
+.000011
+.0000011
+.00000011
+.000000011
+.0000000011
+.00000000011
+.000000000011
+.0000000000011
+.00000000000011
+.000000000000011
+.0000000000000011
+.00000000000000011
+.000000000000000011
+.0000000000000000011
+.00000000000000000011
+1.01
+.101
+.0101
+.00101
+.000101
+.0000101
+.00000101
+.000000101
+.0000000101
+.00000000101
+.000000000101
+.0000000000101
+.00000000000101
+.000000000000101
+.0000000000000101
+.00000000000000101
+.000000000000000101
+.0000000000000000101
+.00000000000000000101
+.000000000000000000101
+1.001
+.1001
+.01001
+.001001
+.0001001
+.00001001
+.000001001
+.0000001001
+.00000001001
+.000000001001
+.0000000001001
+.00000000001001
+.000000000001001
+.0000000000001001
+.00000000000001001
+.000000000000001001
+.0000000000000001001
+.00000000000000001001
+.000000000000000001001
+.0000000000000000001001
+1.0001
+.10001
+.010001
+.0010001
+.00010001
+.000010001
+.0000010001
+.00000010001
+.000000010001
+.0000000010001
+.00000000010001
+.000000000010001
+.0000000000010001
+.00000000000010001
+.000000000000010001
+.0000000000000010001
+.00000000000000010001
+.000000000000000010001
+.0000000000000000010001
+.00000000000000000010001
+1.00001
+.100001
+.0100001
+.00100001
+.000100001
+.0000100001
+.00000100001
+.000000100001
+.0000000100001
+.00000000100001
+.000000000100001
+.0000000000100001
+.00000000000100001
+.000000000000100001
+.0000000000000100001
+.00000000000000100001
+.000000000000000100001
+.0000000000000000100001
+.00000000000000000100001
+.000000000000000000100001
+1.000001
+.1000001
+.01000001
+.001000001
+.0001000001
+.00001000001
+.000001000001
+.0000001000001
+.00000001000001
+.000000001000001
+.0000000001000001
+.00000000001000001
+.000000000001000001
+.0000000000001000001
+.00000000000001000001
+.000000000000001000001
+.0000000000000001000001
+.00000000000000001000001
+.000000000000000001000001
+.0000000000000000001000001
+1.0000001
+.10000001
+.010000001
+.0010000001
+.00010000001
+.000010000001
+.0000010000001
+.00000010000001
+.000000010000001
+.0000000010000001
+.00000000010000001
+.000000000010000001
+.0000000000010000001
+.00000000000010000001
+.000000000000010000001
+.0000000000000010000001
+.00000000000000010000001
+.000000000000000010000001
+.0000000000000000010000001
+.00000000000000000010000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+.000000000000100000001
+.0000000000000100000001
+.00000000000000100000001
+.000000000000000100000001
+.0000000000000000100000001
+.00000000000000000100000001
+.000000000000000000100000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+.0000000000001000000001
+.00000000000001000000001
+.000000000000001000000001
+.0000000000000001000000001
+.00000000000000001000000001
+.000000000000000001000000001
+.0000000000000000001000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+.00000000000010000000001
+.000000000000010000000001
+.0000000000000010000000001
+.00000000000000010000000001
+.000000000000000010000000001
+.0000000000000000010000000001
+.00000000000000000010000000001
+10
+1.0
+.10
+.010
+.0010
+.00010
+.000010
+.0000010
+.00000010
+.000000010
+.0000000010
+.00000000010
+.000000000010
+.0000000000010
+.00000000000010
+.000000000000010
+.0000000000000010
+.00000000000000010
+.000000000000000010
+.0000000000000000010
+10.1
+1.01
+.101
+.0101
+.00101
+.000101
+.0000101
+.00000101
+.000000101
+.0000000101
+.00000000101
+.000000000101
+.0000000000101
+.00000000000101
+.000000000000101
+.0000000000000101
+.00000000000000101
+.000000000000000101
+.0000000000000000101
+.00000000000000000101
+10.01
+1.001
+.1001
+.01001
+.001001
+.0001001
+.00001001
+.000001001
+.0000001001
+.00000001001
+.000000001001
+.0000000001001
+.00000000001001
+.000000000001001
+.0000000000001001
+.00000000000001001
+.000000000000001001
+.0000000000000001001
+.00000000000000001001
+.000000000000000001001
+10.001
+1.0001
+.10001
+.010001
+.0010001
+.00010001
+.000010001
+.0000010001
+.00000010001
+.000000010001
+.0000000010001
+.00000000010001
+.000000000010001
+.0000000000010001
+.00000000000010001
+.000000000000010001
+.0000000000000010001
+.00000000000000010001
+.000000000000000010001
+.0000000000000000010001
+10.0001
+1.00001
+.100001
+.0100001
+.00100001
+.000100001
+.0000100001
+.00000100001
+.000000100001
+.0000000100001
+.00000000100001
+.000000000100001
+.0000000000100001
+.00000000000100001
+.000000000000100001
+.0000000000000100001
+.00000000000000100001
+.000000000000000100001
+.0000000000000000100001
+.00000000000000000100001
+10.00001
+1.000001
+.1000001
+.01000001
+.001000001
+.0001000001
+.00001000001
+.000001000001
+.0000001000001
+.00000001000001
+.000000001000001
+.0000000001000001
+.00000000001000001
+.000000000001000001
+.0000000000001000001
+.00000000000001000001
+.000000000000001000001
+.0000000000000001000001
+.00000000000000001000001
+.000000000000000001000001
+10.000001
+1.0000001
+.10000001
+.010000001
+.0010000001
+.00010000001
+.000010000001
+.0000010000001
+.00000010000001
+.000000010000001
+.0000000010000001
+.00000000010000001
+.000000000010000001
+.0000000000010000001
+.00000000000010000001
+.000000000000010000001
+.0000000000000010000001
+.00000000000000010000001
+.000000000000000010000001
+.0000000000000000010000001
+10.0000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+.000000000000100000001
+.0000000000000100000001
+.00000000000000100000001
+.000000000000000100000001
+.0000000000000000100000001
+.00000000000000000100000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+.0000000000001000000001
+.00000000000001000000001
+.000000000000001000000001
+.0000000000000001000000001
+.00000000000000001000000001
+.000000000000000001000000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+.00000000000010000000001
+.000000000000010000000001
+.0000000000000010000000001
+.00000000000000010000000001
+.000000000000000010000000001
+.0000000000000000010000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+.00000000000100000000001
+.000000000000100000000001
+.0000000000000100000000001
+.00000000000000100000000001
+.000000000000000100000000001
+.0000000000000000100000000001
+.00000000000000000100000000001
+100
+10.0
+1.00
+.100
+.0100
+.00100
+.000100
+.0000100
+.00000100
+.000000100
+.0000000100
+.00000000100
+.000000000100
+.0000000000100
+.00000000000100
+.000000000000100
+.0000000000000100
+.00000000000000100
+.000000000000000100
+.0000000000000000100
+100.1
+10.01
+1.001
+.1001
+.01001
+.001001
+.0001001
+.00001001
+.000001001
+.0000001001
+.00000001001
+.000000001001
+.0000000001001
+.00000000001001
+.000000000001001
+.0000000000001001
+.00000000000001001
+.000000000000001001
+.0000000000000001001
+.00000000000000001001
+100.01
+10.001
+1.0001
+.10001
+.010001
+.0010001
+.00010001
+.000010001
+.0000010001
+.00000010001
+.000000010001
+.0000000010001
+.00000000010001
+.000000000010001
+.0000000000010001
+.00000000000010001
+.000000000000010001
+.0000000000000010001
+.00000000000000010001
+.000000000000000010001
+100.001
+10.0001
+1.00001
+.100001
+.0100001
+.00100001
+.000100001
+.0000100001
+.00000100001
+.000000100001
+.0000000100001
+.00000000100001
+.000000000100001
+.0000000000100001
+.00000000000100001
+.000000000000100001
+.0000000000000100001
+.00000000000000100001
+.000000000000000100001
+.0000000000000000100001
+100.0001
+10.00001
+1.000001
+.1000001
+.01000001
+.001000001
+.0001000001
+.00001000001
+.000001000001
+.0000001000001
+.00000001000001
+.000000001000001
+.0000000001000001
+.00000000001000001
+.000000000001000001
+.0000000000001000001
+.00000000000001000001
+.000000000000001000001
+.0000000000000001000001
+.00000000000000001000001
+100.00001
+10.000001
+1.0000001
+.10000001
+.010000001
+.0010000001
+.00010000001
+.000010000001
+.0000010000001
+.00000010000001
+.000000010000001
+.0000000010000001
+.00000000010000001
+.000000000010000001
+.0000000000010000001
+.00000000000010000001
+.000000000000010000001
+.0000000000000010000001
+.00000000000000010000001
+.000000000000000010000001
+100.000001
+10.0000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+.000000000000100000001
+.0000000000000100000001
+.00000000000000100000001
+.000000000000000100000001
+.0000000000000000100000001
+100.0000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+.0000000000001000000001
+.00000000000001000000001
+.000000000000001000000001
+.0000000000000001000000001
+.00000000000000001000000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+.00000000000010000000001
+.000000000000010000000001
+.0000000000000010000000001
+.00000000000000010000000001
+.000000000000000010000000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+.00000000000100000000001
+.000000000000100000000001
+.0000000000000100000000001
+.00000000000000100000000001
+.000000000000000100000000001
+.0000000000000000100000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+.00000000001000000000001
+.000000000001000000000001
+.0000000000001000000000001
+.00000000000001000000000001
+.000000000000001000000000001
+.0000000000000001000000000001
+.00000000000000001000000000001
+1000
+100.0
+10.00
+1.000
+.1000
+.01000
+.001000
+.0001000
+.00001000
+.000001000
+.0000001000
+.00000001000
+.000000001000
+.0000000001000
+.00000000001000
+.000000000001000
+.0000000000001000
+.00000000000001000
+.000000000000001000
+.0000000000000001000
+1000.1
+100.01
+10.001
+1.0001
+.10001
+.010001
+.0010001
+.00010001
+.000010001
+.0000010001
+.00000010001
+.000000010001
+.0000000010001
+.00000000010001
+.000000000010001
+.0000000000010001
+.00000000000010001
+.000000000000010001
+.0000000000000010001
+.00000000000000010001
+1000.01
+100.001
+10.0001
+1.00001
+.100001
+.0100001
+.00100001
+.000100001
+.0000100001
+.00000100001
+.000000100001
+.0000000100001
+.00000000100001
+.000000000100001
+.0000000000100001
+.00000000000100001
+.000000000000100001
+.0000000000000100001
+.00000000000000100001
+.000000000000000100001
+1000.001
+100.0001
+10.00001
+1.000001
+.1000001
+.01000001
+.001000001
+.0001000001
+.00001000001
+.000001000001
+.0000001000001
+.00000001000001
+.000000001000001
+.0000000001000001
+.00000000001000001
+.000000000001000001
+.0000000000001000001
+.00000000000001000001
+.000000000000001000001
+.0000000000000001000001
+1000.0001
+100.00001
+10.000001
+1.0000001
+.10000001
+.010000001
+.0010000001
+.00010000001
+.000010000001
+.0000010000001
+.00000010000001
+.000000010000001
+.0000000010000001
+.00000000010000001
+.000000000010000001
+.0000000000010000001
+.00000000000010000001
+.000000000000010000001
+.0000000000000010000001
+.00000000000000010000001
+1000.00001
+100.000001
+10.0000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+.000000000000100000001
+.0000000000000100000001
+.00000000000000100000001
+.000000000000000100000001
+1000.000001
+100.0000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+.0000000000001000000001
+.00000000000001000000001
+.000000000000001000000001
+.0000000000000001000000001
+1000.0000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+.00000000000010000000001
+.000000000000010000000001
+.0000000000000010000000001
+.00000000000000010000000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+.00000000000100000000001
+.000000000000100000000001
+.0000000000000100000000001
+.00000000000000100000000001
+.000000000000000100000000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+.00000000001000000000001
+.000000000001000000000001
+.0000000000001000000000001
+.00000000000001000000000001
+.000000000000001000000000001
+.0000000000000001000000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+.00000000010000000000001
+.000000000010000000000001
+.0000000000010000000000001
+.00000000000010000000000001
+.000000000000010000000000001
+.0000000000000010000000000001
+.00000000000000010000000000001
+10000
+1000.0
+100.00
+10.000
+1.0000
+.10000
+.010000
+.0010000
+.00010000
+.000010000
+.0000010000
+.00000010000
+.000000010000
+.0000000010000
+.00000000010000
+.000000000010000
+.0000000000010000
+.00000000000010000
+.000000000000010000
+.0000000000000010000
+10000.1
+1000.01
+100.001
+10.0001
+1.00001
+.100001
+.0100001
+.00100001
+.000100001
+.0000100001
+.00000100001
+.000000100001
+.0000000100001
+.00000000100001
+.000000000100001
+.0000000000100001
+.00000000000100001
+.000000000000100001
+.0000000000000100001
+.00000000000000100001
+10000.01
+1000.001
+100.0001
+10.00001
+1.000001
+.1000001
+.01000001
+.001000001
+.0001000001
+.00001000001
+.000001000001
+.0000001000001
+.00000001000001
+.000000001000001
+.0000000001000001
+.00000000001000001
+.000000000001000001
+.0000000000001000001
+.00000000000001000001
+.000000000000001000001
+10000.001
+1000.0001
+100.00001
+10.000001
+1.0000001
+.10000001
+.010000001
+.0010000001
+.00010000001
+.000010000001
+.0000010000001
+.00000010000001
+.000000010000001
+.0000000010000001
+.00000000010000001
+.000000000010000001
+.0000000000010000001
+.00000000000010000001
+.000000000000010000001
+.0000000000000010000001
+10000.0001
+1000.00001
+100.000001
+10.0000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+.000000000000100000001
+.0000000000000100000001
+.00000000000000100000001
+10000.00001
+1000.000001
+100.0000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+.0000000000001000000001
+.00000000000001000000001
+.000000000000001000000001
+10000.000001
+1000.0000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+.00000000000010000000001
+.000000000000010000000001
+.0000000000000010000000001
+10000.0000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+.00000000000100000000001
+.000000000000100000000001
+.0000000000000100000000001
+.00000000000000100000000001
+10000.00000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+.00000000001000000000001
+.000000000001000000000001
+.0000000000001000000000001
+.00000000000001000000000001
+.000000000000001000000000001
+10000.000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+.00000000010000000000001
+.000000000010000000000001
+.0000000000010000000000001
+.00000000000010000000000001
+.000000000000010000000000001
+.0000000000000010000000000001
+10000.0000000001
+1000.00000000001
+100.000000000001
+10.0000000000001
+1.00000000000001
+.100000000000001
+.0100000000000001
+.00100000000000001
+.000100000000000001
+.0000100000000000001
+.00000100000000000001
+.000000100000000000001
+.0000000100000000000001
+.00000000100000000000001
+.000000000100000000000001
+.0000000000100000000000001
+.00000000000100000000000001
+.000000000000100000000000001
+.0000000000000100000000000001
+.00000000000000100000000000001
+100000
+10000.0
+1000.00
+100.000
+10.0000
+1.00000
+.100000
+.0100000
+.00100000
+.000100000
+.0000100000
+.00000100000
+.000000100000
+.0000000100000
+.00000000100000
+.000000000100000
+.0000000000100000
+.00000000000100000
+.000000000000100000
+.0000000000000100000
+100000.1
+10000.01
+1000.001
+100.0001
+10.00001
+1.000001
+.1000001
+.01000001
+.001000001
+.0001000001
+.00001000001
+.000001000001
+.0000001000001
+.00000001000001
+.000000001000001
+.0000000001000001
+.00000000001000001
+.000000000001000001
+.0000000000001000001
+.00000000000001000001
+100000.01
+10000.001
+1000.0001
+100.00001
+10.000001
+1.0000001
+.10000001
+.010000001
+.0010000001
+.00010000001
+.000010000001
+.0000010000001
+.00000010000001
+.000000010000001
+.0000000010000001
+.00000000010000001
+.000000000010000001
+.0000000000010000001
+.00000000000010000001
+.000000000000010000001
+100000.001
+10000.0001
+1000.00001
+100.000001
+10.0000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+.000000000000100000001
+.0000000000000100000001
+100000.0001
+10000.00001
+1000.000001
+100.0000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+.0000000000001000000001
+.00000000000001000000001
+100000.00001
+10000.000001
+1000.0000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+.00000000000010000000001
+.000000000000010000000001
+100000.000001
+10000.0000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+.00000000000100000000001
+.000000000000100000000001
+.0000000000000100000000001
+100000.0000001
+10000.00000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+.00000000001000000000001
+.000000000001000000000001
+.0000000000001000000000001
+.00000000000001000000000001
+100000.00000001
+10000.000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+.00000000010000000000001
+.000000000010000000000001
+.0000000000010000000000001
+.00000000000010000000000001
+.000000000000010000000000001
+100000.000000001
+10000.0000000001
+1000.00000000001
+100.000000000001
+10.0000000000001
+1.00000000000001
+.100000000000001
+.0100000000000001
+.00100000000000001
+.000100000000000001
+.0000100000000000001
+.00000100000000000001
+.000000100000000000001
+.0000000100000000000001
+.00000000100000000000001
+.000000000100000000000001
+.0000000000100000000000001
+.00000000000100000000000001
+.000000000000100000000000001
+.0000000000000100000000000001
+100000.0000000001
+10000.00000000001
+1000.000000000001
+100.0000000000001
+10.00000000000001
+1.000000000000001
+.1000000000000001
+.01000000000000001
+.001000000000000001
+.0001000000000000001
+.00001000000000000001
+.000001000000000000001
+.0000001000000000000001
+.00000001000000000000001
+.000000001000000000000001
+.0000000001000000000000001
+.00000000001000000000000001
+.000000000001000000000000001
+.0000000000001000000000000001
+.00000000000001000000000000001
+1000000
+100000.0
+10000.00
+1000.000
+100.0000
+10.00000
+1.000000
+.1000000
+.01000000
+.001000000
+.0001000000
+.00001000000
+.000001000000
+.0000001000000
+.00000001000000
+.000000001000000
+.0000000001000000
+.00000000001000000
+.000000000001000000
+.0000000000001000000
+1000000.1
+100000.01
+10000.001
+1000.0001
+100.00001
+10.000001
+1.0000001
+.10000001
+.010000001
+.0010000001
+.00010000001
+.000010000001
+.0000010000001
+.00000010000001
+.000000010000001
+.0000000010000001
+.00000000010000001
+.000000000010000001
+.0000000000010000001
+.00000000000010000001
+1000000.01
+100000.001
+10000.0001
+1000.00001
+100.000001
+10.0000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+.000000000000100000001
+1000000.001
+100000.0001
+10000.00001
+1000.000001
+100.0000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+.0000000000001000000001
+1000000.0001
+100000.00001
+10000.000001
+1000.0000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+.00000000000010000000001
+1000000.00001
+100000.000001
+10000.0000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+.00000000000100000000001
+.000000000000100000000001
+1000000.000001
+100000.0000001
+10000.00000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+.00000000001000000000001
+.000000000001000000000001
+.0000000000001000000000001
+1000000.0000001
+100000.00000001
+10000.000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+.00000000010000000000001
+.000000000010000000000001
+.0000000000010000000000001
+.00000000000010000000000001
+1000000.00000001
+100000.000000001
+10000.0000000001
+1000.00000000001
+100.000000000001
+10.0000000000001
+1.00000000000001
+.100000000000001
+.0100000000000001
+.00100000000000001
+.000100000000000001
+.0000100000000000001
+.00000100000000000001
+.000000100000000000001
+.0000000100000000000001
+.00000000100000000000001
+.000000000100000000000001
+.0000000000100000000000001
+.00000000000100000000000001
+.000000000000100000000000001
+1000000.000000001
+100000.0000000001
+10000.00000000001
+1000.000000000001
+100.0000000000001
+10.00000000000001
+1.000000000000001
+.1000000000000001
+.01000000000000001
+.001000000000000001
+.0001000000000000001
+.00001000000000000001
+.000001000000000000001
+.0000001000000000000001
+.00000001000000000000001
+.000000001000000000000001
+.0000000001000000000000001
+.00000000001000000000000001
+.000000000001000000000000001
+.0000000000001000000000000001
+1000000.0000000001
+100000.00000000001
+10000.000000000001
+1000.0000000000001
+100.00000000000001
+10.000000000000001
+1.0000000000000001
+.10000000000000001
+.010000000000000001
+.0010000000000000001
+.00010000000000000001
+.000010000000000000001
+.0000010000000000000001
+.00000010000000000000001
+.000000010000000000000001
+.0000000010000000000000001
+.00000000010000000000000001
+.000000000010000000000000001
+.0000000000010000000000000001
+.00000000000010000000000000001
+10000000
+1000000.0
+100000.00
+10000.000
+1000.0000
+100.00000
+10.000000
+1.0000000
+.10000000
+.010000000
+.0010000000
+.00010000000
+.000010000000
+.0000010000000
+.00000010000000
+.000000010000000
+.0000000010000000
+.00000000010000000
+.000000000010000000
+.0000000000010000000
+10000000.1
+1000000.01
+100000.001
+10000.0001
+1000.00001
+100.000001
+10.0000001
+1.00000001
+.100000001
+.0100000001
+.00100000001
+.000100000001
+.0000100000001
+.00000100000001
+.000000100000001
+.0000000100000001
+.00000000100000001
+.000000000100000001
+.0000000000100000001
+.00000000000100000001
+10000000.01
+1000000.001
+100000.0001
+10000.00001
+1000.000001
+100.0000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+.000000000001000000001
+10000000.001
+1000000.0001
+100000.00001
+10000.000001
+1000.0000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+.0000000000010000000001
+10000000.0001
+1000000.00001
+100000.000001
+10000.0000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+.00000000000100000000001
+10000000.00001
+1000000.000001
+100000.0000001
+10000.00000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+.00000000001000000000001
+.000000000001000000000001
+10000000.000001
+1000000.0000001
+100000.00000001
+10000.000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+.00000000010000000000001
+.000000000010000000000001
+.0000000000010000000000001
+10000000.0000001
+1000000.00000001
+100000.000000001
+10000.0000000001
+1000.00000000001
+100.000000000001
+10.0000000000001
+1.00000000000001
+.100000000000001
+.0100000000000001
+.00100000000000001
+.000100000000000001
+.0000100000000000001
+.00000100000000000001
+.000000100000000000001
+.0000000100000000000001
+.00000000100000000000001
+.000000000100000000000001
+.0000000000100000000000001
+.00000000000100000000000001
+10000000.00000001
+1000000.000000001
+100000.0000000001
+10000.00000000001
+1000.000000000001
+100.0000000000001
+10.00000000000001
+1.000000000000001
+.1000000000000001
+.01000000000000001
+.001000000000000001
+.0001000000000000001
+.00001000000000000001
+.000001000000000000001
+.0000001000000000000001
+.00000001000000000000001
+.000000001000000000000001
+.0000000001000000000000001
+.00000000001000000000000001
+.000000000001000000000000001
+10000000.000000001
+1000000.0000000001
+100000.00000000001
+10000.000000000001
+1000.0000000000001
+100.00000000000001
+10.000000000000001
+1.0000000000000001
+.10000000000000001
+.010000000000000001
+.0010000000000000001
+.00010000000000000001
+.000010000000000000001
+.0000010000000000000001
+.00000010000000000000001
+.000000010000000000000001
+.0000000010000000000000001
+.00000000010000000000000001
+.000000000010000000000000001
+.0000000000010000000000000001
+10000000.0000000001
+1000000.00000000001
+100000.000000000001
+10000.0000000000001
+1000.00000000000001
+100.000000000000001
+10.0000000000000001
+1.00000000000000001
+.100000000000000001
+.0100000000000000001
+.00100000000000000001
+.000100000000000000001
+.0000100000000000000001
+.00000100000000000000001
+.000000100000000000000001
+.0000000100000000000000001
+.00000000100000000000000001
+.000000000100000000000000001
+.0000000000100000000000000001
+.00000000000100000000000000001
+100000000
+10000000.0
+1000000.00
+100000.000
+10000.0000
+1000.00000
+100.000000
+10.0000000
+1.00000000
+.100000000
+.0100000000
+.00100000000
+.000100000000
+.0000100000000
+.00000100000000
+.000000100000000
+.0000000100000000
+.00000000100000000
+.000000000100000000
+.0000000000100000000
+100000000.1
+10000000.01
+1000000.001
+100000.0001
+10000.00001
+1000.000001
+100.0000001
+10.00000001
+1.000000001
+.1000000001
+.01000000001
+.001000000001
+.0001000000001
+.00001000000001
+.000001000000001
+.0000001000000001
+.00000001000000001
+.000000001000000001
+.0000000001000000001
+.00000000001000000001
+100000000.01
+10000000.001
+1000000.0001
+100000.00001
+10000.000001
+1000.0000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+.000000000010000000001
+100000000.001
+10000000.0001
+1000000.00001
+100000.000001
+10000.0000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+.0000000000100000000001
+100000000.0001
+10000000.00001
+1000000.000001
+100000.0000001
+10000.00000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+.00000000001000000000001
+100000000.00001
+10000000.000001
+1000000.0000001
+100000.00000001
+10000.000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+.00000000010000000000001
+.000000000010000000000001
+100000000.000001
+10000000.0000001
+1000000.00000001
+100000.000000001
+10000.0000000001
+1000.00000000001
+100.000000000001
+10.0000000000001
+1.00000000000001
+.100000000000001
+.0100000000000001
+.00100000000000001
+.000100000000000001
+.0000100000000000001
+.00000100000000000001
+.000000100000000000001
+.0000000100000000000001
+.00000000100000000000001
+.000000000100000000000001
+.0000000000100000000000001
+100000000.0000001
+10000000.00000001
+1000000.000000001
+100000.0000000001
+10000.00000000001
+1000.000000000001
+100.0000000000001
+10.00000000000001
+1.000000000000001
+.1000000000000001
+.01000000000000001
+.001000000000000001
+.0001000000000000001
+.00001000000000000001
+.000001000000000000001
+.0000001000000000000001
+.00000001000000000000001
+.000000001000000000000001
+.0000000001000000000000001
+.00000000001000000000000001
+100000000.00000001
+10000000.000000001
+1000000.0000000001
+100000.00000000001
+10000.000000000001
+1000.0000000000001
+100.00000000000001
+10.000000000000001
+1.0000000000000001
+.10000000000000001
+.010000000000000001
+.0010000000000000001
+.00010000000000000001
+.000010000000000000001
+.0000010000000000000001
+.00000010000000000000001
+.000000010000000000000001
+.0000000010000000000000001
+.00000000010000000000000001
+.000000000010000000000000001
+100000000.000000001
+10000000.0000000001
+1000000.00000000001
+100000.000000000001
+10000.0000000000001
+1000.00000000000001
+100.000000000000001
+10.0000000000000001
+1.00000000000000001
+.100000000000000001
+.0100000000000000001
+.00100000000000000001
+.000100000000000000001
+.0000100000000000000001
+.00000100000000000000001
+.000000100000000000000001
+.0000000100000000000000001
+.00000000100000000000000001
+.000000000100000000000000001
+.0000000000100000000000000001
+100000000.0000000001
+10000000.00000000001
+1000000.000000000001
+100000.0000000000001
+10000.00000000000001
+1000.000000000000001
+100.0000000000000001
+10.00000000000000001
+1.000000000000000001
+.1000000000000000001
+.01000000000000000001
+.001000000000000000001
+.0001000000000000000001
+.00001000000000000000001
+.000001000000000000000001
+.0000001000000000000000001
+.00000001000000000000000001
+.000000001000000000000000001
+.0000000001000000000000000001
+.00000000001000000000000000001
+1000000000
+100000000.0
+10000000.00
+1000000.000
+100000.0000
+10000.00000
+1000.000000
+100.0000000
+10.00000000
+1.000000000
+.1000000000
+.01000000000
+.001000000000
+.0001000000000
+.00001000000000
+.000001000000000
+.0000001000000000
+.00000001000000000
+.000000001000000000
+.0000000001000000000
+1000000000.1
+100000000.01
+10000000.001
+1000000.0001
+100000.00001
+10000.000001
+1000.0000001
+100.00000001
+10.000000001
+1.0000000001
+.10000000001
+.010000000001
+.0010000000001
+.00010000000001
+.000010000000001
+.0000010000000001
+.00000010000000001
+.000000010000000001
+.0000000010000000001
+.00000000010000000001
+1000000000.01
+100000000.001
+10000000.0001
+1000000.00001
+100000.000001
+10000.0000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+.000000000100000000001
+1000000000.001
+100000000.0001
+10000000.00001
+1000000.000001
+100000.0000001
+10000.00000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+.0000000001000000000001
+1000000000.0001
+100000000.00001
+10000000.000001
+1000000.0000001
+100000.00000001
+10000.000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+.00000000010000000000001
+1000000000.00001
+100000000.000001
+10000000.0000001
+1000000.00000001
+100000.000000001
+10000.0000000001
+1000.00000000001
+100.000000000001
+10.0000000000001
+1.00000000000001
+.100000000000001
+.0100000000000001
+.00100000000000001
+.000100000000000001
+.0000100000000000001
+.00000100000000000001
+.000000100000000000001
+.0000000100000000000001
+.00000000100000000000001
+.000000000100000000000001
+1000000000.000001
+100000000.0000001
+10000000.00000001
+1000000.000000001
+100000.0000000001
+10000.00000000001
+1000.000000000001
+100.0000000000001
+10.00000000000001
+1.000000000000001
+.1000000000000001
+.01000000000000001
+.001000000000000001
+.0001000000000000001
+.00001000000000000001
+.000001000000000000001
+.0000001000000000000001
+.00000001000000000000001
+.000000001000000000000001
+.0000000001000000000000001
+1000000000.0000001
+100000000.00000001
+10000000.000000001
+1000000.0000000001
+100000.00000000001
+10000.000000000001
+1000.0000000000001
+100.00000000000001
+10.000000000000001
+1.0000000000000001
+.10000000000000001
+.010000000000000001
+.0010000000000000001
+.00010000000000000001
+.000010000000000000001
+.0000010000000000000001
+.00000010000000000000001
+.000000010000000000000001
+.0000000010000000000000001
+.00000000010000000000000001
+1000000000.00000001
+100000000.000000001
+10000000.0000000001
+1000000.00000000001
+100000.000000000001
+10000.0000000000001
+1000.00000000000001
+100.000000000000001
+10.0000000000000001
+1.00000000000000001
+.100000000000000001
+.0100000000000000001
+.00100000000000000001
+.000100000000000000001
+.0000100000000000000001
+.00000100000000000000001
+.000000100000000000000001
+.0000000100000000000000001
+.00000000100000000000000001
+.000000000100000000000000001
+1000000000.000000001
+100000000.0000000001
+10000000.00000000001
+1000000.000000000001
+100000.0000000000001
+10000.00000000000001
+1000.000000000000001
+100.0000000000000001
+10.00000000000000001
+1.000000000000000001
+.1000000000000000001
+.01000000000000000001
+.001000000000000000001
+.0001000000000000000001
+.00001000000000000000001
+.000001000000000000000001
+.0000001000000000000000001
+.00000001000000000000000001
+.000000001000000000000000001
+.0000000001000000000000000001
+1000000000.0000000001
+100000000.00000000001
+10000000.000000000001
+1000000.0000000000001
+100000.00000000000001
+10000.000000000000001
+1000.0000000000000001
+100.00000000000000001
+10.000000000000000001
+1.0000000000000000001
+.10000000000000000001
+.010000000000000000001
+.0010000000000000000001
+.00010000000000000000001
+.000010000000000000000001
+.0000010000000000000000001
+.00000010000000000000000001
+.000000010000000000000000001
+.0000000010000000000000000001
+.00000000010000000000000000001
+10000000000
+1000000000.0
+100000000.00
+10000000.000
+1000000.0000
+100000.00000
+10000.000000
+1000.0000000
+100.00000000
+10.000000000
+1.0000000000
+.10000000000
+.010000000000
+.0010000000000
+.00010000000000
+.000010000000000
+.0000010000000000
+.00000010000000000
+.000000010000000000
+.0000000010000000000
+10000000000.1
+1000000000.01
+100000000.001
+10000000.0001
+1000000.00001
+100000.000001
+10000.0000001
+1000.00000001
+100.000000001
+10.0000000001
+1.00000000001
+.100000000001
+.0100000000001
+.00100000000001
+.000100000000001
+.0000100000000001
+.00000100000000001
+.000000100000000001
+.0000000100000000001
+.00000000100000000001
+10000000000.01
+1000000000.001
+100000000.0001
+10000000.00001
+1000000.000001
+100000.0000001
+10000.00000001
+1000.000000001
+100.0000000001
+10.00000000001
+1.000000000001
+.1000000000001
+.01000000000001
+.001000000000001
+.0001000000000001
+.00001000000000001
+.000001000000000001
+.0000001000000000001
+.00000001000000000001
+.000000001000000000001
+10000000000.001
+1000000000.0001
+100000000.00001
+10000000.000001
+1000000.0000001
+100000.00000001
+10000.000000001
+1000.0000000001
+100.00000000001
+10.000000000001
+1.0000000000001
+.10000000000001
+.010000000000001
+.0010000000000001
+.00010000000000001
+.000010000000000001
+.0000010000000000001
+.00000010000000000001
+.000000010000000000001
+.0000000010000000000001
+10000000000.0001
+1000000000.00001
+100000000.000001
+10000000.0000001
+1000000.00000001
+100000.000000001
+10000.0000000001
+1000.00000000001
+100.000000000001
+10.0000000000001
+1.00000000000001
+.100000000000001
+.0100000000000001
+.00100000000000001
+.000100000000000001
+.0000100000000000001
+.00000100000000000001
+.000000100000000000001
+.0000000100000000000001
+.00000000100000000000001
+10000000000.00001
+1000000000.000001
+100000000.0000001
+10000000.00000001
+1000000.000000001
+100000.0000000001
+10000.00000000001
+1000.000000000001
+100.0000000000001
+10.00000000000001
+1.000000000000001
+.1000000000000001
+.01000000000000001
+.001000000000000001
+.0001000000000000001
+.00001000000000000001
+.000001000000000000001
+.0000001000000000000001
+.00000001000000000000001
+.000000001000000000000001
+10000000000.000001
+1000000000.0000001
+100000000.00000001
+10000000.000000001
+1000000.0000000001
+100000.00000000001
+10000.000000000001
+1000.0000000000001
+100.00000000000001
+10.000000000000001
+1.0000000000000001
+.10000000000000001
+.010000000000000001
+.0010000000000000001
+.00010000000000000001
+.000010000000000000001
+.0000010000000000000001
+.00000010000000000000001
+.000000010000000000000001
+.0000000010000000000000001
+10000000000.0000001
+1000000000.00000001
+100000000.000000001
+10000000.0000000001
+1000000.00000000001
+100000.000000000001
+10000.0000000000001
+1000.00000000000001
+100.000000000000001
+10.0000000000000001
+1.00000000000000001
+.100000000000000001
+.0100000000000000001
+.00100000000000000001
+.000100000000000000001
+.0000100000000000000001
+.00000100000000000000001
+.000000100000000000000001
+.0000000100000000000000001
+.00000000100000000000000001
+10000000000.00000001
+1000000000.000000001
+100000000.0000000001
+10000000.00000000001
+1000000.000000000001
+100000.0000000000001
+10000.00000000000001
+1000.000000000000001
+100.0000000000000001
+10.00000000000000001
+1.000000000000000001
+.1000000000000000001
+.01000000000000000001
+.001000000000000000001
+.0001000000000000000001
+.00001000000000000000001
+.000001000000000000000001
+.0000001000000000000000001
+.00000001000000000000000001
+.000000001000000000000000001
+10000000000.000000001
+1000000000.0000000001
+100000000.00000000001
+10000000.000000000001
+1000000.0000000000001
+100000.00000000000001
+10000.000000000000001
+1000.0000000000000001
+100.00000000000000001
+10.000000000000000001
+1.0000000000000000001
+.10000000000000000001
+.010000000000000000001
+.0010000000000000000001
+.00010000000000000000001
+.000010000000000000000001
+.0000010000000000000000001
+.00000010000000000000000001
+.000000010000000000000000001
+.0000000010000000000000000001
+10000000000.0000000001
+1000000000.00000000001
+100000000.000000000001
+10000000.0000000000001
+1000000.00000000000001
+100000.000000000000001
+10000.0000000000000001
+1000.00000000000000001
+100.000000000000000001
+10.0000000000000000001
+1.00000000000000000001
+.100000000000000000001
+.0100000000000000000001
+.00100000000000000000001
+.000100000000000000000001
+.0000100000000000000000001
+.00000100000000000000000001
+.000000100000000000000000001
+.0000000100000000000000000001
+.00000000100000000000000000001
diff --git a/contrib/bc/tests/bc/sine.txt b/contrib/bc/tests/bc/sine.txt
new file mode 100644
index 000000000000..d3a547bcd796
--- /dev/null
+++ b/contrib/bc/tests/bc/sine.txt
@@ -0,0 +1,207 @@
+scale = 25
+p = 4 * a(1)
+scale = 20
+s(0)
+s(0.5)
+s(1)
+s(2)
+s(3)
+s(-0.5)
+s(-1)
+s(-2)
+s(-3)
+s(p / 7)
+s(-p / 7)
+s(p / 4)
+s(-p / 4)
+s(p / 3)
+s(-p / 3)
+s(p / 2)
+s(-p / 2)
+s(3 * p / 4)
+s(3 * -p / 4)
+s(p)
+s(-p)
+s(3 * p / 2)
+s(3 * -p / 2)
+s(7 * p / 4)
+s(7 * -p / 4)
+s(13 * p / 4)
+s(13 * -p / 4)
+s(2 * p)
+s(2 * -p)
+s(131231)
+s(-131231)
+s(69.1967507777)
+s(10828)
+s(-16248506.847013148)
+s(2050281000)
+s(8224939)
+s(11334231.1154662464)
+s(-4109411249.2986954846)
+s(-2395915402.13984)
+s(-2795874313)
+s(-2262647256)
+s(3323158182.1239222084)
+s(99901384)
+s(-4202726050.2780080957)
+s(2870000621.3228830588)
+s(-4230239450.981045150)
+s(-1517506941.2678857223)
+s(4004582176)
+s(-4193724543.1108508063)
+s(-3432511261)
+s(1804484812)
+s(3229084127)
+s(-3565317246.583937244)
+s(3503281621)
+s(-3469146313.1766891244)
+s(-2257308049.307721068)
+s(-3978441809)
+s(3431564304.3752537)
+s(1249644440.2464914559)
+s(2395558891.1188487974)
+s(-2607820706.4079280116)
+s(1208310007)
+s(-3758597557.863203175)
+s(1186920672)
+s(-3988103872)
+s(-4280635328.4194857577)
+s(1051748072)
+s(-1884006279)
+s(-1046568719.2698663389)
+s(2482991410)
+s(-2106101268.1154045959)
+s(3530359346.77217900)
+s(-3373362543)
+s(2601598062)
+s(2987020862)
+s(-12033356.2057140648)
+s(-3721760707)
+s(2842387705.4145759704)
+s(3515832681.1808393297)
+s(-3658522034.16149)
+s(3963658030.2860423992)
+s(2977802215.597946655)
+s(-4271392570.4091498761)
+s(2378692585)
+s(-3545193743.629374782)
+s(-1762458738)
+s(-1174277828.4264040126)
+s(-1724994857)
+s(2802750230.1783499408)
+s(-3068133550)
+s(3324811474.621822235)
+s(2873024984)
+s(-3509056632.3888206298)
+s(1772903162.647192879)
+s(2836543102)
+s(4117858580.186)
+s(2988632386.4063754522)
+s(-4256784971.1770067447)
+s(2280820447)
+s(-2865200306)
+s(-3329592486)
+s(519126268)
+s(-2452430452)
+s(-2693220186.62104082)
+s(-3796811992.14485798)
+s(3619792326)
+s(2697791049.3038381550)
+s(3751267834.2808166557)
+s(-3761719074)
+s(-3824087631)
+s(2119301150)
+s(1398148974)
+s(-3386564819.1351816969)
+s(-3171483098)
+s(3688944941.3273318162)
+s(3060521119)
+s(-3527110404)
+s(3699631193)
+s(3872838898)
+s(3880350192)
+s(-4109411249.2986954846)
+s(-2395915402.13984)
+s(-2795874313)
+s(-2262647256)
+s(3323158182.1239222084)
+s(99901384)
+s(-4202726050.2780080957)
+s(2870000621.3228830588)
+s(-4230239450.981045150)
+s(-1517506941.2678857223)
+s(4004582176)
+s(-4193724543.1108508063)
+s(-3432511261)
+s(1804484812)
+s(3229084127)
+s(-3565317246.583937244)
+s(3503281621)
+s(-3469146313.1766891244)
+s(-2257308049.307721068)
+s(-3978441809)
+s(3431564304.3752537)
+s(1249644440.2464914559)
+s(2395558891.1188487974)
+s(-2607820706.4079280116)
+s(1208310007)
+s(-3758597557.863203175)
+s(1186920672)
+s(-3988103872)
+s(-4280635328.4194857577)
+s(1051748072)
+s(-1884006279)
+s(-1046568719.2698663389)
+s(2482991410)
+s(-2106101268.1154045959)
+s(3530359346.77217900)
+s(-3373362543)
+s(2601598062)
+s(2576349783.2446436039)
+s(2987020862)
+s(-12033356.2057140648)
+s(-3721760707)
+s(2842387705.4145759704)
+s(3515832681.1808393297)
+s(-3658522034.16149)
+s(3963658030.2860423992)
+s(2977802215.597946655)
+s(-4271392570.4091498761)
+s(2378692585)
+s(-3545193743.629374782)
+s(-1762458738)
+s(-1174277828.4264040126)
+s(-1724994857)
+s(2802750230.1783499408)
+s(-3068133550)
+s(3324811474.621822235)
+s(2873024984)
+s(-3509056632.3888206298)
+s(1772903162.647192879)
+s(2836543102)
+s(4117858580.186)
+s(2988632386.4063754522)
+s(-4256784971.1770067447)
+s(2280820447)
+s(-2865200306)
+s(-3329592486)
+s(519126268)
+s(-2452430452)
+s(-2693220186.62104082)
+s(-3796811992.14485798)
+s(3619792326)
+s(2697791049.3038381550)
+s(3751267834.2808166557)
+s(-3761719074)
+s(-3824087631)
+s(2119301150)
+s(1398148974)
+s(-3386564819.1351816969)
+s(-3171483098)
+s(3688944941.3273318162)
+s(3060521119)
+s(-3527110404)
+s(3699631193)
+s(3872838898)
+s(3880350192)
diff --git a/contrib/bc/tests/bc/sine_results.txt b/contrib/bc/tests/bc/sine_results.txt
new file mode 100644
index 000000000000..7a4a1ab0cbc4
--- /dev/null
+++ b/contrib/bc/tests/bc/sine_results.txt
@@ -0,0 +1,204 @@
+0
+.47942553860420300027
+.84147098480789650665
+.90929742682568169539
+.14112000805986722210
+-.47942553860420300027
+-.84147098480789650665
+-.90929742682568169539
+-.14112000805986722210
+.43388373911755812047
+-.43388373911755812047
+.70710678118654752439
+-.70710678118654752439
+.86602540378443864676
+-.86602540378443864676
+1.00000000000000000000
+-1.00000000000000000000
+.70710678118654752440
+-.70710678118654752440
+0
+0
+-1.00000000000000000000
+1.00000000000000000000
+-.70710678118654752440
+.70710678118654752440
+-.70710678118654752439
+.70710678118654752439
+0
+0
+.38173640790989719211
+-.38173640790989719211
+.08162149793819434415
+.87714140586973771462
+-.91157035998052051623
+-.69638975047120679880
+-.94806056135672896231
+-.54548669379730874215
+.14605234154783145589
+-.12183062787430962391
+-.89832305526331682409
+-.99513029384033555290
+.76528428398894958149
+.51077956237618482050
+-.75908868040685122962
+-.37015497140201575652
+-.51432535569032144654
+.68890201397514289831
+.88200006249578882510
+-.01188893762444044480
+-.55298206739629427055
+-.39165958853437135625
+.17732674488831117445
+-.09648816960119759281
+.15728984163381104344
+-.31554983227150461370
+-.72225704678824601977
+.96170480789326775287
+-.47636475887571231114
+-.98999375714278585763
+-.06715264746977580303
+-.69464867397161089634
+.58037673122614640119
+-.44244898040675115062
+.04242496278231069061
+.96417934585711006987
+-.54513053517818430563
+-.28604677908958958915
+-.68003854521180919710
+.26597321569379963920
+-.34591048991595943570
+-.17084074152217894535
+-.42880744669595980174
+.36518031021580667844
+-.03514839609475800827
+.93891962312087620513
+-.69421849362562852947
+.15169857474887222961
+-.00226070393499995347
+.96209233301706432156
+-.79937182245558378826
+.99966966326862290520
+.85234799672007656117
+-.20824280061137520443
+-.00761257856348159450
+.10708922858398661064
+-.80233147080821341443
+.26521358383069223461
+-.95173930946495828679
+.66210405748455769256
+.30054820568403786217
+.21640593048970779808
+-.87596287572245980692
+.74627849623707962934
+-.25747200288605259984
+-.14700538617135227740
+-.06294254604551440990
+.67948313824962059899
+.83714389089726798409
+.33805040346429707760
+.80273418514828673749
+.72262501870089953244
+-.77469383027517310713
+-.15575896025754423345
+.22191568853026376075
+.25137052589938954082
+-.80534308288073574163
+-.44963537508211028805
+-.92368907556208259630
+-.80963411623457804531
+-.96822928101198069490
+-.46604999828123759716
+.63275578793565409192
+-.40563425346575205109
+.13095444406203282638
+.96217617474547242151
+-.16256793375739137005
+.71791623784197898982
+-.10713685791219679248
+.50758780541979250307
+-.09795373670371402656
+.14605234154783145589
+-.12183062787430962391
+-.89832305526331682409
+-.99513029384033555290
+.76528428398894958149
+.51077956237618482050
+-.75908868040685122962
+-.37015497140201575652
+-.51432535569032144654
+.68890201397514289831
+.88200006249578882510
+-.01188893762444044480
+-.55298206739629427055
+-.39165958853437135625
+.17732674488831117445
+-.09648816960119759281
+.15728984163381104344
+-.31554983227150461370
+-.72225704678824601977
+.96170480789326775287
+-.47636475887571231114
+-.98999375714278585763
+-.06715264746977580303
+-.69464867397161089634
+.58037673122614640119
+-.44244898040675115062
+.04242496278231069061
+.96417934585711006987
+-.54513053517818430563
+-.28604677908958958915
+-.68003854521180919710
+.26597321569379963920
+-.34591048991595943570
+-.17084074152217894535
+-.42880744669595980174
+.36518031021580667844
+-.03514839609475800827
+.75884554410943292265
+.93891962312087620513
+-.69421849362562852947
+.15169857474887222961
+-.00226070393499995347
+.96209233301706432156
+-.79937182245558378826
+.99966966326862290520
+.85234799672007656117
+-.20824280061137520443
+-.00761257856348159450
+.10708922858398661064
+-.80233147080821341443
+.26521358383069223461
+-.95173930946495828679
+.66210405748455769256
+.30054820568403786217
+.21640593048970779808
+-.87596287572245980692
+.74627849623707962934
+-.25747200288605259984
+-.14700538617135227740
+-.06294254604551440990
+.67948313824962059899
+.83714389089726798409
+.33805040346429707760
+.80273418514828673749
+.72262501870089953244
+-.77469383027517310713
+-.15575896025754423345
+.22191568853026376075
+.25137052589938954082
+-.80534308288073574163
+-.44963537508211028805
+-.92368907556208259630
+-.80963411623457804531
+-.96822928101198069490
+-.46604999828123759716
+.63275578793565409192
+-.40563425346575205109
+.13095444406203282638
+.96217617474547242151
+-.16256793375739137005
+.71791623784197898982
+-.10713685791219679248
+.50758780541979250307
+-.09795373670371402656
diff --git a/contrib/bc/tests/bc/sqrt.txt b/contrib/bc/tests/bc/sqrt.txt
new file mode 100644
index 000000000000..afd87ff0f6e6
--- /dev/null
+++ b/contrib/bc/tests/bc/sqrt.txt
@@ -0,0 +1,18 @@
+scale = 20
+sqrt(0)
+sqrt(2)
+sqrt(4)
+sqrt(9)
+sqrt(16)
+sqrt(25)
+sqrt(121)
+sqrt(48765)
+sqrt(9287356207356)
+sqrt(0.189274385967238956872354)
+sqrt(12389467137496823.134567829387456283946)
+sqrt(.0000000000000000000000000000123)
+sqrt(1)
+scale = 0;
+sqrt(1407)
+sqrt(79101)
+scale = 6; sqrt(88.1247699921300025847737099094480986051698668662822009535526240)
diff --git a/contrib/bc/tests/bc/sqrt_results.txt b/contrib/bc/tests/bc/sqrt_results.txt
new file mode 100644
index 000000000000..10a4fa95d5a5
--- /dev/null
+++ b/contrib/bc/tests/bc/sqrt_results.txt
@@ -0,0 +1,16 @@
+0
+1.41421356237309504880
+2.00000000000000000000
+3.00000000000000000000
+4.00000000000000000000
+5.00000000000000000000
+11.00000000000000000000
+220.82798735667542192643
+3047516.39985021245496456781
+.435056761776252544285578
+111307983.260397019622398608908
+.0000000000000035071355833500363
+1.00000000000000000000
+37
+281
+9.3874794269883757005315658512340070115147163425837869223395574
diff --git a/contrib/bc/tests/bc/stdin.txt b/contrib/bc/tests/bc/stdin.txt
new file mode 100644
index 000000000000..c9d12a6e4839
--- /dev/null
+++ b/contrib/bc/tests/bc/stdin.txt
@@ -0,0 +1,16 @@
+#stuff
+# "string in a hash comment"
+# /* comment in a hash comment */
+1 /* c */ + 2
+"String /* with partial comment"
+"String /* with full comment */"
+1 /* Comment with partial "string */ + 2
+2 /* Comment with full "string" */ + 3
+3 /* Comment with a # hash comment */ + 4
+"String with a # hash comment"
+1 + \
+2
+i = 4
+read()
+i *= 5
+if (1 < 3) 1
diff --git a/contrib/bc/tests/bc/stdin1.txt b/contrib/bc/tests/bc/stdin1.txt
new file mode 100644
index 000000000000..3721c265baa2
--- /dev/null
+++ b/contrib/bc/tests/bc/stdin1.txt
@@ -0,0 +1,2 @@
+if (1 < 3)
+ if (2 < 3) 1
diff --git a/contrib/bc/tests/bc/stdin1_results.txt b/contrib/bc/tests/bc/stdin1_results.txt
new file mode 100644
index 000000000000..d00491fd7e5b
--- /dev/null
+++ b/contrib/bc/tests/bc/stdin1_results.txt
@@ -0,0 +1 @@
+1
diff --git a/contrib/bc/tests/bc/stdin2.txt b/contrib/bc/tests/bc/stdin2.txt
new file mode 100644
index 000000000000..f260cfa7dbcf
--- /dev/null
+++ b/contrib/bc/tests/bc/stdin2.txt
@@ -0,0 +1 @@
+for (i = 0; i < 3; ++i) if (2 < 3) 1
diff --git a/contrib/bc/tests/bc/stdin2_results.txt b/contrib/bc/tests/bc/stdin2_results.txt
new file mode 100644
index 000000000000..e8183f05f5db
--- /dev/null
+++ b/contrib/bc/tests/bc/stdin2_results.txt
@@ -0,0 +1,3 @@
+1
+1
+1
diff --git a/contrib/bc/tests/bc/stdin_results.txt b/contrib/bc/tests/bc/stdin_results.txt
new file mode 100644
index 000000000000..298fdddff604
--- /dev/null
+++ b/contrib/bc/tests/bc/stdin_results.txt
@@ -0,0 +1,7 @@
+3
+String /* with partial commentString /* with full comment */3
+5
+7
+String with a # hash comment3
+20
+1
diff --git a/contrib/bc/tests/bc/strings.txt b/contrib/bc/tests/bc/strings.txt
new file mode 100644
index 000000000000..8de9901d064c
--- /dev/null
+++ b/contrib/bc/tests/bc/strings.txt
@@ -0,0 +1,16 @@
+"string"
+"another string"
+"yet
+another
+string"
+"noescapes\n"
+"newline
+"
+print "string"
+print "newline\n"
+
+print "\\\e\n"
+print "\d\n"
+"abc\\
+def
+"
diff --git a/contrib/bc/tests/bc/strings_results.txt b/contrib/bc/tests/bc/strings_results.txt
new file mode 100644
index 000000000000..7e1646f03872
--- /dev/null
+++ b/contrib/bc/tests/bc/strings_results.txt
@@ -0,0 +1,8 @@
+stringanother stringyet
+another
+stringnoescapes\nnewline
+stringnewline
+\\
+\d
+abc\\
+def
diff --git a/contrib/bc/tests/bc/subtract.txt b/contrib/bc/tests/bc/subtract.txt
new file mode 100644
index 000000000000..e3ea1ced9ec5
--- /dev/null
+++ b/contrib/bc/tests/bc/subtract.txt
@@ -0,0 +1,153 @@
+0 - 0
+0 - 1
+1 - 0
+1 - 1
+5 - 2
+2 - 9
+321974 - 12845976238457
+2874519803456710938465 - 384723854
+10000000000000000000000000000000000000000 - 999999999999999999999999999999999999999
+10000000000000000000000000000000000000000 - 9999999999999999999999999999999999999999
+10000000000000000000000000000000000000000 - 999999999999999999999999999999999999999.99999999999999999999999999999999999
+10000000000000000000000000000000000000000 - 9999999999999999999999999999999999999999.9999999999999999999999999999999999
+10000000000000000000000000000000000000000 - 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+10000000000000000000000000000000000000001 - 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+10000000000000000000000000000000000000000.0000000001 - 0.0000000000000000000000000000000000000000000000000000000000000000000000000001
+-2 - 6
+-23784692345 - 182934721309467230894628735496027345
+-224352354962873059862 - -1245723576829456278354960278345
+-3468273598 - -12354243
+-0.92345768293 - -2354768923
+-712384634.123476823 - -24768293376
+-1879234638 - -0.917234869234
+-0.9172438692134 - -0.971284967124
+-0.1283475123465 - -0.937462346
+-124765829346.2837468293562 - -0.923467829346
+-12476829385769 - -1928476259034.8378629356
+-0.38476284395876345 - -94875394587623.2357869324857
+-4674596708467.34754789403674343567 - -48672394852354698.237548629345
+979519669 - 3018100865
+929002449 - 3280677283
+0 - -525898
+3- - -3
+18297034019823741908237410928374.81920734712098347109281029873 - 182907.12809
+182039471029834 - 282039471029834
+282039471029834 - 182039471029834
+182039471029834.2801722893 - 282039471029834
+282039471029834.2801722893 - 182039471029834
+182039471029834.2801722893 - 282039471029834.2838
+282039471029834.2801722893 - 182039471029834.2838
+182039471029834 - 282039471029834.2801722893
+282039471029834 - 182039471029834.2801722893
+182039471029834.8297282893 - 282039471029834.2801722893
+282039471029834.8297282893 - 182039471029834.2801722893
+471029834 - 282039471029834
+471029834 - 182039471029834
+471029834.2801722893 - 282039471029834
+471029834.2801722893 - 182039471029834
+471029834.2801722893 - 282039471029834.2838
+471029834.2801722893 - 182039471029834.2838
+471029834 - 282039471029834.2801722893
+471029834 - 182039471029834.2801722893
+471029834.8297282893 - 282039471029834.2801722893
+471029834.8297282893 - 182039471029834.2801722893
+182039471029834 - 471029834
+282039471029834 - 471029834
+182039471029834.2801722893 - 471029834
+282039471029834.2801722893 - 471029834
+182039471029834.2801722893 - 471029834.2838
+282039471029834.2801722893 - 471029834.2838
+182039471029834 - 471029834.2801722893
+282039471029834 - 471029834.2801722893
+182039471029834.8297282893 - 471029834.2801722893
+282039471029834.8297282893 - 471029834.2801722893
+-182039471029834 - 282039471029834
+-282039471029834 - 182039471029834
+-182039471029834.2801722893 - 282039471029834
+-282039471029834.2801722893 - 182039471029834
+-182039471029834.2801722893 - 282039471029834.2838
+-282039471029834.2801722893 - 182039471029834.2838
+-182039471029834 - 282039471029834.2801722893
+-282039471029834 - 182039471029834.2801722893
+-182039471029834.8297282893 - 282039471029834.2801722893
+-282039471029834.8297282893 - 182039471029834.2801722893
+-471029834 - 282039471029834
+-471029834 - 182039471029834
+-471029834.2801722893 - 282039471029834
+-471029834.2801722893 - 182039471029834
+-471029834.2801722893 - 282039471029834.2838
+-471029834.2801722893 - 182039471029834.2838
+-471029834 - 282039471029834.2801722893
+-471029834 - 182039471029834.2801722893
+-471029834.8297282893 - 282039471029834.2801722893
+-471029834.8297282893 - 182039471029834.2801722893
+-182039471029834 - 471029834
+-282039471029834 - 471029834
+-182039471029834.2801722893 - 471029834
+-282039471029834.2801722893 - 471029834
+-182039471029834.2801722893 - 471029834.2838
+-282039471029834.2801722893 - 471029834.2838
+-182039471029834 - 471029834.2801722893
+-282039471029834 - 471029834.2801722893
+-182039471029834.8297282893 - 471029834.2801722893
+-282039471029834.8297282893 - 471029834.2801722893
+182039471029834 - -282039471029834
+282039471029834 - -182039471029834
+182039471029834.2801722893 - -282039471029834
+282039471029834.2801722893 - -182039471029834
+182039471029834.2801722893 - -282039471029834.2838
+282039471029834.2801722893 - -182039471029834.2838
+182039471029834 - -282039471029834.2801722893
+282039471029834 - -182039471029834.2801722893
+182039471029834.8297282893 - -282039471029834.2801722893
+282039471029834.8297282893 - -182039471029834.2801722893
+471029834 - -282039471029834
+471029834 - -182039471029834
+471029834.2801722893 - -282039471029834
+471029834.2801722893 - -182039471029834
+471029834.2801722893 - -282039471029834.2838
+471029834.2801722893 - -182039471029834.2838
+471029834 - -282039471029834.2801722893
+471029834 - -182039471029834.2801722893
+471029834.8297282893 - -282039471029834.2801722893
+471029834.8297282893 - -182039471029834.2801722893
+182039471029834 - -471029834
+282039471029834 - -471029834
+182039471029834.2801722893 - -471029834
+282039471029834.2801722893 - -471029834
+182039471029834.2801722893 - -471029834.2838
+282039471029834.2801722893 - -471029834.2838
+182039471029834 - -471029834.2801722893
+282039471029834 - -471029834.2801722893
+182039471029834.8297282893 - -471029834.2801722893
+282039471029834.8297282893 - -471029834.2801722893
+-182039471029834 - -282039471029834
+-282039471029834 - -182039471029834
+-182039471029834.2801722893 - -282039471029834
+-282039471029834.2801722893 - -182039471029834
+-182039471029834.2801722893 - -282039471029834.2838
+-282039471029834.2801722893 - -182039471029834.2838
+-182039471029834 - -282039471029834.2801722893
+-282039471029834 - -182039471029834.2801722893
+-182039471029834.8297282893 - -282039471029834.2801722893
+-282039471029834.8297282893 - -182039471029834.2801722893
+-471029834 - -282039471029834
+-471029834 - -182039471029834
+-471029834.2801722893 - -282039471029834
+-471029834.2801722893 - -182039471029834
+-471029834.2801722893 - -282039471029834.2838
+-471029834.2801722893 - -182039471029834.2838
+-471029834 - -282039471029834.2801722893
+-471029834 - -182039471029834.2801722893
+-471029834.8297282893 - -282039471029834.2801722893
+-471029834.8297282893 - -182039471029834.2801722893
+-182039471029834 - -471029834
+-282039471029834 - -471029834
+-182039471029834.2801722893 - -471029834
+-282039471029834.2801722893 - -471029834
+-182039471029834.2801722893 - -471029834.2838
+-282039471029834.2801722893 - -471029834.2838
+-182039471029834 - -471029834.2801722893
+-282039471029834 - -471029834.2801722893
+-182039471029834.8297282893 - -471029834.2801722893
+-282039471029834.8297282893 - -471029834.2801722893
diff --git a/contrib/bc/tests/bc/subtract_results.txt b/contrib/bc/tests/bc/subtract_results.txt
new file mode 100644
index 000000000000..a38ffcad76c7
--- /dev/null
+++ b/contrib/bc/tests/bc/subtract_results.txt
@@ -0,0 +1,157 @@
+0
+-1
+1
+0
+3
+-7
+-12845975916483
+2874519803456326214611
+9000000000000000000000000000000000000001
+1
+9000000000000000000000000000000000000000.000000000000000000000000000\
+00000001
+.0000000000000000000000000000000001
+9999999999999999999999999999999999999999.999999999999999999999999999\
+99999999999999999999999999999999999999999999999999999999999
+10000000000000000000000000000000000000000.99999999999999999999999999\
+999999999999999999999999999999999999999999999999999999999999
+10000000000000000000000000000000000000000.00000000009999999999999999\
+99999999999999999999999999999999999999999999999999
+-8
+-182934721309467230894628759280719690
+1245723576605103923392087218483
+-3455919355
+2354768922.07654231707
+24055908741.876523177
+-1879234637.082765130766
+.0540410979106
+.8091148336535
+-124765829345.3602790000102
+-10548353126734.1621370644
+94875394587622.85102408852693655
+48667720255646230.89000073530825656433
+-2038581196
+-2351674834
+525898
+0
+18297034019823741908237410745467.69111734712098347109281029873
+-100000000000000
+100000000000000
+-99999999999999.7198277107
+100000000000000.2801722893
+-100000000000000.0036277107
+99999999999999.9963722893
+-100000000000000.2801722893
+99999999999999.7198277107
+-99999999999999.4504440000
+100000000000000.5495560000
+-282039000000000
+-182039000000000
+-282038999999999.7198277107
+-182038999999999.7198277107
+-282039000000000.0036277107
+-182039000000000.0036277107
+-282039000000000.2801722893
+-182039000000000.2801722893
+-282038999999999.4504440000
+-182038999999999.4504440000
+182039000000000
+282039000000000
+182039000000000.2801722893
+282039000000000.2801722893
+182038999999999.9963722893
+282038999999999.9963722893
+182038999999999.7198277107
+282038999999999.7198277107
+182039000000000.5495560000
+282039000000000.5495560000
+-464078942059668
+-464078942059668
+-464078942059668.2801722893
+-464078942059668.2801722893
+-464078942059668.5639722893
+-464078942059668.5639722893
+-464078942059668.2801722893
+-464078942059668.2801722893
+-464078942059669.1099005786
+-464078942059669.1099005786
+-282039942059668
+-182039942059668
+-282039942059668.2801722893
+-182039942059668.2801722893
+-282039942059668.5639722893
+-182039942059668.5639722893
+-282039942059668.2801722893
+-182039942059668.2801722893
+-282039942059669.1099005786
+-182039942059669.1099005786
+-182039942059668
+-282039942059668
+-182039942059668.2801722893
+-282039942059668.2801722893
+-182039942059668.5639722893
+-282039942059668.5639722893
+-182039942059668.2801722893
+-282039942059668.2801722893
+-182039942059669.1099005786
+-282039942059669.1099005786
+464078942059668
+464078942059668
+464078942059668.2801722893
+464078942059668.2801722893
+464078942059668.5639722893
+464078942059668.5639722893
+464078942059668.2801722893
+464078942059668.2801722893
+464078942059669.1099005786
+464078942059669.1099005786
+282039942059668
+182039942059668
+282039942059668.2801722893
+182039942059668.2801722893
+282039942059668.5639722893
+182039942059668.5639722893
+282039942059668.2801722893
+182039942059668.2801722893
+282039942059669.1099005786
+182039942059669.1099005786
+182039942059668
+282039942059668
+182039942059668.2801722893
+282039942059668.2801722893
+182039942059668.5639722893
+282039942059668.5639722893
+182039942059668.2801722893
+282039942059668.2801722893
+182039942059669.1099005786
+282039942059669.1099005786
+100000000000000
+-100000000000000
+99999999999999.7198277107
+-100000000000000.2801722893
+100000000000000.0036277107
+-99999999999999.9963722893
+100000000000000.2801722893
+-99999999999999.7198277107
+99999999999999.4504440000
+-100000000000000.5495560000
+282039000000000
+182039000000000
+282038999999999.7198277107
+182038999999999.7198277107
+282039000000000.0036277107
+182039000000000.0036277107
+282039000000000.2801722893
+182039000000000.2801722893
+282038999999999.4504440000
+182038999999999.4504440000
+-182039000000000
+-282039000000000
+-182039000000000.2801722893
+-282039000000000.2801722893
+-182038999999999.9963722893
+-282038999999999.9963722893
+-182038999999999.7198277107
+-282038999999999.7198277107
+-182039000000000.5495560000
+-282039000000000.5495560000
diff --git a/contrib/bc/tests/bc/timeconst.sh b/contrib/bc/tests/bc/timeconst.sh
new file mode 100755
index 000000000000..32e1e743d9e4
--- /dev/null
+++ b/contrib/bc/tests/bc/timeconst.sh
@@ -0,0 +1,91 @@
+#! /bin/sh
+#
+# Copyright (c) 2018-2020 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.
+#
+
+# Tests the timeconst.bc script from the Linux kernel build.
+# You can find the script at kernel/time/timeconst.bc in any Linux repo.
+# One such repo is: https://github.com/torvalds/linux
+
+script="$0"
+testdir=$(dirname "$script")
+
+if [ "$#" -gt 0 ]; then
+ timeconst="$1"
+ shift
+else
+ timeconst="$testdir/scripts/timeconst.bc"
+fi
+
+if [ "$#" -gt 0 ]; then
+ bc="$1"
+ shift
+else
+ bc="$testdir/../../bin/bc"
+fi
+
+out1="$testdir/../.log_bc_timeconst.txt"
+out2="$testdir/../.log_bc_timeconst_test.txt"
+
+base=$(basename "$timeconst")
+
+if [ ! -f "$timeconst" ]; then
+ printf 'Warning: %s does not exist\n' "$timeconst"
+ printf 'Skipping...\n'
+ exit 0
+fi
+
+printf 'Running %s...' "$base"
+
+nums=$(printf 'for (i = 0; i <= 1000; ++i) { i }\n' | bc)
+
+for i in $nums; do
+
+ printf '%s\n' "$i" | bc -q "$timeconst" > "$out1"
+
+ err="$?"
+
+ if [ "$err" -ne 0 ]; then
+ printf '\nOther bc is not GNU compatible. Skipping...\n'
+ exit 0
+ fi
+
+ printf '%s\n' "$i" | "$bc" "$@" -q "$timeconst" > "$out2"
+
+ diff "$out1" "$out2"
+
+ error="$?"
+
+ if [ "$error" -ne 0 ]; then
+ printf '\nFailed on input: %s\n' "$i"
+ exit "$error"
+ fi
+
+done
+
+rm -f "$out1"
+rm -f "$out2"
+
+printf 'pass\n'
diff --git a/contrib/bc/tests/bc/trunc.txt b/contrib/bc/tests/bc/trunc.txt
new file mode 100644
index 000000000000..364bb224a2e3
--- /dev/null
+++ b/contrib/bc/tests/bc/trunc.txt
@@ -0,0 +1,15 @@
+0$
+1$
+2$
+0.8249167203486$
+1.28937150237$
+2.0$
+28937.92837605126$
+2890.000000000$
+-1$
+-1.128973$
+-9812387.28910273$
+x = 83.298
+x$
+x = -1893.19
+(x)$
diff --git a/contrib/bc/tests/bc/trunc_results.txt b/contrib/bc/tests/bc/trunc_results.txt
new file mode 100644
index 000000000000..c888c95d2daa
--- /dev/null
+++ b/contrib/bc/tests/bc/trunc_results.txt
@@ -0,0 +1,13 @@
+0
+1
+2
+0
+1
+2
+28937
+2890
+-1
+-1
+-9812387
+83
+-1893
diff --git a/contrib/bc/tests/bc/vars.txt b/contrib/bc/tests/bc/vars.txt
new file mode 100644
index 000000000000..91e3572c2a0b
--- /dev/null
+++ b/contrib/bc/tests/bc/vars.txt
@@ -0,0 +1,7 @@
+scale=10;123981239.981273987 * 12983791827398.29836472638
+scale=100;759634576394.3946587934658364895 / 9834759834895386.36459364958346
+34895734986539489834759837489573498573.398475984759837485734987598345 + 9823749832749872384234872934.28347982374987239847982374
+a=123123123.987239874; b=123123123.239479823748; a+b
+20347023.23498723984 - 28934723874.234720384
+scale=100;a=739534985.895347284957;b=238746782364.2374623784; c = a / b; c
+s7298367203972395108367910823465293084561329084561390845613409516734503870691837451 + 785621394067928346918023476190834672198467134908618723249671349062187346898241093486139046139084613490817356023871869102746182749061872609129847
diff --git a/contrib/bc/tests/bc/vars_results.txt b/contrib/bc/tests/bc/vars_results.txt
new file mode 100644
index 000000000000..6597d8439723
--- /dev/null
+++ b/contrib/bc/tests/bc/vars_results.txt
@@ -0,0 +1,12 @@
+1609746610419572350599.59456175545
+.0000772397688552681359718594121969204138521230712049526233926741658\
+845368495051158801794834809672994
+34895734996363239667509709873808371507.68195580850970988421481133834\
+5
+246246247.226719697748
+-28914376850.99973314416
+.0030975704827179453786044330548590249517387192084765414205077089498\
+482709063381782183114683451531598
+78562139406792834691802347619083467219846713490861872324967134906218\
+73468982410934861390461390846134908173560238718691027461827490618726\
+09129847
diff --git a/contrib/bc/tests/bc/void.txt b/contrib/bc/tests/bc/void.txt
new file mode 100644
index 000000000000..b85d70c8590a
--- /dev/null
+++ b/contrib/bc/tests/bc/void.txt
@@ -0,0 +1,20 @@
+define void stuff(x) {
+ print "x: ", x, "\n"
+}
+
+define void(x) {
+ return x
+}
+
+stuff(0)
+stuff(1)
+stuff(2.2839)
+stuff(-9.9289389)
+
+void(0)
+void(1)
+void(2.9823)
+void(-3.5982)
+
+void = .198389
+void + 10
diff --git a/contrib/bc/tests/bc/void_results.txt b/contrib/bc/tests/bc/void_results.txt
new file mode 100644
index 000000000000..1e352efe9238
--- /dev/null
+++ b/contrib/bc/tests/bc/void_results.txt
@@ -0,0 +1,9 @@
+x: 0
+x: 1
+x: 2.2839
+x: -9.9289389
+0
+1
+2.9823
+-3.5982
+10.198389
diff --git a/contrib/bc/tests/bcl.c b/contrib/bc/tests/bcl.c
new file mode 100644
index 000000000000..aab2c5d35e9b
--- /dev/null
+++ b/contrib/bc/tests/bcl.c
@@ -0,0 +1,228 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2020 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.
+ *
+ * *****************************************************************************
+ *
+ * Tests for bcl(3).
+ *
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <bcl.h>
+
+static void err(BclError e) {
+ if (e != BCL_ERROR_NONE) abort();
+}
+
+int main(void) {
+
+ BclError e;
+ BclContext ctxt;
+ size_t scale;
+ BclNumber n, n2, n3, n4, n5, n6;
+ char* res;
+ BclBigDig b = 0;
+
+ e = bcl_init();
+ err(e);
+
+ e = bcl_init();
+ err(e);
+
+ if (bcl_abortOnFatalError()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ bcl_setAbortOnFatalError(true);
+
+ if (!bcl_abortOnFatalError()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ ctxt = bcl_ctxt_create();
+
+ bcl_pushContext(ctxt);
+
+ ctxt = bcl_ctxt_create();
+
+ bcl_pushContext(ctxt);
+
+ scale = 10;
+
+ bcl_ctxt_setScale(ctxt, scale);
+
+ scale = bcl_ctxt_scale(ctxt);
+ if (scale != 10) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ scale = 16;
+
+ bcl_ctxt_setIbase(ctxt, scale);
+
+ scale = bcl_ctxt_ibase(ctxt);
+ if (scale != 16) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ bcl_ctxt_setObase(ctxt, scale);
+
+ scale = bcl_ctxt_obase(ctxt);
+ if (scale != 16) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ bcl_ctxt_setIbase(ctxt, 10);
+ bcl_ctxt_setObase(ctxt, 10);
+
+ n = bcl_num_create();
+
+ n2 = bcl_dup(n);
+ bcl_copy(n, n2);
+
+ n3 = bcl_parse("2938");
+ err(bcl_err(n3));
+
+ n4 = bcl_parse("-28390.9108273");
+ err(bcl_err(n4));
+
+ if (!bcl_num_neg(n4)) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ n3 = bcl_add(n3, n4);
+ err(bcl_err(n3));
+
+ res = bcl_string(bcl_dup(n3));
+ if (strcmp(res, "-25452.9108273")) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ n4 = bcl_parse("8937458902.2890347");
+ err(bcl_err(n4));
+
+ e = bcl_divmod(bcl_dup(n4), n3, &n5, &n6);
+ err(e);
+
+ res = bcl_string(n5);
+
+ if (strcmp(res, "-351137.0060159482"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(n6);
+
+ if (strcmp(res, ".00000152374405414"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ n4 = bcl_sqrt(n4);
+ err(bcl_err(n4));
+
+ res = bcl_string(bcl_dup(n4));
+
+ if (strcmp(res, "94538.1346457028"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ e = bcl_num_setScale(n4, 20);
+ err(e);
+
+ res = bcl_string(bcl_dup(n4));
+
+ if (strcmp(res, "94538.13464570280000000000"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ e = bcl_num_setScale(n4, 0);
+ err(e);
+
+ res = bcl_string(bcl_dup(n4));
+
+ if (strcmp(res, "94538"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ e = bcl_bigdig(n4, &b);
+ err(e);
+
+ if (b != 94538) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ n4 = bcl_bigdig2num(b);
+ err(bcl_err(n4));
+
+ res = bcl_string(bcl_dup(n4));
+
+ if (strcmp(res, "94538"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ n4 = bcl_frand(10);
+ err(bcl_err(n4));
+
+ n4 = bcl_lshift(n4, bcl_bigdig2num(10));
+ err(bcl_err(n4));
+
+ n3 = bcl_irand(n4);
+ err(bcl_err(n3));
+
+ n2 = bcl_ifrand(bcl_dup(n3), 10);
+ err(bcl_err(n2));
+
+ e = bcl_rand_seedWithNum(n3);
+ err(e);
+
+ n4 = bcl_rand_seed2num();
+ err(bcl_err(n4));
+
+ n5 = bcl_parse("10");
+ err(bcl_err(n5));
+
+ n6 = bcl_modexp(bcl_dup(n5), bcl_dup(n5), bcl_dup(n5));
+ err(bcl_err(n6));
+
+ bcl_num_free(n);
+
+ bcl_ctxt_freeNums(ctxt);
+
+ bcl_gc();
+
+ bcl_popContext();
+
+ bcl_ctxt_free(ctxt);
+
+ ctxt = bcl_context();
+
+ bcl_popContext();
+
+ bcl_ctxt_free(ctxt);
+
+ bcl_free();
+
+ bcl_free();
+
+ return 0;
+}
diff --git a/contrib/bc/tests/dc/abs.txt b/contrib/bc/tests/dc/abs.txt
new file mode 100644
index 000000000000..9907dfc6679d
--- /dev/null
+++ b/contrib/bc/tests/dc/abs.txt
@@ -0,0 +1,7 @@
+0bpR
+1bpR
+.218933bpR
+138963.9873645bpR
+_19bpR
+_.1298376bpR
+_3892173.289375bpR
diff --git a/contrib/bc/tests/dc/abs_results.txt b/contrib/bc/tests/dc/abs_results.txt
new file mode 100644
index 000000000000..921a848ab6f0
--- /dev/null
+++ b/contrib/bc/tests/dc/abs_results.txt
@@ -0,0 +1,7 @@
+0
+1
+.218933
+138963.9873645
+19
+.1298376
+3892173.289375
diff --git a/contrib/bc/tests/dc/add.txt b/contrib/bc/tests/dc/add.txt
new file mode 100644
index 000000000000..42da2f1f309c
--- /dev/null
+++ b/contrib/bc/tests/dc/add.txt
@@ -0,0 +1,33 @@
+0 0+pR
+0 0 0++pR
+0 1+pR
+0 1 1++pR
+1 1+pR
+1 0+pR
+2 5+pR
+237 483+pR
+999 999+pR
+2374623 324869356734856+pR
+2378639084586723980562 23468729367839+pR
+37298367203972395108367910823465293084561329084561390845613409516734503870691837451 785621394067928346918023476190834672198467134908618723249671349062187346898241093486139046139084613490817356023871869102746182749061872609129847+pR
+1.1 0+pR
+0 1.1+pR
+457283.731284923576 37842934672834.3874629385672354+pR
+1.0 0.1+pR
+3746289134067138046 0.138375863945672398456712389456273486293+pR
+_1 _1+pR
+_4 _15+pR
+_1346782 _1287904651762468913476+pR
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+pR
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005+pR
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+pR
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999999999999999999999999999999999999999899999999999999999999999999999999999999999999999999999999999999 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+pR
+99999999999999999999999999999999999989999999999999999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+pR
+_1889985797 2012747315+pR
+0 _14338.391079082+pR
+_2422297 1.3134942556+pR
+_1289374 1289374.2893417 0.238971 28937.28971+++pR
+1289374 1289374.2893417 _0.238971 28937.28971+++pR
+1289374 1289374.2893417 0.238971 _28937.28971+++pR
+1289374 1289374.2893417 _0.238971 _28937.28971+++pR
+1289374 _1289374.2893417 _0.238971 _28937.28971+++pR
diff --git a/contrib/bc/tests/dc/add_results.txt b/contrib/bc/tests/dc/add_results.txt
new file mode 100644
index 000000000000..542a62ea3a33
--- /dev/null
+++ b/contrib/bc/tests/dc/add_results.txt
@@ -0,0 +1,45 @@
+0
+0
+1
+2
+2
+1
+7
+720
+1998
+324869359109479
+2378639108055453348401
+78562139406792834691802347619083467219846713490861872324967138636055\
+45508706362018540498696043776980521464405852627147161556994835657433\
+00967298
+1.1
+1.1
+37842935130118.1187478621432354
+1.1
+3746289134067138046.138375863945672398456712389456273486293
+-2
+-19
+-1287904651762470260258
+100000000000000000000000000000000000000000000000000000000000.0000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+000000000000000000000000000000000000000000000
+100000000000000000000000000000000000000000000000000000000000.0000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+000000000000000000000000000000000000000000000
+100000000000000000000000000000000000000000000000000000000000.0000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+000000000000000000000000000000000000000009999
+99999999999999999999999999999999999999999999999999999999999.99999999\
+99999999999999999999999999999999999999999999999999000000000000000000\
+00000000000000000000000000000000000000009999
+99999999999999999999999999999999999990000000000000000000000.00000000\
+00000000000000000000000000000000000000000000000000000000000000000000\
+00000000000000000000000000000000000000009999
+122761518
+-14338.391079082
+-2422295.6865057444
+28937.8180227
+2607685.3400807
+2549811.2386027
+2549810.7606607
+-28937.8180227
diff --git a/contrib/bc/tests/dc/all.txt b/contrib/bc/tests/dc/all.txt
new file mode 100644
index 000000000000..6879541f7f1a
--- /dev/null
+++ b/contrib/bc/tests/dc/all.txt
@@ -0,0 +1,22 @@
+decimal
+add
+subtract
+multiply
+divide
+modulus
+divmod
+power
+sqrt
+modexp
+boolean
+negate
+trunc
+places
+shift
+abs
+scientific
+engineering
+vars
+misc
+strings
+rand
diff --git a/contrib/bc/tests/dc/boolean.txt b/contrib/bc/tests/dc/boolean.txt
new file mode 100644
index 000000000000..815100f0d085
--- /dev/null
+++ b/contrib/bc/tests/dc/boolean.txt
@@ -0,0 +1,80 @@
+0 1(pR
+1 1(pR
+2 1(pR
+_1 1(pR
+_1 0(pR
+_1 _1(pR
+_1 _2(pR
+0 1{pR
+1 1{pR
+2 1{pR
+_1 1{pR
+_1 0{pR
+_1 _1{pR
+_1 _2{pR
+0 1)pR
+1 1)pR
+2 1)pR
+_1 1)pR
+_1 0)pR
+_1 _1)pR
+_1 _2)pR
+0 1}pR
+1 1}pR
+2 1}pR
+_1 1}pR
+_1 0}pR
+_1 _1}pR
+_1 _2}pR
+0 0GpR
+0 1GpR
+1 0GpR
+_1 _1GpR
+0 _1GpR
+_1 0GpR
+1 1GpR
+238 2GpR
+0NpR
+1NpR
+_1NpR
+2398NpR
+_2983.2389NpR
+0 0MpR
+1 0MpR
+0 1MpR
+1 1MpR
+128973240 0MpR
+0 2893712MpR
+1982 28937MpR
+_2938 0MpR
+0 _1023.298037MpR
+0.283917 0MpR
+2389 _1208.28937MpR
+0 289.289372MpR
+_298.29387 0MpR
+_2983.28973 82937MpR
+0 _2938.320837MpR
+_2089.2308 0MpR
+_0.2893 _2938.28973MpR
+0.00000 1892MpR
+1289.023 .0000MpR
+0 0mpR
+1 0mpR
+0 1mpR
+1 1mpR
+128973240 0mpR
+0 2893712mpR
+1982 28937mpR
+_2938 0mpR
+0 _1023.298037mpR
+0.283917 0mpR
+2389 _1208.28937mpR
+0 289.289372mpR
+_298.29387 0mpR
+_2983.28973 82937mpR
+0 _2938.320837mpR
+_2089.2308 0mpR
+_0.2893 _2938.28973mpR
+0.00000 1892mpR
+1289.023 .0000mpR
+0.0000 .00000mpR
diff --git a/contrib/bc/tests/dc/boolean_results.txt b/contrib/bc/tests/dc/boolean_results.txt
new file mode 100644
index 000000000000..225cebbe04bb
--- /dev/null
+++ b/contrib/bc/tests/dc/boolean_results.txt
@@ -0,0 +1,80 @@
+0
+0
+1
+0
+0
+0
+1
+0
+1
+1
+0
+0
+1
+1
+1
+0
+0
+1
+1
+0
+0
+1
+1
+0
+1
+1
+1
+0
+1
+0
+0
+1
+0
+0
+1
+0
+1
+0
+0
+0
+0
+0
+0
+0
+1
+0
+0
+1
+0
+0
+0
+1
+0
+0
+1
+0
+0
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
diff --git a/contrib/bc/tests/dc/decimal.txt b/contrib/bc/tests/dc/decimal.txt
new file mode 100644
index 000000000000..ebbb2dc91b3a
--- /dev/null
+++ b/contrib/bc/tests/dc/decimal.txt
@@ -0,0 +1,36 @@
+0pR
+0.0pR
+.0000pR
+000000000000000000000000.00000000000000000000000pR
+000000000000000000000000000135482346782356pR
+000000000000000000000000002pR
+1pR
+11pR
+123pR
+7505pR
+1023468723275435238491972521917846pR
+4343472432431705867392073517038270398027352709027389273920739037937960379637893607893607893670530278200795207952702873892786172916728961783907893607418973587857386079679267926737520730925372983782793652793pR
+_1pR
+_203pR
+_57pR
+_18586pR
+_31378682943772818461924738352952347258pR
+_823945628745673589495067238723986520375698237620834674509627345273096287563846592384526349872634895763257893467523987578690283762897568459072348758071071087813501875908127359018715023841710239872301387278pR
+.123521346523546pR
+0.1245923756273856pR
+_.1024678456387pR
+_0.8735863475634587pR
+4.0pR
+_6.0pR
+234237468293576.000000000000000000000000000000pR
+23987623568943567.00000000000000000005677834650000000000000pR
+23856934568940675.000000000000000435676782300000000000000456784pR
+77567648698496.000000000000000000587674750000000000458563800000000000000pR
+2348672354968723.2374823546000000000003256987394502346892435623870000000034578pR
+_2354768.000000000000000000000000000000000000pR
+_96739874567.000000000347683456pR
+_3764568345.000000000004573845000000347683460pR
+_356784356.934568495770004586495678300000000pR
+74325437345273852773827101738273127312738521733017537073520735207307570358738257390761276072160719802671980267018728630178.7082681027680521760217867841276127681270867827821768173178207830710978017738178678012767377058785378278207385237085237803278203782037237582795870pR
+_756752732785273851273728537852738257837283678965738527385272983678372867327835672967385278372637862738627836279863782673862783670.71738178361738718367186378610738617836781603760178367018603760178107735278372832783728367826738627836278378260736270367362073867097307925pR
+9812734012837410982345719208345712908357412903587192048571920458712.23957182459817249058172945781pR
diff --git a/contrib/bc/tests/dc/decimal_results.txt b/contrib/bc/tests/dc/decimal_results.txt
new file mode 100644
index 000000000000..275d431c6e0f
--- /dev/null
+++ b/contrib/bc/tests/dc/decimal_results.txt
@@ -0,0 +1,51 @@
+0
+0
+0
+0
+135482346782356
+2
+1
+11
+123
+7505
+1023468723275435238491972521917846
+43434724324317058673920735170382703980273527090273892739207390379379\
+60379637893607893607893670530278200795207952702873892786172916728961\
+78390789360741897358785738607967926792673752073092537298378279365279\
+3
+-1
+-203
+-57
+-18586
+-31378682943772818461924738352952347258
+-8239456287456735894950672387239865203756982376208346745096273452730\
+96287563846592384526349872634895763257893467523987578690283762897568\
+45907234875807107108781350187590812735901871502384171023987230138727\
+8
+.123521346523546
+.1245923756273856
+-.1024678456387
+-.8735863475634587
+4.0
+-6.0
+234237468293576.000000000000000000000000000000
+23987623568943567.00000000000000000005677834650000000000000
+23856934568940675.000000000000000435676782300000000000000456784
+77567648698496.00000000000000000058767475000000000045856380000000000\
+0000
+2348672354968723.237482354600000000000325698739450234689243562387000\
+0000034578
+-2354768.000000000000000000000000000000000000
+-96739874567.000000000347683456
+-3764568345.000000000004573845000000347683460
+-356784356.934568495770004586495678300000000
+74325437345273852773827101738273127312738521733017537073520735207307\
+570358738257390761276072160719802671980267018728630178.7082681027680\
+52176021786784127612768127086782782176817317820783071097801773817867\
+8012767377058785378278207385237085237803278203782037237582795870
+-7567527327852738512737285378527382578372836789657385273852729836783\
+72867327835672967385278372637862738627836279863782673862783670.71738\
+17836173871836718637861073861783678160376017836701860376017810773527\
+8372832783728367826738627836278378260736270367362073867097307925
+9812734012837410982345719208345712908357412903587192048571920458712.\
+23957182459817249058172945781
diff --git a/contrib/bc/tests/dc/divide.txt b/contrib/bc/tests/dc/divide.txt
new file mode 100644
index 000000000000..38b874e9f175
--- /dev/null
+++ b/contrib/bc/tests/dc/divide.txt
@@ -0,0 +1,33 @@
+20k
+0 1/pR
+0 321566/pR
+0 0.3984567238456/pR
+1 1/pR
+1 1287469297356/pR
+1 0.2395672438567234/pR
+1 237586239856.0293596728392360/pR
+1249687284356 3027949207835207/pR
+378617298617396719 35748521/pR
+9348576237845624358 0.9857829375461/pR
+35768293846193284 2374568947.045762839567823/pR
+_78987234567812345 876542837618936/pR
+_356789237555535468 0.3375273860984786903/pR
+_5203475364850390 435742903748307.70869378534043296404530458/pR
+_0.37861723347576903 7385770896/pR
+_0.399454682043962 0.34824389304/pR
+_0.6920414523873204 356489645223.76076045304879030/pR
+_35872917389671.7573280963748 73924708/pR
+_78375896314.4836709876983 0.78356798637817/pR
+_2374123896417.143789621437581 347821469423789.1473856783960/pR
+_896729350238549726 _34976289345762/pR
+_2374568293458762348596 _0.8792370647234987679/pR
+_237584692306721845726038 _21783910782374529637.978102738746189024761/pR
+_0.23457980123576298375682 _1375486293874612/pR
+_0.173897061862478951264 _0.8179327486017634987516298745/pR
+_0.9186739823576829347586 _0.235678293458756239846/pR
+_0.9375896183746982374568 _13784962873546.0928729395476283745/pR
+_2930754618923467.12323745862937465 _734869238465/pR
+_23745861923467.874675129834675 _0.23542357869124756/pR
+_3878923750692883.7238596702834756902 _7384192674957215364986723.9738461923487621983/pR
+1 0.00000000000000000000000000000000000000000002346728372937352457354204563027/pR
+239854711289345712 2891374 182 .2893 ///pR
diff --git a/contrib/bc/tests/dc/divide_results.txt b/contrib/bc/tests/dc/divide_results.txt
new file mode 100644
index 000000000000..340ae94c1aa6
--- /dev/null
+++ b/contrib/bc/tests/dc/divide_results.txt
@@ -0,0 +1,32 @@
+0
+0
+0
+1.00000000000000000000
+.00000000000077671755
+4.17419336592637110778
+.00000000000420899796
+.00041271738677857404
+10591131829.40901859967857131767
+9483402361494453751.52388015648196297248
+15063068.13735316451497043884
+-90.11223545260531110575
+-1057067521778623447.45138528213564485251
+-11.94161814246320631346
+-.00000000005126306228
+-1.14705437777218917343
+-.00000000000194126663
+-485262.88923145638029569727
+-100024372711.74763635544535424582
+-.00682569681609989277
+25638.20711150436682153521
+2700714504347599627864.24626421085374010264
+10906.42973524078145692731
+.00000000000000017054
+.21260557443109085166
+3.89799997647407910677
+.00000000000006801538
+3988.13076601933678578945
+100864416620775.31076855630746548983
+.00000000052530099381
+42612515855353136519261264261472677699404182.78776061098893912189
+52187553294928.31582417732156163799
diff --git a/contrib/bc/tests/dc/divmod.txt b/contrib/bc/tests/dc/divmod.txt
new file mode 100644
index 000000000000..1633203ff99f
--- /dev/null
+++ b/contrib/bc/tests/dc/divmod.txt
@@ -0,0 +1,64 @@
+20k
+0 1~pRpR
+0 321566~pRpR
+0 0.3984567238456~pRpR
+1 1~pRpR
+1 1287469297356~pRpR
+1 0.2395672438567234~pRpR
+1 237586239856.0293596728392360~pRpR
+1249687284356 3027949207835207~pRpR
+378617298617396719 35748521~pRpR
+9348576237845624358 0.9857829375461~pRpR
+35768293846193284 2374568947.045762839567823~pRpR
+_78987234567812345 876542837618936~pRpR
+_356789237555535468 0.3375273860984786903~pRpR
+_5203475364850390 435742903748307.70869378534043296404530458~pRpR
+_0.37861723347576903 7385770896~pRpR
+_0.399454682043962 0.34824389304~pRpR
+_0.6920414523873204 356489645223.76076045304879030~pRpR
+_35872917389671.7573280963748 73924708~pRpR
+_78375896314.4836709876983 0.78356798637817~pRpR
+_2374123896417.143789621437581 347821469423789.1473856783960~pRpR
+_896729350238549726 _34976289345762~pRpR
+_2374568293458762348596 _0.8792370647234987679~pRpR
+_237584692306721845726038 _21783910782374529637.978102738746189024761~pRpR
+_0.23457980123576298375682 _1375486293874612~pRpR
+_0.173897061862478951264 _0.8179327486017634987516298745~pRpR
+_0.9186739823576829347586 _0.235678293458756239846~pRpR
+_0.9375896183746982374568 _13784962873546.0928729395476283745~pRpR
+_2930754618923467.12323745862937465 _734869238465~pRpR
+_23745861923467.874675129834675 _0.23542357869124756~pRpR
+_3878923750692883.7238596702834756902 _7384192674957215364986723.9738461923487621983~pRpR
+1 0.00000000000000000000000000000000000000000002346728372937352457354204563027~pRpR
+0k
+0 1~pRpR
+0 321566~pRpR
+0 0.3984567238456~pRpR
+1 1~pRpR
+1 1287469297356~pRpR
+1 0.2395672438567234~pRpR
+1 237586239856.0293596728392360~pRpR
+1249687284356 3027949207835207~pRpR
+378617298617396719 35748521~pRpR
+9348576237845624358 0.9857829375461~pRpR
+35768293846193284 2374568947.045762839567823~pRpR
+_78987234567812345 876542837618936~pRpR
+_356789237555535468 0.3375273860984786903~pRpR
+_5203475364850390 435742903748307.70869378534043296404530458~pRpR
+_0.37861723347576903 7385770896~pRpR
+_0.399454682043962 0.34824389304~pRpR
+_0.6920414523873204 356489645223.76076045304879030~pRpR
+_35872917389671.7573280963748 73924708~pRpR
+_78375896314.4836709876983 0.78356798637817~pRpR
+_2374123896417.143789621437581 347821469423789.1473856783960~pRpR
+_896729350238549726 _34976289345762~pRpR
+_2374568293458762348596 _0.8792370647234987679~pRpR
+_237584692306721845726038 _21783910782374529637.978102738746189024761~pRpR
+_0.23457980123576298375682 _1375486293874612~pRpR
+_0.173897061862478951264 _0.8179327486017634987516298745~pRpR
+_0.9186739823576829347586 _0.235678293458756239846~pRpR
+_0.9375896183746982374568 _13784962873546.0928729395476283745~pRpR
+_2930754618923467.12323745862937465 _734869238465~pRpR
+_23745861923467.874675129834675 _0.23542357869124756~pRpR
+_3878923750692883.7238596702834756902 _7384192674957215364986723.9738461923487621983~pRpR
+1 0.00000000000000000000000000000000000000000002346728372937352457354204563027~pRpR
diff --git a/contrib/bc/tests/dc/divmod_results.txt b/contrib/bc/tests/dc/divmod_results.txt
new file mode 100644
index 000000000000..c55e9303d935
--- /dev/null
+++ b/contrib/bc/tests/dc/divmod_results.txt
@@ -0,0 +1,126 @@
+0
+0
+0
+0
+0
+0
+0
+1.00000000000000000000
+.00000000165742620220
+.00000000000077671755
+.000000000000000000000404744340951948
+4.17419336592637110778
+.000000001121901731436913388268041440
+.00000000000420899796
+.00000053204123177372
+.00041271738677857404
+.00000000000027633393
+10591131829.40901859967857131767
+.000000000000000000008615446968672
+9483402361494453751.52388015648196297248
+.00000000001477790730322167374655468
+15063068.13735316451497043884
+-.00000456715270151800
+-90.11223545260531110575
+-.000000000000000000002529869118878532347
+-1057067521778623447.45138528213564485251
+-.0000022326265743225222025732006233770753463532
+-11.94161814246320631346
+-.00000000004830962712
+-.00000000005126306228
+-.0000000000000000000013970700728
+-1.14705437777218917343
+-.0000000001738947526290727016287423110
+-.00000000000194126663
+-.00000000000045885284
+-485262.88923145638029569727
+-.0000000000000000000075040663382506
+-100024372711.74763635544535424582
+-.000001609445227594519190694403080
+-.00682569681609989277
+-.00000019041665271998
+25638.20711150436682153521
+-.000000000000000000005200979673140462744
+2700714504347599627864.24626421085374010264
+-.15832010238185026960887316509782343287709
+10906.42973524078145692731
+-.00000436867838665327682
+.00000000000000017054
+-.000000000000000000004322546241638067588696083330
+.21260557443109085166
+-.00000000000000000000103666428264443764258
+3.89799997647407910677
+-.000000130244568783188524951028009600190
+.00000000000006801538
+-.00000000467404345575
+3988.13076601933678578945
+-.0000000000000000000004406586308076852
+100864416620775.31076855630746548983
+-53336.193401942302558132911110799109649707477
+.00000000052530099381
+.0000000000000000000000000000000000000000000000000000000000000001907\
+266929376630027064745963897
+42612515855353136519261264261472677699404182.78776061098893912189
+0
+0
+0
+0
+0
+0
+0
+1
+1
+0
+.0417310245731064
+4
+1.0000000000000000
+0
+1249687284356
+0
+14621810
+10591131829
+.5164321195789
+9483402361494453751
+326154559.235716791539036
+15063068
+-98379182108105
+-90
+-.1523548944025685359
+-1057067521778623447
+-410303423619005.20436836125523739550164962
+-11
+-.37861723347576903
+0
+-.051210789003962
+-1
+-.69204145238732040
+0
+-65736175.7573280963748
+-485262
+-.58582391357943
+-100024372711
+-2374123896417.143789621437581
+0
+-7243991903570
+25638
+-.2165246218974912344
+2700714504347599627864
+-9361314145225494248.811531234062495956534
+10906
+-.23457980123576298375682
+0
+-.1738970618624789512640000000
+0
+-.2116391019814142152206
+3
+-.9375896183746982374568
+0
+-96095925047.12323745862937465
+3988
+-.07316224567061600
+100864416620775
+-3878923750692883.7238596702834756902
+0
+.0000000000000000000000000000000000000000000184866017689020776005643\
+3621086
+42612515855353136519261264261472677699404182
diff --git a/contrib/bc/tests/dc/engineering.txt b/contrib/bc/tests/dc/engineering.txt
new file mode 100644
index 000000000000..90a35052b3cb
--- /dev/null
+++ b/contrib/bc/tests/dc/engineering.txt
@@ -0,0 +1,19 @@
+1o
+0pR
+1pR
+_34pR
+298pR
+_8933pR
+29488pR
+_148232pR
+8927559pR
+.2pR
+_.02pR
+.002pR
+_.0003pR
+.0000209310pR
+_.00000289362pR
+.000000859289pR
+_.02983672pR
+.20201296pR
+_.8907210897000000000000000000pR
diff --git a/contrib/bc/tests/dc/engineering_results.txt b/contrib/bc/tests/dc/engineering_results.txt
new file mode 100644
index 000000000000..dd26f9bbb138
--- /dev/null
+++ b/contrib/bc/tests/dc/engineering_results.txt
@@ -0,0 +1,18 @@
+0
+1e0
+-34e0
+298e0
+-8.933e3
+29.488e3
+-148.232e3
+8.927559e6
+200e-3
+-20e-3
+2e-3
+-300e-6
+20.9310e-6
+-2.89362e-6
+859.289e-9
+-29.83672e-3
+202.01296e-3
+-890.7210897000000000000000000e-3
diff --git a/contrib/bc/tests/dc/errors.txt b/contrib/bc/tests/dc/errors.txt
new file mode 100644
index 000000000000..8ead40c57e9d
--- /dev/null
+++ b/contrib/bc/tests/dc/errors.txt
@@ -0,0 +1,32 @@
+p
+P
+x
+R
+d
+r
+1r
+b
+4 100000|
+_
+]
+zp198202389.289374pzp[He World!]xSzpzXfrfxzpfR
+[hello]k
+3 2 0|
+3 0 0|
+3.2 3 1|
+3 3.2 1|
+2 10 34.2|
+2 _10 23|
+3 0~
+0 _251^pR
+.
+@
+0 0< $
+0 0> s e %
+[string]b
+[s][s]+
+[s][s]@
+[s][s]v
+0si 0 1 >i
+?
+?
diff --git a/contrib/bc/tests/dc/errors/01.txt b/contrib/bc/tests/dc/errors/01.txt
new file mode 100644
index 000000000000..8adde2ea0deb
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/01.txt
@@ -0,0 +1,2 @@
+[[aotsnheau
+'t,.h]
diff --git a/contrib/bc/tests/dc/errors/02.txt b/contrib/bc/tests/dc/errors/02.txt
new file mode 100644
index 000000000000..893128a8e8e7
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/02.txt
@@ -0,0 +1,10 @@
+0 R
+2 1
+1 0+pRpp
+34.x
+[lip0+si10]ip1+pR
+0 1 1++pR
+1 1+p?
+1 0+pRpp
+34.x
+[lip0+si10}ip1+si30li<L]sL0sJlLx
diff --git a/contrib/bc/tests/dc/errors/03.txt b/contrib/bc/tests/dc/errors/03.txt
new file mode 100644
index 000000000000..a0877e7ec264
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/03.txt
@@ -0,0 +1,2 @@
+0 lip1-si0l0+234sx_9lq+pR 34.x
+[li170LLdp1+s+sX10lM<L]sL0sJlLx
diff --git a/contrib/bc/tests/dc/errors/04.txt b/contrib/bc/tests/dc/errors/04.txt
new file mode 100644
index 000000000000..a59572d8f761
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/04.txt
@@ -0,0 +1,10 @@
+zp198202389.289374p1+pR
+0 1 1+kpR
+1 1+pR
+1 0IpR
+2 9+iR
+037 483+pR
+999 999+pR
+237467456283846vpR
+.0000000ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsdddddddddddddddddddddddddddddddddddddddddddddddddddddsdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd/ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddfddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddd96723895687456283846vpR
+.0
diff --git a/contrib/bc/tests/dc/errors/05.txt b/contrib/bc/tests/dc/errors/05.txt
new file mode 100644
index 000000000000..924f8ad41960
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/05.txt
@@ -0,0 +1,3 @@
+04604462921702348sx_928374892.28937syzpRlxlq+pR
+34.x
+[li1702348sxLLLLLL928374892.28937sLLL]sL0sJlLx
diff --git a/contrib/bc/tests/dc/errors/06.txt b/contrib/bc/tests/dc/errors/06.txt
new file mode 100644
index 000000000000..e806f63d71b0
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/06.txt
@@ -0,0 +1,4 @@
+00Q;pd69 p d9S16+00I;pd69Q2 0^pR
+1O392RQ2 1^pR
+1361345237859627#8sM[lip1-si0li!<LeM]^L1OsilLx
+[[Done!]pR]SM^lip1-si0li!=LesL1L;0silLx
diff --git a/contrib/bc/tests/dc/errors/07.txt b/contrib/bc/tests/dc/errors/07.txt
new file mode 100644
index 000000000000..6d1a9dfa9f95
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/07.txt
@@ -0,0 +1,4 @@
+1 0 1|dR
+1 [lipL]SL10sildR
+1 [lipL]sL10|Lx
+[
diff --git a/contrib/bc/tests/dc/errors/08.txt b/contrib/bc/tests/dc/errors/08.txt
new file mode 100644
index 000000000000..9c34b0e0e24e
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/08.txt
@@ -0,0 +1,2 @@
+0 2+p[lip1-si0li!=L^di>L]SL98silLx
+i
diff --git a/contrib/bc/tests/dc/errors/09.txt b/contrib/bc/tests/dc/errors/09.txt
new file mode 100644
index 000000000000..48c1e09bddda
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/09.txt
@@ -0,0 +1,22 @@
+#! /dc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsW#! /bin/dc
+0sm[Nx]0s_[]zsWx[li]zs^x[lili100>Nx]0sm[]zsWx[liNx]zsxx[li;rlilix]
+x[liN]zsWx[liNx]zsxx[li;rlilix]
+x[liNzsxx#! /bin/dc
+*sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]x]zsxx#! /bin/dc
+*sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsW#! /bipR
+00?00pR0.0pR
+.0000p0000000000000;0000000000.0pR
+.0000p00.000000;00000500000.0pR
+.0000p0000000000?00pR0.0pR
+.0000p0000000000000;0000000000.0pR
+.0000p00.000000;00000500000.0pR
+.0000p00000000000000000000000000000000000000000d000.0pR
+.0000p000000000000000000000000R
+.0000p02730pR
+00000pR0.0pR
+.0000p0000000000000000000000R
+.0000p00pR
diff --git a/contrib/bc/tests/dc/errors/10.txt b/contrib/bc/tests/dc/errors/10.txt
new file mode 100644
index 000000000000..5eb80178119a
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/10.txt
@@ -0,0 +1,19 @@
+#! /dc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nfvfff[]zsm[]zsWx[li]zsPx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]x[li]zsGx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsW#! /bin/dc
+0sm[Nx]0s_[]zsWx[li]zs^x[lili100>Nx]0sm[]zsWx[liNx]zsxx[li;rlilix]
+x[liNx]zsxx#! /bin/dc
+0sm[Nx]0sm[]zsWx[li]zsPx[Nxx]0sm[]x[li]zsGx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsW#!sdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsW#! /bin/dc
+0sm[Nx]0s_@]zsWx[li]zs^x[lili100>Nx]0sm[]zsWx[liNx]zsxx[li;rlilix]
+x[liNx]zsxx#! /bin/dc
+0sm[Nx]0sm[]zsWx[li]zsPx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]x[li]zsGx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsW#! /bin/dc
+0sm[Nx]0s_[]zsWx[li]zs^x[lili100>Nx]0sm[]zsWx[liNx]zsxx[li;rlilix]
+x[liNx]zsxx#! /bin/dc
+0sm[Nx]0sm[]zsWx[li]zsPx[Nx]0sm[]zsdc
+0sm[Nx]0sm[]zÂ…Wx[li]zsGd[Nx]0sm[]zsWx[li]zsGx[Nx]0sm[]zsW#! /Wx[li]zs^x[Nx]0s_[]zsWx[li]zs^x[lili100>Nx]0sm[]zs]0sm[]zsdc
diff --git a/contrib/bc/tests/dc/errors/11.txt b/contrib/bc/tests/dc/errors/11.txt
new file mode 100644
index 000000000000..b2fa5d291941
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/11.txt
@@ -0,0 +1,4 @@
+#! /bin/dc
+[[Done!]aa]sM[lip1-si0li>LeM]sL10silLx
+[[Done!]pR]sM[]sL10silLx
+[R]sM[lip=`eM]sL;Lx
diff --git a/contrib/bc/tests/dc/errors/12.txt b/contrib/bc/tests/dc/errors/12.txt
new file mode 100644
index 000000000000..711f970c8615
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/12.txt
@@ -0,0 +1,5 @@
+1;'9R 0si[lid1+silv14l*rliP+{Kla1;0>xli1+sililiSi1+sili14li?-si0!>x]li1162 2346dvdddd;ddddddddddddd?-sdddddddddd0+ddd 1+pR
+0dvdddd;ddSddddddddddd 0si[lid1+sil1sili14li?-si]dsxx[li;00!>x]li1162 2346dvddddddddddddddddddddddddd0 0+ddd 1+pR
+0 0 0+ddddvdddd;ddddddddddddddddddddddd;9R
+0!0 0+ddd 1+pR
+0
diff --git a/contrib/bc/tests/dc/errors/13.txt b/contrib/bc/tests/dc/errors/13.txt
new file mode 100644
index 000000000000..5737fd6d9a7c
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/13.txt
@@ -0,0 +1,17 @@
+zp198[Oelln, Wor\W!]pppppppppppppppR
+_1 _1(pR
+_1 _2(pR
+2 1{pR
+_1 1{pR 999+pR
+2374623 324869356734856+pR
+2378639084aaaaaaaaaaaaaaxaaaaaaaaaaaaaaR
+3729836720397239510836791082346529K084561329084561390845613409516734503870691837451 78562139198467134908618723249671349062187346898241093486139046139084613490817356023871869102746999999061872609129847+pR
+1.1 0+pR
+0 1.1+pR
+457283.731284923576 37842934672834.3874629385672354+pR
+1.0 0.1+pR
+3746289134067138046 0.138375863945R72398456712389456273486293+pR
+_1 _1+pR
+_4 _15+pR
+_1346782 _1287904651762468913476+pR
+99999999999999999999999999999999999999999999999999999999999.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999N9 0.000000000000000000000000000000000000ßßßßßßßßßßßßßßßßßßßßßßßßßßß000000000000000000000000000000000000000000000000000000000000000000000000000000000001+pR
diff --git a/contrib/bc/tests/dc/errors/14.txt b/contrib/bc/tests/dc/errors/14.txt
new file mode 100644
index 000000000000..c84b2b60ae06
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/14.txt
@@ -0,0 +1,7 @@
+0bpR
+1bpR
+.218933bpR
+138963.9873645bpR
+_19bpR
+_.1298376bpR
+_3892173.289375bpR: \ No newline at end of file
diff --git a/contrib/bc/tests/dc/errors/15.txt b/contrib/bc/tests/dc/errors/15.txt
new file mode 100644
index 000000000000..adb809dcca3d
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/15.txt
@@ -0,0 +1,11 @@
+0bpax1bpR
+1bpR
+.218933b987pR
+_19bp/98
+_38_.1/19bp38_.1/98
+_38921.1/98/98
+_38_.1/98
+_38921.1/98
+98
+_38921.1/98
+73.289 75bpu
diff --git a/contrib/bc/tests/dc/errors/16.txt b/contrib/bc/tests/dc/errors/16.txt
new file mode 100644
index 000000000000..1eef81b7317e
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/16.txt
@@ -0,0 +1,7 @@
+0 0;^dddddRps.R@s.16dddRRd^2ddRZ(b-P;;$p;;;;;;9;;;;;;$ppppppppppppp33
+_
+1 0+pR
+2 5+pR
+)37 =8M+p[
+999 999+ÿR
+237 \ No newline at end of file
diff --git a/contrib/bc/tests/dc/errors/17.txt b/contrib/bc/tests/dc/errors/17.txt
new file mode 100644
index 000000000000..dde24cc76040
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/17.txt
@@ -0,0 +1,21 @@
+0 1(pR
+1;;;;;pR
+1
+0 18d[963.9873R
+0 1894^666666696666666666PH66R]sM[liv1-si0li!<LpR
+_1 0{pR
+_1 _1{pR
+_1 f2872917389671.7573280963748_13784962873546.09287293954765~pRpR
+_23745861923467.874675129834675 _0.23542357869124756~pRpR
+_3878923750692883.7238596702834756902 _7384192674957215364986723.973F461923487621983~pRpR23873204 356489645223.76076045304879030~pRpR
+_35872917389671.75732809637
+1 0.071.75732809637
+1 0.000000000000000000000000000000000000000000000000000000000000000234672x37293735888888888888888888888888888888$88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888488888888<8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888884986723.973F461923487621983~pRpR23873204 356489645223.76076045304879030~pRpR
+_35872917389671.75732809637
+1 0.071.75732809637
+1 0.000000000000000000000000000000000000000000000000000000000000000234672837293735888888888888888888888888888888$88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888488888888<888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888S8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888Z888888888888
+_14pR
+=398NpR
+_2983
+48895 5067C 2i>LeM]sL1@silLx
+[[ \ No newline at end of file
diff --git a/contrib/bc/tests/dc/errors/18.txt b/contrib/bc/tests/dc/errors/18.txt
new file mode 100644
index 000000000000..685b251165db
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/18.txt
@@ -0,0 +1,3 @@
+1o VVf[li;WORli1S/Zli1;rORli1dH|2li@d-NliO+rK28729@9547628O745/pR
+_29307546189299999999999999999999999999999999999995 0.00000000000000000000000000009999999999999999999+99$9999999999.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995 0.0000000000000000000000000000000000R0000000000000000000000000000000000000+0000000000000000-0000000000000000000005+pR
+99999999999999999999999999999999999999999999999999999999999.999999999999999999999.99999999999999999999999999999999999999999900000000000000000000000R0000000000000000000000000000000000000+0000000000000000-0000000000000000000005+pR999999999999999999999999999999999999999999 0.00000000000000000000000000000000000000000000000000000000000C0020P00000000000000000000000000000000000007fli1+7fli1+si;d7dli1+si;r=Rls1d:Mli +i100>x]dsxx[l!Wxr>x]dsxx[p!Wx]li17396719 00000000001+pR
diff --git a/contrib/bc/tests/dc/errors/19.txt b/contrib/bc/tests/dc/errors/19.txt
new file mode 100644
index 000000000000..defb1546c625
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/19.txt
Binary files differ
diff --git a/contrib/bc/tests/dc/errors/20.txt b/contrib/bc/tests/dc/errors/20.txt
new file mode 100644
index 000000000000..e6126f0b39f2
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/20.txt
@@ -0,0 +1,9 @@
+#!rpR
+I21PPrP PPPP PPsPdaP1:bpR
+ PPPPdPP1d:bpRR
+I21PPrP PPPP PPsPdaP1:bpR
+ PPPPdPP asrp#! asrpR
+I21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PPPPdPP1d:bpRR
+I21PPrP PPPP PPsPdaP1:bpR
+ PPPPdPP asrp#! asrpR
+I21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Y;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;>;;;;;;;;;;;;2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Y;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file
diff --git a/contrib/bc/tests/dc/errors/21.txt b/contrib/bc/tests/dc/errors/21.txt
new file mode 100644
index 000000000000..1a6e5c05b0ce
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/21.txt
@@ -0,0 +1,7 @@
+0bpR
+1bpR
+.218933bpR
+138963.9873645bpR
+S19bpR
+_.1298376bpR
+_3892173.289375bpR
diff --git a/contrib/bc/tests/dc/errors/22.txt b/contrib/bc/tests/dc/errors/22.txt
new file mode 100644
index 000000000000..23d5e2c37808
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/22.txt
@@ -0,0 +1,37 @@
+[Hello, World!]ZpR
+[HepR
+[Hello, \[ World!]pR
+[Hello, \] World!]ZpR
+[Hello, \] World!]pR
+[30pR]
+f29pR]
+[28pR]
+[27pR]
+[26pR]
+[25pR]
+[24pR]
+[23pR]
+[22pR]
+[21pR]
+[20pR]
+[19pR]
+[18pR]
+[17pR]
+[16pR]
+[15pR]
+[14pR]
+[13pR]
+[12pR]
+[11pR]
+[10pR]
+[9pR]
+[8pR]
+[7pR]
+[6pR]
+[5pR]
+[4pR]
+[3pR]
+[2pR]
+[1pR]
+[xz0<x]dsxx
+[\ \ No newline at end of file
diff --git a/contrib/bc/tests/dc/errors/23.txt b/contrib/bc/tests/dc/errors/23.txt
new file mode 100644
index 000000000000..bba814851f94
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/23.txt
Binary files differ
diff --git a/contrib/bc/tests/dc/errors/24.txt b/contrib/bc/tests/dc/errors/24.txt
new file mode 100644
index 000000000000..cc0750c6fd35
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/24.txt
@@ -0,0 +1 @@
+ [] 0:xX:i 0:iX:in/dc.873C45}pR
diff --git a/contrib/bc/tests/dc/errors/25.txt b/contrib/bc/tests/dc/errors/25.txt
new file mode 100644
index 000000000000..24740cab6f4c
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/25.txt
@@ -0,0 +1,7 @@
+#! /bin/dc
+0si[lid:rli1;rd:rli1;rpRli1+sili10>x]dsxx0sx0si
+1 2
+si[lid:rli1;rd:rli1;rpRli1+sili10>x]dsxx0sx0si
+1 2
+ÿ€
+
diff --git a/contrib/bc/tests/dc/errors/26.txt b/contrib/bc/tests/dc/errors/26.txt
new file mode 100644
index 000000000000..0d68e5db9454
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/26.txt
@@ -0,0 +1,222 @@
+0bpR
+1bp0
+.23bpR
+138963.9873645bpR
+_19bpR
+_.1298[li;i;rpRli1+sili10>x]dsxx0sx0si
+1 2+p+p
+3+p
+4+p
+5+p
+6+p
+7+p
+8+p
+9+p
+10+p
+11+p
+12+p
+13+p
+14+p
+15+p
+16+p
+17+p
+18+p
+19+p
+20+p
+21+0+p
+71+o
+72+p
+73+p
+74+p
+75+p
+22+p
+23+p
+24+p
+25+p
+26+p
+27+p
+28+p
+29+p
+30+p
+31+p
+32+p
+33+p
+34+p
+35+p
+36+p
+37+p
+38+p
+39+p
+40+1+p
+42+p
+43+p
+44+p
+45+p
+46+p
+47+p
+48+p
+49+p
+50+p
+51+p
+52+p
+53+p
+54+p
+55+p
+56+p
+57+p
+58+p
+59+p
+60+p
+61+p
+60bpR
+1bp0
+.23bpR
+138963.9873645bpR
+_19bpR
+_.1298[li;i;rpRli1+sili10>x]dsxx0sx0si
+1 2+p+p
+3+p
+4+p
+5+p
+6+p
+7+p
+8+p
+9+p
+10+p
+11+p
+12+p
+13+p
+14+p
+15+p
+16+p
+17+p
+18+p
+19+p
+20+p
+21+0+p
+71+o
+72+p
+73+p
+74+p
+75+p
+22+p
+23+p
+24+p
+25+p
+26+p
+27+p
+28+p
+29+p
+30+p
+31+p
+32+p
+33+p
+34+p
+35+p
+36+p
+37+p
+38+p
+39+p
+40+1+p
+42+p
+43+p
+44+p
+45+p
+46+p
+47+p
+48+p
+49+p
+50+p
+51+p
+52+p
+53+p
+54+p
+55+p
+56+p
+57+p
+58+p
+59+p
+60+p
+61+p
+62+p
+63+p
+64+p
+65+p
+66+p
+67
+73+p
+74+p
+75+p
+76+p
+77+p
+78+p
+79+p
+80+p
+È1+p
+82+p
+83+p
+84+p
+85+pç86+p
+87+p
+88+p
+89+p
+90+p
+91+p
+92+p
+93+p
+94+p
+95+p
+96+p
+97+p
+98+p
+99+p
+100+p
+101+p
+102+p
+103+p
+104+p
+105+p
+106+p
+107+p
+108+p
+109–––––––––––––––––––––––––––3+p2+p
+63+p
+64+p
+65+p
+66+p
+67
+73+p
+74+p
+75+p
+76+p
+77+p
+78+p
+79+pþ80+p
+81+p
+82+p
+83+p
+84+p
+85+pç86+p
+87+p
+88+p
+89+p
+90+p
+91+p
+92+p
+93+p
+94+p
+95+p
+96+p
+97+p
+98+p
+99+p
+100+p
+101+p
+102+p
+103+p
+304+p
+105+p
+106+p
+107+p
+108+p
+109–––––––––––––––––––––––––––3+p
diff --git a/contrib/bc/tests/dc/errors/27.txt b/contrib/bc/tests/dc/errors/27.txt
new file mode 100644
index 000000000000..32a3088db8aa
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/27.txt
@@ -0,0 +1,2 @@
+" 1(pR,129bp\
+
diff --git a/contrib/bc/tests/dc/errors/28.txt b/contrib/bc/tests/dc/errors/28.txt
new file mode 100644
index 000000000000..b6dd1d3695cb
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/28.txt
@@ -0,0 +1,2 @@
+15 4%0:i [2nd] 1:b 0;C p 1;b0:b [2nd] 1:b 0;b p 1;b~~~b 0;b p 1;b~~~0k
+1
diff --git a/contrib/bc/tests/dc/errors/29.txt b/contrib/bc/tests/dc/errors/29.txt
new file mode 100644
index 000000000000..696260536798
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/29.txt
@@ -0,0 +1,20 @@
+15 4%0:b [2nd] 1:b 0;b 1;b X
+ 27239 1%pR
+3460:b [2nd] 1:b 0;b p bpR
+.2 1%pR
+6 4%pR
+15 4%0:b [2nd] 1:b 0;b p 1;b X
+ 27239 1%pR
+b 0;b p 1;b2
+1bpb [2nd] 1:u 0;b p 1;b X
+ 2
+[1st] 0:b [2nd] 1:b 0;b p S;b p
+[string]XpR
+[3 4^p]silix
+[[[q 1 3+pR]Ú]x]x4 5^pR
+4xpR
+5 112ax 90ax 112ax 82ax
+ pR
+[q\\] pR
+[\\] pR
+92 a pR
diff --git a/contrib/bc/tests/dc/misc.txt b/contrib/bc/tests/dc/misc.txt
new file mode 100644
index 000000000000..c1e7f9fd4070
--- /dev/null
+++ b/contrib/bc/tests/dc/misc.txt
@@ -0,0 +1,2 @@
+zp198202389.289374pzp[Hello, World!]pzpzpfrfczpfR
+1n1pR
diff --git a/contrib/bc/tests/dc/misc_results.txt b/contrib/bc/tests/dc/misc_results.txt
new file mode 100644
index 000000000000..512944a3fc1f
--- /dev/null
+++ b/contrib/bc/tests/dc/misc_results.txt
@@ -0,0 +1,21 @@
+0
+198202389.289374
+2
+Hello, World!
+4
+5
+5
+4
+Hello, World!
+2
+198202389.289374
+0
+4
+5
+Hello, World!
+2
+198202389.289374
+0
+0
+0
+11
diff --git a/contrib/bc/tests/dc/modexp.txt b/contrib/bc/tests/dc/modexp.txt
new file mode 100644
index 000000000000..a6afb998558e
--- /dev/null
+++ b/contrib/bc/tests/dc/modexp.txt
@@ -0,0 +1,103 @@
+0 0 1|pR
+1 0 1|pR
+1 0 2|pR
+0 10 1|pR
+1 293 1|pR
+1 2789365 2|pR
+100 8 7|pR
+10922384 15031007 201|pR
+3346529 189 254|pR
+4113416930 197 14|pR
+7709 5887 111|pR
+5487406 3252 128|pR
+2080527 2279453822 219|pR
+48895 50678 232|pR
+1535808383 2902995144 18|pR
+8437837 2882198 69|pR
+35363 25806 2|pR
+3221177403 1560419989 189|pR
+227 42775 163|pR
+2811398069 37500 173|pR
+15046850 3859895697 195|pR
+15770756 3621999893 119|pR
+6937927 3719297189 183|pR
+12573 43819 209|pR
+42098463 7584603 136|pR
+8656683 1328292415 226|pR
+209 81 157|pR
+141 13317429 26|pR
+809485795 60745 101|pR
+4882 1388217898 38|pR
+750704 78 119|pR
+668879580 2888860497 179|pR
+1152725844 15295742 154|pR
+16160694 8981529 154|pR
+216 102 3|pR
+3691227289 5344109 232|pR
+2195559299 61 222|pR
+2478990626 13007440 30|pR
+45083 44 117|pR
+224 55824 53|pR
+1372700133 89 94|pR
+205 10422 48|pR
+11887 12 73|pR
+5955 24353 114|pR
+1201697310 789722419 6|pR
+56577 231 229|pR
+96 38841 189|pR
+6529661 5636520 209|pR
+11005 15955685 27|pR
+9709 231 132|pR
+59790 1034579699 166|pR
+47892 14536879 79|pR
+48 208 21|pR
+33036 3877 65|pR
+164 6527085 249|pR
+12146850 224 37|pR
+218 16425679 62|pR
+51 27641 95|pR
+3076735605 49154 32|pR
+515652717 4117874315 143|pR
+300672671 720768884 110|pR
+9422066 206 5|pR
+43 97 13|pR
+545174510 65319 126|pR
+3317462730 704990271 51|pR
+47316 23231 202|pR
+7236571 4379567 106|pR
+2584584521 2459274189 29|pR
+61562 5035178 178|pR
+65302 112 151|pR
+63040 2168854052 213|pR
+9039611 2370306559 62|pR
+16414384 1020652061 83|pR
+7491 3853569905 172|pR
+1180322494 46670 84|pR
+3823343557 3865107254 127|pR
+6240872 55335 39|pR
+2281401897 1098411 251|pR
+61 2949190429 231|pR
+8981024 162 43|pR
+1 3568883218 212|pR
+4217100969 3471787779 8|pR
+3232237 13 243|pR
+29280 3972452706 100|pR
+13077 6431923 216|pR
+104 3098510775 140|pR
+9503298 174 242|pR
+3424695712 12184 23|pR
+184 15066347 151|pR
+2935856 14003205 184|pR
+1386637762 2128151420 71|pR
+154 11960656 12|pR
+743976432 4004778779 136|pR
+3909160595 3575680922 21|pR
+26133 3580 147|pR
+409154 170 68|pR
+149 55629 40|pR
+5753 13776176 32|pR
+3831447473 658273178 98|pR
+1527252003 2300622 207|pR
+3363824553 8244645 215|pR
+20 145 101|pR
+4005077294 2196555621 94|pR
diff --git a/contrib/bc/tests/dc/modexp_results.txt b/contrib/bc/tests/dc/modexp_results.txt
new file mode 100644
index 000000000000..5bf0f146e967
--- /dev/null
+++ b/contrib/bc/tests/dc/modexp_results.txt
@@ -0,0 +1,103 @@
+1
+1
+1
+0
+0
+1
+4
+74
+1
+0
+98
+0
+72
+1
+1
+1
+1
+108
+36
+52
+65
+8
+181
+22
+7
+123
+93
+21
+17
+20
+1
+108
+58
+22
+0
+105
+161
+16
+40
+15
+45
+25
+64
+69
+0
+225
+27
+1
+22
+73
+92
+38
+15
+16
+173
+33
+32
+21
+25
+109
+71
+1
+4
+62
+15
+90
+29
+5
+40
+84
+40
+53
+8
+31
+64
+44
+14
+13
+145
+1
+1
+1
+76
+0
+189
+104
+192
+9
+119
+56
+45
+4
+32
+16
+135
+4
+29
+1
+49
+0
+128
+6
+18
diff --git a/contrib/bc/tests/dc/modulus.txt b/contrib/bc/tests/dc/modulus.txt
new file mode 100644
index 000000000000..613944b2001a
--- /dev/null
+++ b/contrib/bc/tests/dc/modulus.txt
@@ -0,0 +1,70 @@
+20k
+1 1%pR
+2 1%pR
+16 4%pR
+15 4%pR
+17 4%pR
+2389473 5%pR
+39240687239 1%pR
+346728934 23958%pR
+3496723859067234 298375462837546928347623059375486%pR
+_1 1%pR
+_2 1%pR
+_47589634875689345 37869235%pR
+_1274852934765 2387628935486273546%pR
+_6324758963 237854962%pR
+1 _1%pR
+2 _1%pR
+2 _2%pR
+2 _3%pR
+16 5%pR
+15 5%pR
+14 5%pR
+89237423 _237856923854%pR
+123647238946 _12467%pR
+_1 _1%pR
+_2 _1%pR
+_2 _2%pR
+_2 _3%pR
+_13 _7%pR
+_14 _7%pR
+_15 _7%pR
+_12784956 _32746%pR
+_127849612 _23712347682193%pR
+0k
+1 1%pR
+2 1%pR
+16 4%pR
+15 4%pR
+17 4%pR
+2389473 5%pR
+39240687239 1%pR
+346728934 23958%pR
+3496723859067234 298375462837546928347623059375486%pR
+_1 1%pR
+_2 1%pR
+_47589634875689345 37869235%pR
+_1274852934765 2387628935486273546%pR
+_6324758963 237854962%pR
+1 _1%pR
+2 _1%pR
+2 _2%pR
+2 _3%pR
+16 5%pR
+15 5%pR
+14 5%pR
+89237423 _237856923854%pR
+123647238946 _12467%pR
+_1 _1%pR
+_2 _1%pR
+_2 _2%pR
+_2 _3%pR
+_13 _7%pR
+_14 _7%pR
+_15 _7%pR
+_12784956 _32746%pR
+_127849612 _23712347682193%pR
+_3191280681 641165986%pR
+0k _899510228 _2448300078.40314%pR
+0k _7424863 _207.2609738667%pR
+0k 3769798918 0.6%pR
diff --git a/contrib/bc/tests/dc/modulus_results.txt b/contrib/bc/tests/dc/modulus_results.txt
new file mode 100644
index 000000000000..7d718d22a439
--- /dev/null
+++ b/contrib/bc/tests/dc/modulus_results.txt
@@ -0,0 +1,68 @@
+0
+0
+0
+0
+0
+0
+0
+.00000000000000002026
+2747189239559.46904933397471305894
+0
+0
+-.00000000000011057855
+-.00076922992566770712
+-.00000000000050364144
+0
+0
+0
+.00000000000000000002
+0
+0
+0
+.00000000070585524350
+.00000000000000002898
+0
+0
+0
+-.00000000000000000002
+-.00000000000000000005
+0
+-.00000000000000000002
+-.00000000000000011722
+-.00000002640923745817
+0
+0
+0
+3
+1
+3
+0
+8758
+3496723859067234
+0
+0
+-8236960
+-1274852934765
+-140529951
+0
+0
+0
+2
+1
+0
+4
+89237423
+6692
+0
+0
+0
+-2
+-6
+0
+-1
+-14016
+-127849612
+-626616737
+-899510228.00000
+-153.1331732059
+.4
diff --git a/contrib/bc/tests/dc/multiply.txt b/contrib/bc/tests/dc/multiply.txt
new file mode 100644
index 000000000000..b4faac28b243
--- /dev/null
+++ b/contrib/bc/tests/dc/multiply.txt
@@ -0,0 +1,43 @@
+0k
+0 0*pR
+0.000 0*pR
+1 0*pR
+0 1*pR
+0 2498752389672835476*pR
+873246913745129084576134 0*pR
+1 472638590273489273456*pR
+12374861230476103672835496 1*pR
+1 1*pR
+2 1*pR
+1 2*pR
+2 2*pR
+3 14*pR
+17 8*pR
+1892467513846753 1872439821374591038746*pR
+328962735862.2973546835638947635 1728465791348762356*pR
+38745962374538.387427384672934867234 0.1932476528394672837568923754*pR
+9878894576289457634856.2738627161689017387608947567654 37842939768237596237854203.29874372139852739126739621793162*pR
+_1 1*pR
+_1 2*pR
+78893457 _34876238956*pR
+235678324957634 _0.2349578349672389576*pR
+_12849567821934 12738462937681*pR
+1274861293467.927843682937462 _28935678239*pR
+2936077239872.12937462836 _0.012842357682435762*pR
+2387692387566.2378569237546 _272189345628.123875629835876*pR
+0.012348629356782835962 _23487692356*pR
+0.4768349567348675934 _0.23756834576934857638495*pR
+0.98748395367485962735486 _4675839462354867.376834956738456*pR
+_321784627934586 _235762378596*pR
+_32578623567892356 _0.32567384579638456*pR
+_35768232346876 _2348672935602387620.28375682349576237856*pR
+_0.2356728394765234 _238759624356978*pR
+_0.2345768212346780 _0.235768124697074385948943532045*pR
+_0.370873860736785306278630 _7835678398607.7086378076867096270*pR
+_78365713707.7089637863786730 _738580798679306780*pR
+_73867038956790490258249 _0.7379862716391723672803679*pR
+_378621971598721837710387 _98465373878350798.09743896037963078560*pR
+37164201 2931559660*pR
+679468076118972457796560530571.46287161642138401685 93762.2836*pR
+.000000000000000000000000001 .0000000000000000000000001*pR
+239 289 _98 .8937 _.1893 28937*****pR
diff --git a/contrib/bc/tests/dc/multiply_results.txt b/contrib/bc/tests/dc/multiply_results.txt
new file mode 100644
index 000000000000..9666059a5848
--- /dev/null
+++ b/contrib/bc/tests/dc/multiply_results.txt
@@ -0,0 +1,43 @@
+0
+0
+0
+0
+0
+0
+472638590273489273456
+12374861230476103672835496
+1
+2
+2
+4
+42
+136
+3543531533584430580556128344529291738
+568600835566479683035874339053.4411638427543228060
+7487566285885.8557453089005171423976251098
+373846412427291014394738378015501363938345620046.7869650248829232267\
+2297002026819
+-1
+-2
+-2751507058396910892
+-55374468980751.0837656919743223184
+-163683743464924630346895054
+-36888976187143312550878.567134791289418
+-37706154097.696628262157533781
+-649904428532907022680241.947918694247541
+-290040807.350385412976669306472
+-.11328089187650139309272
+-4617316439035114.40320367843985107357898
+75864709277486862054521256
+10610005628108234.92015040406042336
+84007879267445533366251128067927.91168012197674537856
+56269158624557.1027018519702852
+.055305737239900889424090264801
+2906048299183.472237078104362540110129
+57879411419313585866282299201.3825582163029400
+54512860676747314187949.9414724679950990587298071
+37281153992026463004361915151761464058058.54968338992209002720
+108949072447731660
+63708478450213482928510139572007971.83536929222529239687
+0
+33137343861.8586
diff --git a/contrib/bc/tests/dc/negate.txt b/contrib/bc/tests/dc/negate.txt
new file mode 100644
index 000000000000..f4a3825ec72f
--- /dev/null
+++ b/contrib/bc/tests/dc/negate.txt
@@ -0,0 +1,3 @@
+1_pR
+2_pR
+129837.218092_pR
diff --git a/contrib/bc/tests/dc/negate_results.txt b/contrib/bc/tests/dc/negate_results.txt
new file mode 100644
index 000000000000..e58abbf70d91
--- /dev/null
+++ b/contrib/bc/tests/dc/negate_results.txt
@@ -0,0 +1,3 @@
+-1
+-2
+-129837.218092
diff --git a/contrib/bc/tests/dc/places.txt b/contrib/bc/tests/dc/places.txt
new file mode 100644
index 000000000000..9ba686e2d628
--- /dev/null
+++ b/contrib/bc/tests/dc/places.txt
@@ -0,0 +1,16 @@
+0 0@pR
+1 0@pR
+2 0@pR
+0.0023896 0@pR
+1.298346 0@pR
+2.00000000 0@pR
+0.0023896 3@pR
+1.298346 4@pR
+2.00000000 5@pR
+289 3@pR
+18.34 6@pR
+_183.1 0@pR
+_23.238 8@pR
+_343.23 2@pR
+_.1897263 0@pR
+.1982365 0@pR
diff --git a/contrib/bc/tests/dc/places_results.txt b/contrib/bc/tests/dc/places_results.txt
new file mode 100644
index 000000000000..1ca49ae89932
--- /dev/null
+++ b/contrib/bc/tests/dc/places_results.txt
@@ -0,0 +1,16 @@
+0
+1
+2
+0
+1
+2
+.002
+1.2983
+2.00000
+289.000
+18.340000
+-183
+-23.23800000
+-343.23
+0
+0
diff --git a/contrib/bc/tests/dc/power.txt b/contrib/bc/tests/dc/power.txt
new file mode 100644
index 000000000000..7e75a91c78a3
--- /dev/null
+++ b/contrib/bc/tests/dc/power.txt
@@ -0,0 +1,44 @@
+20k
+0 0^pR
+0 1^pR
+0 1894^pR
+1 0^pR
+39746823 0^pR
+0.238672983047682 0^pR
+18394762374689237468.97354862973846 0^pR
+1 1^pR
+2 1^pR
+18927361346 1^pR
+0.23523785962738592635777 1^pR
+328956734869213746.89782398457234 1^pR
+8937 98^pR
+0.124876812394 2396^pR
+93762.2836 13^pR
+1 _1^pR
+2 _1^pR
+10 _1^pR
+683734768 _1^pR
+38579623756.897937568235 _1^pR
+1 _32467^pR
+2 _53^pR
+23897 _213^pR
+_1 1^pR
+_1 2^pR
+_2 1^pR
+_2 2^pR
+_237 294^pR
+_3746 28^pR
+_0.3548 35^pR
+_4267.234 37^pR
+_326.3246 78^pR
+_1 _1^pR
+_1 _2^pR
+_2 _1^pR
+_2 _2^pR
+_237 _293^pR
+_784 _23^pR
+_86 _7^pR
+_0.23424398 _781^pR
+_178.234786 _879^pR
+_1274.346 _768^pR
+_0.2959371298 227^pR
diff --git a/contrib/bc/tests/dc/power_results.txt b/contrib/bc/tests/dc/power_results.txt
new file mode 100644
index 000000000000..280347a9f258
--- /dev/null
+++ b/contrib/bc/tests/dc/power_results.txt
@@ -0,0 +1,72 @@
+1
+0
+0
+1
+1
+1
+1
+1
+2
+18927361346
+.23523785962738592635777
+328956734869213746.89782398457234
+16473742664221279051571200630760751138799221376964991600670000200609\
+08006052596520320731708604393844468006290371918262741885989163144389\
+39367835091560809036359941703341471396407660150658436796925310445979\
+21333166245765946557344383284626113908419359990042883048537750217279\
+17481980123593363177308481941550382845381799410533956718500484099889\
+610805653325917409549921909941664118421333562129
+0
+43287877285033571298394739716218787350087163435619825150259705419.98\
+016445740928054425
+1.00000000000000000000
+.50000000000000000000
+.10000000000000000000
+.00000000146255543348
+.00000000002592041867
+1.00000000000000000000
+.00000000000000011102
+0
+-1
+1
+-2
+4
+14997322375665265051328725757939209353051902095893907150382724666290\
+49749481660976421019742616298227588464420182758442163654172400528243\
+00885441207762486233574213374503090372518590691583139696652847404883\
+08573912261119588874308960204159666762789603037188471170006223907416\
+60492840269152716750700089148882139254399347568222390231015487895905\
+73727080561379177721440905866857248917982113340543176658480139248897\
+54802503253413282808814063861470711399810899724515727713334909764746\
+27910290211411231279325882505708287941671508154740003122373284699097\
+78346501539634198926772266511968381368929692275950529960923432771985\
+12597189390708050983487158873301681237787429436264801751664042999180\
+3448659818912436089
+11478830555358864333472551120140548480416206583184496764727387456058\
+792742209537931243951391229607936
+-.00000000000000017759
+-2067373624686414405470850679965010694114490999957199847684803894306\
+56243666149296582304582679590231948238805965642713928910384741502707\
+.23224479257866798694
+11606078892843496082360561256965139908586179418605021706789617179085\
+85768049299693425729565480314913006780973928345684673490252494674985\
+0186164225375953066263609289359900615361965737717208159874390.293769\
+70206344604971
+-1.00000000000000000000
+1.00000000000000000000
+-.50000000000000000000
+.25000000000000000000
+0
+0
+-.00000000000002874159
+-1945134149489344891879057554905782841936258356736314337975569799825\
+94091939572752348215929683891336730843553721422164737465108229034947\
+87333189564755763444242676978610321731298729194092653999616928308494\
+26419468484566422775668903315088810746121307679948574976162519479931\
+18935243698160094347216562490000767121041786977792546155155934655909\
+14123833869470494708767968978717730012864171105540029928688274136791\
+98175053824022144065005509214813689232148489884560100200475909009813\
+340098100705258138.98542904577525702068
+0
+0
+0
diff --git a/contrib/bc/tests/dc/rand.txt b/contrib/bc/tests/dc/rand.txt
new file mode 100644
index 000000000000..250da02db3c8
--- /dev/null
+++ b/contrib/bc/tests/dc/rand.txt
@@ -0,0 +1 @@
+J ss ' sr lr " st ls j ' lr GpR lr " lt GpR W W GpR
diff --git a/contrib/bc/tests/dc/rand_results.txt b/contrib/bc/tests/dc/rand_results.txt
new file mode 100644
index 000000000000..e8183f05f5db
--- /dev/null
+++ b/contrib/bc/tests/dc/rand_results.txt
@@ -0,0 +1,3 @@
+1
+1
+1
diff --git a/contrib/bc/tests/dc/read.txt b/contrib/bc/tests/dc/read.txt
new file mode 100644
index 000000000000..9204d0a378e0
--- /dev/null
+++ b/contrib/bc/tests/dc/read.txt
@@ -0,0 +1 @@
+3 4^pR
diff --git a/contrib/bc/tests/dc/read_errors.txt b/contrib/bc/tests/dc/read_errors.txt
new file mode 100644
index 000000000000..dd2f324e235d
--- /dev/null
+++ b/contrib/bc/tests/dc/read_errors.txt
@@ -0,0 +1,2 @@
+
+?
diff --git a/contrib/bc/tests/dc/read_results.txt b/contrib/bc/tests/dc/read_results.txt
new file mode 100644
index 000000000000..d88e31369987
--- /dev/null
+++ b/contrib/bc/tests/dc/read_results.txt
@@ -0,0 +1 @@
+81
diff --git a/contrib/bc/tests/dc/scientific.txt b/contrib/bc/tests/dc/scientific.txt
new file mode 100644
index 000000000000..59a78dbb3a6c
--- /dev/null
+++ b/contrib/bc/tests/dc/scientific.txt
@@ -0,0 +1,51 @@
+0e0pR
+0e1pR
+0e5pR
+0e_2pR
+0e_100pR
+1e0pR
+_1e1pR
+1e9pR
+_1e21pR
+1e_1pR
+_1e_2pR
+1e_5pR
+4.92837e5pR
+_3.28971028e20pR
+6.2e3pR
+_8.289371e2pR
+5.9817280937e8pR
+_3.28977e_1pR
+8.8927891e_20pR
+_7.98239e_4pR
+4.4892e_4pR
+_18937e0pR
+198273e10pR
+_18927e_4pR
+28937e_5pR
+_891072e_7pR
+.28972e0pR
+_.891273e_1pR
+.8928397e1pR
+_.0002983172e5pR
+.00022e3pR
+_.00022e4pR
+.0000328937e8pR
+0o
+0pR
+1pR
+10pR
+_289pR
+2894pR
+_89434pR
+894370pR
+_1239839pR
+28931708pR
+_8052098.8029731809pR
+.1pR
+_.01pR
+.001pR
+_.00038pR
+.0000483pR
+_.0002894378190pR
+.2893712083pR
diff --git a/contrib/bc/tests/dc/scientific_results.txt b/contrib/bc/tests/dc/scientific_results.txt
new file mode 100644
index 000000000000..557fcf61fe5e
--- /dev/null
+++ b/contrib/bc/tests/dc/scientific_results.txt
@@ -0,0 +1,50 @@
+0
+0
+0
+0
+0
+1
+-10
+1000000000
+-1000000000000000000000
+.1
+-.01
+.00001
+492837
+-328971028000000000000
+6200
+-828.9371
+598172809.37
+-.328977
+.000000000000000000088927891
+-.000798239
+.00044892
+-18937
+1982730000000000
+-1.8927
+.28937
+-.0891072
+.28972
+-.0891273
+8.928397
+-29.83172
+.22
+-2.2
+3289.37
+0
+1e0
+1.0e1
+-2.89e2
+2.894e3
+-8.9434e4
+8.94370e5
+-1.239839e6
+2.8931708e7
+-8.0520988029731809e6
+1e-1
+-1e-2
+1e-3
+-3.8e-4
+4.83e-5
+-2.894378190e-4
+2.893712083e-1
diff --git a/contrib/bc/tests/dc/scripts/array.dc b/contrib/bc/tests/dc/scripts/array.dc
new file mode 100755
index 000000000000..5accb118eb69
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/array.dc
@@ -0,0 +1,3 @@
+#! /usr/bin/dc
+0si[lid:rli1+sili100>x]dsxxli1-si[li;rpRli1-sili0!>x]dsxxli1+si[li;rpRli1+sili100>x]dsxx
+0 0:a 1 1:a 2 2:a 0;a 1;a 2;a |pR
diff --git a/contrib/bc/tests/dc/scripts/array.txt b/contrib/bc/tests/dc/scripts/array.txt
new file mode 100644
index 000000000000..a0a2fd6f9d30
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/array.txt
@@ -0,0 +1,201 @@
+99
+98
+97
+96
+95
+94
+93
+92
+91
+90
+89
+88
+87
+86
+85
+84
+83
+82
+81
+80
+79
+78
+77
+76
+75
+74
+73
+72
+71
+70
+69
+68
+67
+66
+65
+64
+63
+62
+61
+60
+59
+58
+57
+56
+55
+54
+53
+52
+51
+50
+49
+48
+47
+46
+45
+44
+43
+42
+41
+40
+39
+38
+37
+36
+35
+34
+33
+32
+31
+30
+29
+28
+27
+26
+25
+24
+23
+22
+21
+20
+19
+18
+17
+16
+15
+14
+13
+12
+11
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+0
diff --git a/contrib/bc/tests/dc/scripts/asciify.dc b/contrib/bc/tests/dc/scripts/asciify.dc
new file mode 100755
index 000000000000..7db61210c831
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/asciify.dc
@@ -0,0 +1,7 @@
+#! /usr/bin/dc
+# To compare:
+# cmp -l .log_dc.txt .log_dc_test.txt | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'
+_48apR
+20k
+1 1%aR
+0si[liapRlid1+sili65536>x]ddsxapRx
diff --git a/contrib/bc/tests/dc/scripts/asciify.txt b/contrib/bc/tests/dc/scripts/asciify.txt
new file mode 100644
index 000000000000..a6af215aa0ea
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/asciify.txt
Binary files differ
diff --git a/contrib/bc/tests/dc/scripts/else.dc b/contrib/bc/tests/dc/scripts/else.dc
new file mode 100755
index 000000000000..84deb8754e9f
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/else.dc
@@ -0,0 +1,4 @@
+#! /usr/bin/dc
+[[Done!]pR]sM[lip1-si0li>LeM]sL10silLx
+[[Done!]pR]sM[lip1-si0li!<LeM]sL10silLx
+[[Done!]pR]sM[lip1-si0li!=LeM]sL10silLx
diff --git a/contrib/bc/tests/dc/scripts/else.txt b/contrib/bc/tests/dc/scripts/else.txt
new file mode 100644
index 000000000000..e5c082bd5ac9
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/else.txt
@@ -0,0 +1,34 @@
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
+Done!
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
+0
+Done!
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
+Done!
diff --git a/contrib/bc/tests/dc/scripts/factorial.dc b/contrib/bc/tests/dc/scripts/factorial.dc
new file mode 100755
index 000000000000..6a751bf61352
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/factorial.dc
@@ -0,0 +1,4 @@
+#! /usr/bin/dc
+[lb1+dsb*plb50>x]sx
+0sb1
+lxx
diff --git a/contrib/bc/tests/dc/scripts/factorial.txt b/contrib/bc/tests/dc/scripts/factorial.txt
new file mode 100644
index 000000000000..0bd3a30f1556
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/factorial.txt
@@ -0,0 +1,50 @@
+1
+2
+6
+24
+120
+720
+5040
+40320
+362880
+3628800
+39916800
+479001600
+6227020800
+87178291200
+1307674368000
+20922789888000
+355687428096000
+6402373705728000
+121645100408832000
+2432902008176640000
+51090942171709440000
+1124000727777607680000
+25852016738884976640000
+620448401733239439360000
+15511210043330985984000000
+403291461126605635584000000
+10888869450418352160768000000
+304888344611713860501504000000
+8841761993739701954543616000000
+265252859812191058636308480000000
+8222838654177922817725562880000000
+263130836933693530167218012160000000
+8683317618811886495518194401280000000
+295232799039604140847618609643520000000
+10333147966386144929666651337523200000000
+371993326789901217467999448150835200000000
+13763753091226345046315979581580902400000000
+523022617466601111760007224100074291200000000
+20397882081197443358640281739902897356800000000
+815915283247897734345611269596115894272000000000
+33452526613163807108170062053440751665152000000000
+1405006117752879898543142606244511569936384000000000
+60415263063373835637355132068513997507264512000000000
+2658271574788448768043625811014615890319638528000000000
+119622220865480194561963161495657715064383733760000000000
+5502622159812088949850305428800254892961651752960000000000
+258623241511168180642964355153611979969197632389120000000000
+12413915592536072670862289047373375038521486354677760000000000
+608281864034267560872252163321295376887552831379210240000000000
+30414093201713378043612608166064768844377641568960512000000000000
diff --git a/contrib/bc/tests/dc/scripts/loop.dc b/contrib/bc/tests/dc/scripts/loop.dc
new file mode 100755
index 000000000000..26cec23818df
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/loop.dc
@@ -0,0 +1,3 @@
+#! /usr/bin/dc
+[lip1-si0li>L]sL10silLx
+[lip1+si10li<L]sL0silLx
diff --git a/contrib/bc/tests/dc/scripts/loop.txt b/contrib/bc/tests/dc/scripts/loop.txt
new file mode 100644
index 000000000000..4029c2f0c126
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/loop.txt
@@ -0,0 +1,20 @@
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
diff --git a/contrib/bc/tests/dc/scripts/prime.dc b/contrib/bc/tests/dc/scripts/prime.dc
new file mode 100755
index 000000000000..cc769d2bbee1
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/prime.dc
@@ -0,0 +1 @@
+0k2p3p[dl!d2+s!%0=@l!l^!<#]s#[s/0ds^]s@[p]s&[ddvs^3s!l# x0<&2+d100000>.]ds.x
diff --git a/contrib/bc/tests/dc/scripts/quit.dc b/contrib/bc/tests/dc/scripts/quit.dc
new file mode 100755
index 000000000000..81e6289af25b
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/quit.dc
@@ -0,0 +1,2 @@
+1se [li p 1+si le li !=lem]sl [lk p 1+sk le lk !=o]so [0sk lox leQ 0sk lox le 3*1+Q 0sk lox]sm [0si llx le 1+se 10 le !=n]dsnx
+1si [li p 1+si 10 li !=set]ss [1000Q]st lsx
diff --git a/contrib/bc/tests/dc/scripts/quit.txt b/contrib/bc/tests/dc/scripts/quit.txt
new file mode 100644
index 000000000000..a2b5201ddc05
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/quit.txt
@@ -0,0 +1,99 @@
+0
+0
+0
+1
+0
+1
+0
+1
+2
+0
+1
+2
+0
+1
+2
+3
+0
+1
+2
+3
+0
+1
+2
+3
+4
+0
+1
+2
+3
+4
+0
+1
+2
+3
+4
+5
+0
+1
+2
+3
+4
+5
+0
+1
+2
+3
+4
+5
+6
+0
+1
+2
+3
+4
+5
+6
+0
+1
+2
+3
+4
+5
+6
+7
+0
+1
+2
+3
+4
+5
+6
+7
+0
+1
+2
+3
+4
+5
+6
+7
+8
+0
+1
+2
+3
+4
+5
+6
+7
+8
+1
+2
+3
+4
+5
+6
+7
+8
+9
diff --git a/contrib/bc/tests/dc/scripts/stream.dc b/contrib/bc/tests/dc/scripts/stream.dc
new file mode 100755
index 000000000000..6efcfa3820b5
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/stream.dc
@@ -0,0 +1 @@
+0si[liPlid1+sili65536>x]ddsxPx
diff --git a/contrib/bc/tests/dc/scripts/weird.dc b/contrib/bc/tests/dc/scripts/weird.dc
new file mode 100755
index 000000000000..391ec05d6282
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/weird.dc
@@ -0,0 +1,2 @@
+#! /usr/bin/dc
+zp198202389.289374pzp[He World!]SzpzXfrfxzpfR
diff --git a/contrib/bc/tests/dc/scripts/weird.txt b/contrib/bc/tests/dc/scripts/weird.txt
new file mode 100644
index 000000000000..d921544766af
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/weird.txt
@@ -0,0 +1,18 @@
+0
+198202389.289374
+2
+2
+0
+2
+198202389.289374
+0
+2
+0
+198202389.289374
+0
+4
+4
+2
+0
+198202389.289374
+0
diff --git a/contrib/bc/tests/dc/shift.txt b/contrib/bc/tests/dc/shift.txt
new file mode 100644
index 000000000000..628b0a5bf6fe
--- /dev/null
+++ b/contrib/bc/tests/dc/shift.txt
@@ -0,0 +1,42 @@
+0 0HpR
+1 0HpR
+2 0HpR
+0.0023896 0HpR
+1.298346 0HpR
+2.00000000 0HpR
+0.0023896 3HpR
+1.298346 4HpR
+2.00000000 5HpR
+89136.892348976 7HpR
+1892634051829351283289298 24HpR
+0 0hpR
+1 0hpR
+2 0hpR
+0.0023896 0hpR
+1.298346 0hpR
+2.00000000 0hpR
+0.0023896 3hpR
+1.298346 4hpR
+2.00000000 5hpR
+89136.892348976 7hpR
+1892634051829351283289298 24hpR
+_1 0HpR
+_2 0HpR
+_0.0023896 0HpR
+_1.298346 0HpR
+_2.00000000 0HpR
+_0.0023896 3HpR
+_1.298346 4HpR
+_2.00000000 5HpR
+_89136.892348976 7HpR
+_1892634051829351283289298 24HpR
+_1 0hpR
+_2 0hpR
+_0.0023896 0hpR
+_1.298346 0hpR
+_2.00000000 0hpR
+_0.0023896 3hpR
+_1.298346 4hpR
+_2.00000000 5hpR
+_89136.892348976 7hpR
+_1892634051829351283289298 24hpR
diff --git a/contrib/bc/tests/dc/shift_results.txt b/contrib/bc/tests/dc/shift_results.txt
new file mode 100644
index 000000000000..f92831f8f5cf
--- /dev/null
+++ b/contrib/bc/tests/dc/shift_results.txt
@@ -0,0 +1,42 @@
+0
+1
+2
+.0023896
+1.298346
+2.00000000
+2.3896
+12983.46
+200000.000
+891368923489.76
+1892634051829351283289298000000000000000000000000
+0
+1
+2
+.0023896
+1.298346
+2.00000000
+.0000023896
+.0001298346
+.0000200000000
+.0089136892348976
+1.892634051829351283289298
+-1
+-2
+-.0023896
+-1.298346
+-2.00000000
+-2.3896
+-12983.46
+-200000.000
+-891368923489.76
+-1892634051829351283289298000000000000000000000000
+-1
+-2
+-.0023896
+-1.298346
+-2.00000000
+-.0000023896
+-.0001298346
+-.0000200000000
+-.0089136892348976
+-1.892634051829351283289298
diff --git a/contrib/bc/tests/dc/sqrt.txt b/contrib/bc/tests/dc/sqrt.txt
new file mode 100644
index 000000000000..7c13fdd0bb5d
--- /dev/null
+++ b/contrib/bc/tests/dc/sqrt.txt
@@ -0,0 +1,14 @@
+20k
+0vpR
+2vpR
+4vpR
+9vpR
+16vpR
+25vpR
+121vpR
+48765vpR
+9287356207356vpR
+0.189274385967238956872354vpR
+12389467137496823.134567829387456283946vpR
+.0000000000000000000000000000123vpR
+1vpR
diff --git a/contrib/bc/tests/dc/sqrt_results.txt b/contrib/bc/tests/dc/sqrt_results.txt
new file mode 100644
index 000000000000..5ded8c294eec
--- /dev/null
+++ b/contrib/bc/tests/dc/sqrt_results.txt
@@ -0,0 +1,13 @@
+0
+1.41421356237309504880
+2.00000000000000000000
+3.00000000000000000000
+4.00000000000000000000
+5.00000000000000000000
+11.00000000000000000000
+220.82798735667542192643
+3047516.39985021245496456781
+.435056761776252544285578
+111307983.260397019622398608908
+.0000000000000035071355833500363
+1.00000000000000000000
diff --git a/contrib/bc/tests/dc/stdin.txt b/contrib/bc/tests/dc/stdin.txt
new file mode 100644
index 000000000000..1cf64f9fc740
--- /dev/null
+++ b/contrib/bc/tests/dc/stdin.txt
@@ -0,0 +1,1005 @@
+0si[lid:rli1+sili10>x]dsxxli1-si[li;rpRli1-sili0!>x]dsxxli1+si[li;rpRli1+sili10>x]dsxx0sx0si
+1 2+p
+[foo]
+0
+1+p
+2+p
+3+p
+4+p
+5+p
+6+p
+7+p
+8+p
+9+p
+10+p
+11+p
+12+p
+13+p
+14+p
+15+p
+16+p
+17+p
+18+p
+19+p
+20+p
+21+p
+22+p
+23+p
+24+p
+25+p
+26+p
+27+p
+28+p
+29+p
+30+p
+31+p
+32+p
+33+p
+34+p
+35+p
+36+p
+37+p
+38+p
+39+p
+40+p
+41+p
+42+p
+43+p
+44+p
+45+p
+46+p
+47+p
+48+p
+49+p
+50+p
+51+p
+52+p
+53+p
+54+p
+55+p
+56+p
+57+p
+58+p
+59+p
+60+p
+61+p
+62+p
+63+p
+64+p
+65+p
+66+p
+67+p
+68+p
+69+p
+70+p
+71+p
+72+p
+73+p
+74+p
+75+p
+76+p
+77+p
+78+p
+79+p
+80+p
+81+p
+82+p
+83+p
+84+p
+85+p
+86+p
+87+p
+88+p
+89+p
+90+p
+91+p
+92+p
+93+p
+94+p
+95+p
+96+p
+97+p
+98+p
+99+p
+100+p
+101+p
+102+p
+103+p
+104+p
+105+p
+106+p
+107+p
+108+p
+109+p
+110+p
+111+p
+112+p
+113+p
+114+p
+115+p
+116+p
+117+p
+118+p
+119+p
+120+p
+121+p
+122+p
+123+p
+124+p
+125+p
+126+p
+127+p
+128+p
+129+p
+130+p
+131+p
+132+p
+133+p
+134+p
+135+p
+136+p
+137+p
+138+p
+139+p
+140+p
+141+p
+142+p
+143+p
+144+p
+145+p
+146+p
+147+p
+148+p
+149+p
+150+p
+151+p
+152+p
+153+p
+154+p
+155+p
+156+p
+157+p
+158+p
+159+p
+160+p
+161+p
+162+p
+163+p
+164+p
+165+p
+166+p
+167+p
+168+p
+169+p
+170+p
+171+p
+172+p
+173+p
+174+p
+175+p
+176+p
+177+p
+178+p
+179+p
+180+p
+181+p
+182+p
+183+p
+184+p
+185+p
+186+p
+187+p
+188+p
+189+p
+190+p
+191+p
+192+p
+193+p
+194+p
+195+p
+196+p
+197+p
+198+p
+199+p
+200+p
+201+p
+202+p
+203+p
+204+p
+205+p
+206+p
+207+p
+208+p
+209+p
+210+p
+211+p
+212+p
+213+p
+214+p
+215+p
+216+p
+217+p
+218+p
+219+p
+220+p
+221+p
+222+p
+223+p
+224+p
+225+p
+226+p
+227+p
+228+p
+229+p
+230+p
+231+p
+232+p
+233+p
+234+p
+235+p
+236+p
+237+p
+238+p
+239+p
+240+p
+241+p
+242+p
+243+p
+244+p
+245+p
+246+p
+247+p
+248+p
+249+p
+250+p
+251+p
+252+p
+253+p
+254+p
+255+p
+256+p
+257+p
+258+p
+259+p
+260+p
+261+p
+262+p
+263+p
+264+p
+265+p
+266+p
+267+p
+268+p
+269+p
+270+p
+271+p
+272+p
+273+p
+274+p
+275+p
+276+p
+277+p
+278+p
+279+p
+280+p
+281+p
+282+p
+283+p
+284+p
+285+p
+286+p
+287+p
+288+p
+289+p
+290+p
+291+p
+292+p
+293+p
+294+p
+295+p
+296+p
+297+p
+298+p
+299+p
+300+p
+301+p
+302+p
+303+p
+304+p
+305+p
+306+p
+307+p
+308+p
+309+p
+310+p
+311+p
+312+p
+313+p
+314+p
+315+p
+316+p
+317+p
+318+p
+319+p
+320+p
+321+p
+322+p
+323+p
+324+p
+325+p
+326+p
+327+p
+328+p
+329+p
+330+p
+331+p
+332+p
+333+p
+334+p
+335+p
+336+p
+337+p
+338+p
+339+p
+340+p
+341+p
+342+p
+343+p
+344+p
+345+p
+346+p
+347+p
+348+p
+349+p
+350+p
+351+p
+352+p
+353+p
+354+p
+355+p
+356+p
+357+p
+358+p
+359+p
+360+p
+361+p
+362+p
+363+p
+364+p
+365+p
+366+p
+367+p
+368+p
+369+p
+370+p
+371+p
+372+p
+373+p
+374+p
+375+p
+376+p
+377+p
+378+p
+379+p
+380+p
+381+p
+382+p
+383+p
+384+p
+385+p
+386+p
+387+p
+388+p
+389+p
+390+p
+391+p
+392+p
+393+p
+394+p
+395+p
+396+p
+397+p
+398+p
+399+p
+400+p
+401+p
+402+p
+403+p
+404+p
+405+p
+406+p
+407+p
+408+p
+409+p
+410+p
+411+p
+412+p
+413+p
+414+p
+415+p
+416+p
+417+p
+418+p
+419+p
+420+p
+421+p
+422+p
+423+p
+424+p
+425+p
+426+p
+427+p
+428+p
+429+p
+430+p
+431+p
+432+p
+433+p
+434+p
+435+p
+436+p
+437+p
+438+p
+439+p
+440+p
+441+p
+442+p
+443+p
+444+p
+445+p
+446+p
+447+p
+448+p
+449+p
+450+p
+451+p
+452+p
+453+p
+454+p
+455+p
+456+p
+457+p
+458+p
+459+p
+460+p
+461+p
+462+p
+463+p
+464+p
+465+p
+466+p
+467+p
+468+p
+469+p
+470+p
+471+p
+472+p
+473+p
+474+p
+475+p
+476+p
+477+p
+478+p
+479+p
+480+p
+481+p
+482+p
+483+p
+484+p
+485+p
+486+p
+487+p
+488+p
+489+p
+490+p
+491+p
+492+p
+493+p
+494+p
+495+p
+496+p
+497+p
+498+p
+499+p
+500+p
+501+p
+502+p
+503+p
+504+p
+505+p
+506+p
+507+p
+508+p
+509+p
+510+p
+511+p
+512+p
+513+p
+514+p
+515+p
+516+p
+517+p
+518+p
+519+p
+520+p
+521+p
+522+p
+523+p
+524+p
+525+p
+526+p
+527+p
+528+p
+529+p
+530+p
+531+p
+532+p
+533+p
+534+p
+535+p
+536+p
+537+p
+538+p
+539+p
+540+p
+541+p
+542+p
+543+p
+544+p
+545+p
+546+p
+547+p
+548+p
+549+p
+550+p
+551+p
+552+p
+553+p
+554+p
+555+p
+556+p
+557+p
+558+p
+559+p
+560+p
+561+p
+562+p
+563+p
+564+p
+565+p
+566+p
+567+p
+568+p
+569+p
+570+p
+571+p
+572+p
+573+p
+574+p
+575+p
+576+p
+577+p
+578+p
+579+p
+580+p
+581+p
+582+p
+583+p
+584+p
+585+p
+586+p
+587+p
+588+p
+589+p
+590+p
+591+p
+592+p
+593+p
+594+p
+595+p
+596+p
+597+p
+598+p
+599+p
+600+p
+601+p
+602+p
+603+p
+604+p
+605+p
+606+p
+607+p
+608+p
+609+p
+610+p
+611+p
+612+p
+613+p
+614+p
+615+p
+616+p
+617+p
+618+p
+619+p
+620+p
+621+p
+622+p
+623+p
+624+p
+625+p
+626+p
+627+p
+628+p
+629+p
+630+p
+631+p
+632+p
+633+p
+634+p
+635+p
+636+p
+637+p
+638+p
+639+p
+640+p
+641+p
+642+p
+643+p
+644+p
+645+p
+646+p
+647+p
+648+p
+649+p
+650+p
+651+p
+652+p
+653+p
+654+p
+655+p
+656+p
+657+p
+658+p
+659+p
+660+p
+661+p
+662+p
+663+p
+664+p
+665+p
+666+p
+667+p
+668+p
+669+p
+670+p
+671+p
+672+p
+673+p
+674+p
+675+p
+676+p
+677+p
+678+p
+679+p
+680+p
+681+p
+682+p
+683+p
+684+p
+685+p
+686+p
+687+p
+688+p
+689+p
+690+p
+691+p
+692+p
+693+p
+694+p
+695+p
+696+p
+697+p
+698+p
+699+p
+700+p
+701+p
+702+p
+703+p
+704+p
+705+p
+706+p
+707+p
+708+p
+709+p
+710+p
+711+p
+712+p
+713+p
+714+p
+715+p
+716+p
+717+p
+718+p
+719+p
+720+p
+721+p
+722+p
+723+p
+724+p
+725+p
+726+p
+727+p
+728+p
+729+p
+730+p
+731+p
+732+p
+733+p
+734+p
+735+p
+736+p
+737+p
+738+p
+739+p
+740+p
+741+p
+742+p
+743+p
+744+p
+745+p
+746+p
+747+p
+748+p
+749+p
+750+p
+751+p
+752+p
+753+p
+754+p
+755+p
+756+p
+757+p
+758+p
+759+p
+760+p
+761+p
+762+p
+763+p
+764+p
+765+p
+766+p
+767+p
+768+p
+769+p
+770+p
+771+p
+772+p
+773+p
+774+p
+775+p
+776+p
+777+p
+778+p
+779+p
+780+p
+781+p
+782+p
+783+p
+784+p
+785+p
+786+p
+787+p
+788+p
+789+p
+790+p
+791+p
+792+p
+793+p
+794+p
+795+p
+796+p
+797+p
+798+p
+799+p
+800+p
+801+p
+802+p
+803+p
+804+p
+805+p
+806+p
+807+p
+808+p
+809+p
+810+p
+811+p
+812+p
+813+p
+814+p
+815+p
+816+p
+817+p
+818+p
+819+p
+820+p
+821+p
+822+p
+823+p
+824+p
+825+p
+826+p
+827+p
+828+p
+829+p
+830+p
+831+p
+832+p
+833+p
+834+p
+835+p
+836+p
+837+p
+838+p
+839+p
+840+p
+841+p
+842+p
+843+p
+844+p
+845+p
+846+p
+847+p
+848+p
+849+p
+850+p
+851+p
+852+p
+853+p
+854+p
+855+p
+856+p
+857+p
+858+p
+859+p
+860+p
+861+p
+862+p
+863+p
+864+p
+865+p
+866+p
+867+p
+868+p
+869+p
+870+p
+871+p
+872+p
+873+p
+874+p
+875+p
+876+p
+877+p
+878+p
+879+p
+880+p
+881+p
+882+p
+883+p
+884+p
+885+p
+886+p
+887+p
+888+p
+889+p
+890+p
+891+p
+892+p
+893+p
+894+p
+895+p
+896+p
+897+p
+898+p
+899+p
+900+p
+901+p
+902+p
+903+p
+904+p
+905+p
+906+p
+907+p
+908+p
+909+p
+910+p
+911+p
+912+p
+913+p
+914+p
+915+p
+916+p
+917+p
+918+p
+919+p
+920+p
+921+p
+922+p
+923+p
+924+p
+925+p
+926+p
+927+p
+928+p
+929+p
+930+p
+931+p
+932+p
+933+p
+934+p
+935+p
+936+p
+937+p
+938+p
+939+p
+940+p
+941+p
+942+p
+943+p
+944+p
+945+p
+946+p
+947+p
+948+p
+949+p
+950+p
+951+p
+952+p
+953+p
+954+p
+955+p
+956+p
+957+p
+958+p
+959+p
+960+p
+961+p
+962+p
+963+p
+964+p
+965+p
+966+p
+967+p
+968+p
+969+p
+970+p
+971+p
+972+p
+973+p
+974+p
+975+p
+976+p
+977+p
+978+p
+979+p
+980+p
+981+p
+982+p
+983+p
+984+p
+985+p
+986+p
+987+p
+988+p
+989+p
+990+p
+991+p
+992+p
+993+p
+994+p
+995+p
+996+p
+997+p
+998+p
+999+p
+1000+p
+p
diff --git a/contrib/bc/tests/dc/stdin_results.txt b/contrib/bc/tests/dc/stdin_results.txt
new file mode 100644
index 000000000000..56a33e5cf82d
--- /dev/null
+++ b/contrib/bc/tests/dc/stdin_results.txt
@@ -0,0 +1,1022 @@
+9
+8
+7
+6
+5
+4
+3
+2
+1
+0
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+3
+1
+3
+6
+10
+15
+21
+28
+36
+45
+55
+66
+78
+91
+105
+120
+136
+153
+171
+190
+210
+231
+253
+276
+300
+325
+351
+378
+406
+435
+465
+496
+528
+561
+595
+630
+666
+703
+741
+780
+820
+861
+903
+946
+990
+1035
+1081
+1128
+1176
+1225
+1275
+1326
+1378
+1431
+1485
+1540
+1596
+1653
+1711
+1770
+1830
+1891
+1953
+2016
+2080
+2145
+2211
+2278
+2346
+2415
+2485
+2556
+2628
+2701
+2775
+2850
+2926
+3003
+3081
+3160
+3240
+3321
+3403
+3486
+3570
+3655
+3741
+3828
+3916
+4005
+4095
+4186
+4278
+4371
+4465
+4560
+4656
+4753
+4851
+4950
+5050
+5151
+5253
+5356
+5460
+5565
+5671
+5778
+5886
+5995
+6105
+6216
+6328
+6441
+6555
+6670
+6786
+6903
+7021
+7140
+7260
+7381
+7503
+7626
+7750
+7875
+8001
+8128
+8256
+8385
+8515
+8646
+8778
+8911
+9045
+9180
+9316
+9453
+9591
+9730
+9870
+10011
+10153
+10296
+10440
+10585
+10731
+10878
+11026
+11175
+11325
+11476
+11628
+11781
+11935
+12090
+12246
+12403
+12561
+12720
+12880
+13041
+13203
+13366
+13530
+13695
+13861
+14028
+14196
+14365
+14535
+14706
+14878
+15051
+15225
+15400
+15576
+15753
+15931
+16110
+16290
+16471
+16653
+16836
+17020
+17205
+17391
+17578
+17766
+17955
+18145
+18336
+18528
+18721
+18915
+19110
+19306
+19503
+19701
+19900
+20100
+20301
+20503
+20706
+20910
+21115
+21321
+21528
+21736
+21945
+22155
+22366
+22578
+22791
+23005
+23220
+23436
+23653
+23871
+24090
+24310
+24531
+24753
+24976
+25200
+25425
+25651
+25878
+26106
+26335
+26565
+26796
+27028
+27261
+27495
+27730
+27966
+28203
+28441
+28680
+28920
+29161
+29403
+29646
+29890
+30135
+30381
+30628
+30876
+31125
+31375
+31626
+31878
+32131
+32385
+32640
+32896
+33153
+33411
+33670
+33930
+34191
+34453
+34716
+34980
+35245
+35511
+35778
+36046
+36315
+36585
+36856
+37128
+37401
+37675
+37950
+38226
+38503
+38781
+39060
+39340
+39621
+39903
+40186
+40470
+40755
+41041
+41328
+41616
+41905
+42195
+42486
+42778
+43071
+43365
+43660
+43956
+44253
+44551
+44850
+45150
+45451
+45753
+46056
+46360
+46665
+46971
+47278
+47586
+47895
+48205
+48516
+48828
+49141
+49455
+49770
+50086
+50403
+50721
+51040
+51360
+51681
+52003
+52326
+52650
+52975
+53301
+53628
+53956
+54285
+54615
+54946
+55278
+55611
+55945
+56280
+56616
+56953
+57291
+57630
+57970
+58311
+58653
+58996
+59340
+59685
+60031
+60378
+60726
+61075
+61425
+61776
+62128
+62481
+62835
+63190
+63546
+63903
+64261
+64620
+64980
+65341
+65703
+66066
+66430
+66795
+67161
+67528
+67896
+68265
+68635
+69006
+69378
+69751
+70125
+70500
+70876
+71253
+71631
+72010
+72390
+72771
+73153
+73536
+73920
+74305
+74691
+75078
+75466
+75855
+76245
+76636
+77028
+77421
+77815
+78210
+78606
+79003
+79401
+79800
+80200
+80601
+81003
+81406
+81810
+82215
+82621
+83028
+83436
+83845
+84255
+84666
+85078
+85491
+85905
+86320
+86736
+87153
+87571
+87990
+88410
+88831
+89253
+89676
+90100
+90525
+90951
+91378
+91806
+92235
+92665
+93096
+93528
+93961
+94395
+94830
+95266
+95703
+96141
+96580
+97020
+97461
+97903
+98346
+98790
+99235
+99681
+100128
+100576
+101025
+101475
+101926
+102378
+102831
+103285
+103740
+104196
+104653
+105111
+105570
+106030
+106491
+106953
+107416
+107880
+108345
+108811
+109278
+109746
+110215
+110685
+111156
+111628
+112101
+112575
+113050
+113526
+114003
+114481
+114960
+115440
+115921
+116403
+116886
+117370
+117855
+118341
+118828
+119316
+119805
+120295
+120786
+121278
+121771
+122265
+122760
+123256
+123753
+124251
+124750
+125250
+125751
+126253
+126756
+127260
+127765
+128271
+128778
+129286
+129795
+130305
+130816
+131328
+131841
+132355
+132870
+133386
+133903
+134421
+134940
+135460
+135981
+136503
+137026
+137550
+138075
+138601
+139128
+139656
+140185
+140715
+141246
+141778
+142311
+142845
+143380
+143916
+144453
+144991
+145530
+146070
+146611
+147153
+147696
+148240
+148785
+149331
+149878
+150426
+150975
+151525
+152076
+152628
+153181
+153735
+154290
+154846
+155403
+155961
+156520
+157080
+157641
+158203
+158766
+159330
+159895
+160461
+161028
+161596
+162165
+162735
+163306
+163878
+164451
+165025
+165600
+166176
+166753
+167331
+167910
+168490
+169071
+169653
+170236
+170820
+171405
+171991
+172578
+173166
+173755
+174345
+174936
+175528
+176121
+176715
+177310
+177906
+178503
+179101
+179700
+180300
+180901
+181503
+182106
+182710
+183315
+183921
+184528
+185136
+185745
+186355
+186966
+187578
+188191
+188805
+189420
+190036
+190653
+191271
+191890
+192510
+193131
+193753
+194376
+195000
+195625
+196251
+196878
+197506
+198135
+198765
+199396
+200028
+200661
+201295
+201930
+202566
+203203
+203841
+204480
+205120
+205761
+206403
+207046
+207690
+208335
+208981
+209628
+210276
+210925
+211575
+212226
+212878
+213531
+214185
+214840
+215496
+216153
+216811
+217470
+218130
+218791
+219453
+220116
+220780
+221445
+222111
+222778
+223446
+224115
+224785
+225456
+226128
+226801
+227475
+228150
+228826
+229503
+230181
+230860
+231540
+232221
+232903
+233586
+234270
+234955
+235641
+236328
+237016
+237705
+238395
+239086
+239778
+240471
+241165
+241860
+242556
+243253
+243951
+244650
+245350
+246051
+246753
+247456
+248160
+248865
+249571
+250278
+250986
+251695
+252405
+253116
+253828
+254541
+255255
+255970
+256686
+257403
+258121
+258840
+259560
+260281
+261003
+261726
+262450
+263175
+263901
+264628
+265356
+266085
+266815
+267546
+268278
+269011
+269745
+270480
+271216
+271953
+272691
+273430
+274170
+274911
+275653
+276396
+277140
+277885
+278631
+279378
+280126
+280875
+281625
+282376
+283128
+283881
+284635
+285390
+286146
+286903
+287661
+288420
+289180
+289941
+290703
+291466
+292230
+292995
+293761
+294528
+295296
+296065
+296835
+297606
+298378
+299151
+299925
+300700
+301476
+302253
+303031
+303810
+304590
+305371
+306153
+306936
+307720
+308505
+309291
+310078
+310866
+311655
+312445
+313236
+314028
+314821
+315615
+316410
+317206
+318003
+318801
+319600
+320400
+321201
+322003
+322806
+323610
+324415
+325221
+326028
+326836
+327645
+328455
+329266
+330078
+330891
+331705
+332520
+333336
+334153
+334971
+335790
+336610
+337431
+338253
+339076
+339900
+340725
+341551
+342378
+343206
+344035
+344865
+345696
+346528
+347361
+348195
+349030
+349866
+350703
+351541
+352380
+353220
+354061
+354903
+355746
+356590
+357435
+358281
+359128
+359976
+360825
+361675
+362526
+363378
+364231
+365085
+365940
+366796
+367653
+368511
+369370
+370230
+371091
+371953
+372816
+373680
+374545
+375411
+376278
+377146
+378015
+378885
+379756
+380628
+381501
+382375
+383250
+384126
+385003
+385881
+386760
+387640
+388521
+389403
+390286
+391170
+392055
+392941
+393828
+394716
+395605
+396495
+397386
+398278
+399171
+400065
+400960
+401856
+402753
+403651
+404550
+405450
+406351
+407253
+408156
+409060
+409965
+410871
+411778
+412686
+413595
+414505
+415416
+416328
+417241
+418155
+419070
+419986
+420903
+421821
+422740
+423660
+424581
+425503
+426426
+427350
+428275
+429201
+430128
+431056
+431985
+432915
+433846
+434778
+435711
+436645
+437580
+438516
+439453
+440391
+441330
+442270
+443211
+444153
+445096
+446040
+446985
+447931
+448878
+449826
+450775
+451725
+452676
+453628
+454581
+455535
+456490
+457446
+458403
+459361
+460320
+461280
+462241
+463203
+464166
+465130
+466095
+467061
+468028
+468996
+469965
+470935
+471906
+472878
+473851
+474825
+475800
+476776
+477753
+478731
+479710
+480690
+481671
+482653
+483636
+484620
+485605
+486591
+487578
+488566
+489555
+490545
+491536
+492528
+493521
+494515
+495510
+496506
+497503
+498501
+499500
+500500
+500500
diff --git a/contrib/bc/tests/dc/strings.txt b/contrib/bc/tests/dc/strings.txt
new file mode 100644
index 000000000000..369d8e1dd842
--- /dev/null
+++ b/contrib/bc/tests/dc/strings.txt
@@ -0,0 +1,50 @@
+[Hello, World!]ZpR
+[Hello, World!]pR
+[Hello, \[ World!]ZpR
+[Hello, \[ World!]pR
+[Hello, \] World!]ZpR
+[Hello, \] World!]pR
+[30pR]
+[29pR]
+[28pR]
+[27pR]
+[26pR]
+[25pR]
+[24pR]
+[23pR]
+[22pR]
+[21pR]
+[20pR]
+[19pR]
+[18pR]
+[17pR]
+[16pR]
+[15pR]
+[14pR]
+[13pR]
+[12pR]
+[11pR]
+[10pR]
+[9pR]
+[8pR]
+[7pR]
+[6pR]
+[5pR]
+[4pR]
+[3pR]
+[2pR]
+[1pR]
+[xz0<x]dsxx
+[\\]pR
+[\[\]]pR
+1xpR
+[1st] 0:b [2nd] 1:b 0;b p 1;b p
+[string]XpR
+[3 4^pR]silix
+[[[q 1 3+pR]x]x]x4 5^pR
+4xpR
+5 112ax 90ax 112ax 82ax
+[\q] pR
+[q\\] pR
+[\\] pR
+92 a pR
diff --git a/contrib/bc/tests/dc/strings_results.txt b/contrib/bc/tests/dc/strings_results.txt
new file mode 100644
index 000000000000..509b105d51f3
--- /dev/null
+++ b/contrib/bc/tests/dc/strings_results.txt
@@ -0,0 +1,51 @@
+13
+Hello, World!
+15
+Hello, [ World!
+15
+Hello, ] World!
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+\
+[]
+1
+1st
+2nd
+0
+81
+1024
+4
+5
+1
+q
+q\
+\
+\
diff --git a/contrib/bc/tests/dc/subtract.txt b/contrib/bc/tests/dc/subtract.txt
new file mode 100644
index 000000000000..2cb4104fb717
--- /dev/null
+++ b/contrib/bc/tests/dc/subtract.txt
@@ -0,0 +1,33 @@
+0 0-pR
+0 1-pR
+1 0-pR
+1 1-pR
+5 2-pR
+2 9-pR
+321974 12845976238457-pR
+2874519803456710938465 384723854-pR
+10000000000000000000000000000000000000000 999999999999999999999999999999999999999-pR
+10000000000000000000000000000000000000000 9999999999999999999999999999999999999999-pR
+10000000000000000000000000000000000000000 999999999999999999999999999999999999999.99999999999999999999999999999999999-pR
+10000000000000000000000000000000000000000 9999999999999999999999999999999999999999.9999999999999999999999999999999999-pR
+10000000000000000000000000000000000000000 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000001-pR
+10000000000000000000000000000000000000001 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000001-pR
+10000000000000000000000000000000000000000.0000000001 0.0000000000000000000000000000000000000000000000000000000000000000000000000001-pR
+_2 6-pR
+_23784692345 182934721309467230894628735496027345-pR
+_224352354962873059862 _1245723576829456278354960278345-pR
+_3468273598 _12354243-pR
+_0.92345768293 _2354768923-pR
+_712384634.123476823 _24768293376-pR
+_1879234638 _0.917234869234-pR
+_0.9172438692134 _0.971284967124-pR
+_0.1283475123465 _0.937462346-pR
+_124765829346.2837468293562 _0.923467829346-pR
+_12476829385769 _1928476259034.8378629356-pR
+_0.38476284395876345 _94875394587623.2357869324857-pR
+_4674596708467.34754789403674343567 _48672394852354698.237548629345-pR
+979519669 3018100865-pR
+929002449 3280677283-pR
+0 _525898-pR
+3 _3-pR
+2 _1 2893714 _2189367411289 _.8921374 3.9201384----pR
diff --git a/contrib/bc/tests/dc/subtract_results.txt b/contrib/bc/tests/dc/subtract_results.txt
new file mode 100644
index 000000000000..9f772625422e
--- /dev/null
+++ b/contrib/bc/tests/dc/subtract_results.txt
@@ -0,0 +1,37 @@
+0
+-1
+1
+0
+3
+-7
+-12845975916483
+2874519803456326214611
+9000000000000000000000000000000000000001
+1
+9000000000000000000000000000000000000000.000000000000000000000000000\
+00000001
+.0000000000000000000000000000000001
+9999999999999999999999999999999999999999.999999999999999999999999999\
+99999999999999999999999999999999999999999999999999999999999
+10000000000000000000000000000000000000000.99999999999999999999999999\
+999999999999999999999999999999999999999999999999999999999999
+10000000000000000000000000000000000000000.00000000009999999999999999\
+99999999999999999999999999999999999999999999999999
+-8
+-182934721309467230894628759280719690
+1245723576605103923392087218483
+-3455919355
+2354768922.07654231707
+24055908741.876523177
+-1879234637.082765130766
+.0540410979106
+.8091148336535
+-124765829345.3602790000102
+-10548353126734.1621370644
+94875394587622.85102408852693655
+48667720255646230.89000073530825656433
+-2038581196
+-2351674834
+525898
+6
+-2189370304999.1877242
diff --git a/contrib/bc/tests/dc/trunc.txt b/contrib/bc/tests/dc/trunc.txt
new file mode 100644
index 000000000000..684752e065dd
--- /dev/null
+++ b/contrib/bc/tests/dc/trunc.txt
@@ -0,0 +1,11 @@
+0$pR
+1$pR
+2$pR
+0.8249167203486$pR
+1.28937150237$pR
+2.0$pR
+28937.92837605126$pR
+2890.000000000$pR
+_1$pR
+_1.128973$pR
+_9812387.28910273$pR
diff --git a/contrib/bc/tests/dc/trunc_results.txt b/contrib/bc/tests/dc/trunc_results.txt
new file mode 100644
index 000000000000..c680604170d7
--- /dev/null
+++ b/contrib/bc/tests/dc/trunc_results.txt
@@ -0,0 +1,11 @@
+0
+1
+2
+0
+1
+2
+28937
+2890
+-1
+-1
+-9812387
diff --git a/contrib/bc/tests/dc/vars.txt b/contrib/bc/tests/dc/vars.txt
new file mode 100644
index 000000000000..bbe73b47d81f
--- /dev/null
+++ b/contrib/bc/tests/dc/vars.txt
@@ -0,0 +1,2 @@
+298734.8921702348sx_928374892.28937syzpRlxly+pR
+298734.8921702348S xotj _928374892.28937S yotp zpRl xotj l yotp-pRzpR L xotj L yotp-pR
diff --git a/contrib/bc/tests/dc/vars_results.txt b/contrib/bc/tests/dc/vars_results.txt
new file mode 100644
index 000000000000..6f18e7a84b2b
--- /dev/null
+++ b/contrib/bc/tests/dc/vars_results.txt
@@ -0,0 +1,6 @@
+0
+-928076157.3971997652
+0
+928673627.1815402348
+0
+928673627.1815402348
diff --git a/contrib/bc/tests/errors.sh b/contrib/bc/tests/errors.sh
new file mode 100755
index 000000000000..17c84ca24ef3
--- /dev/null
+++ b/contrib/bc/tests/errors.sh
@@ -0,0 +1,132 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+# WARNING: Test files cannot have empty lines!
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../functions.sh"
+
+if [ "$#" -eq 0 ]; then
+ printf 'usage: %s dir [exec args...]\n' "$script"
+ exit 1
+else
+ d="$1"
+ shift
+fi
+
+if [ "$#" -lt 1 ]; then
+ exe="$testdir/../bin/$d"
+else
+ exe="$1"
+ shift
+fi
+
+out="$testdir/../.log_${d}_test.txt"
+
+exebase=$(basename "$exe")
+
+posix="posix_errors"
+read_errors="read_errors"
+
+if [ "$d" = "bc" ]; then
+ opts="-l"
+ halt="halt"
+ read_call="read()"
+ read_expr="${read_call}\n5+5;"
+else
+ opts="-x"
+ halt="q"
+fi
+
+for testfile in $testdir/$d/*errors.txt; do
+
+ if [ -z "${testfile##*$read_errors*}" ]; then
+ # We don't test read errors here. Skip.
+ continue
+ fi
+
+ if [ -z "${testfile##*$posix*}" ]; then
+
+ line="last"
+ printf '%s\n' "$line" | "$exe" "$@" "-lw" 2> "$out" > /dev/null
+ err="$?"
+
+ if [ "$err" -ne 0 ]; then
+ die "$d" "returned an error ($err)" "POSIX warning" 1
+ fi
+
+ checktest "$d" "1" "$line" "$out" "$exebase"
+
+ options="-ls"
+ else
+ options="$opts"
+ fi
+
+ base=$(basename "$testfile")
+ base="${base%.*}"
+ printf 'Running %s %s...' "$d" "$base"
+
+ while read -r line; do
+
+ rm -f "$out"
+
+ printf '%s\n' "$line" | "$exe" "$@" "$options" 2> "$out" > /dev/null
+ err="$?"
+
+ checktest "$d" "$err" "$line" "$out" "$exebase"
+
+ done < "$testfile"
+
+ printf 'pass\n'
+
+done
+
+for testfile in $testdir/$d/errors/*.txt; do
+
+ printf 'Running %s error file %s...' "$d" "$testfile"
+
+ printf '%s\n' "$halt" | "$exe" "$@" $opts "$testfile" 2> "$out" > /dev/null
+ err="$?"
+
+ checktest "$d" "$err" "$testfile" "$out" "$exebase"
+
+ printf 'pass\n'
+
+ printf 'Running %s error file %s through cat...' "$d" "$testfile"
+
+ cat "$testfile" | "$exe" "$@" $opts 2> "$out" > /dev/null
+ err="$?"
+
+ checkcrash "$d" "$err" "$testfile"
+
+ printf 'pass\n'
+
+done
diff --git a/contrib/bc/tests/radamsa.sh b/contrib/bc/tests/radamsa.sh
new file mode 100755
index 000000000000..537ee10255c3
--- /dev/null
+++ b/contrib/bc/tests/radamsa.sh
@@ -0,0 +1,120 @@
+#! /bin/bash
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+getentry() {
+
+ if [ $# -gt 0 ]; then
+ entnum="$1"
+ else
+ entnum=0
+ fi
+
+ e=$(cat -)
+ num=$(printf '%s\n' "$e" | wc -l)
+
+ if [ "$entnum" -eq 0 ]; then
+ rand=$(printf 'irand(%s) + 1\n' "$num" | "$bcdir/bc")
+ else
+ rand="$entnum"
+ fi
+
+ ent=$(printf '%s\n' "$e" | tail -n +$rand | head -n 1)
+
+ printf '%s\n' "$ent"
+}
+
+script="$0"
+
+if [ "$#" -lt 1 ]; then
+ printf 'usage: %s dir\n' "$0"
+ exit 1
+fi
+
+d="$1"
+shift
+
+dir=$(dirname "$script")
+
+. "$dir/../functions.sh"
+
+bcdir="$dir/../bin"
+
+if [ "$d" = "bc" ]; then
+ inputs="$dir/../../inputs"
+ opts="-lq"
+elif [ "$d" = "dc" ]; then
+ inputs="$dir/../../inputs_dc"
+ opts="-x"
+else
+ err_exit "wrong type of executable" 1
+fi
+
+export ASAN_OPTIONS="abort_on_error=1"
+
+entries=$(cat "$dir/radamsa.txt")
+
+IFS=$'\n'
+
+go=1
+
+while [ "$go" -ne 0 ]; do
+
+ if [ "$d" = "bc" ]; then
+
+ entry=$(cat -- "$dir/radamsa.txt" | getentry)
+ items=$(printf '%s\n' "$entry" | radamsa -n 10)
+
+ printf '%s\n' "$items"
+
+ for i in `seq 1 10`; do
+
+ item=$(printf '%s\n' "$items" | getentry "$i")
+
+ export BC_ENV_ARGS="$item"
+ echo 'halt' | "$bcdir/$d"
+ err=$?
+
+ checkcrash "$d" "$err" "radamsa env args: \"$item\""
+ done
+
+ fi
+
+ f=$(ls "$inputs" | getentry)
+ l=$(cat "$inputs/$f" | wc -l)
+ ll=$(printf '%s^2\n' "$l" | bc)
+
+ for i in $(seq 1 2); do
+ data=$(cat "$inputs/$f" | radamsa -n 1)
+ printf '%s\n' "$data" > "$dir/../.log_${d}_test.txt"
+ printf '%s\n' "$data" | timeout -s SIGTERM 5 "$bcdir/$d" "$opts" > /dev/null
+ err=$?
+ checkcrash "$d" "$err" "radamsa stdin"
+ done
+
+done
diff --git a/contrib/bc/tests/radamsa.txt b/contrib/bc/tests/radamsa.txt
new file mode 100644
index 000000000000..4bf28907bead
--- /dev/null
+++ b/contrib/bc/tests/radamsa.txt
@@ -0,0 +1,17 @@
+-lq '/home/gavin/.bcrc'
+-lq "/home/gavin/.bcrc"
+-lqg '/home/gavin/bc stuff.bc'
+-lqg "/home/gavin/bc stuff.bc"
+-lqg '/home/gavin/"bc" stuff.bc'
+-lqg "/home/gavin/'bc' stuff.bc"
+-lqg '/home/gavin/bc stuff.bc
+-lqg "/home/gavin/bc stuff.bc
+-lqg '/home/gavin/"bc" stuff.bc
+-lqg "/home/gavin/'bc' stuff.bc
+--mathlib --expand
+--file="/home/gavin/.bcrc"
+--file=/home/gavin/.bcrc
+--file="/home/gavin/bc stuff.bc"
+--file
+--expression "4+4"
+-e "irand(128)" -f /home/gavin/.bcrc
diff --git a/contrib/bc/tests/randmath.py b/contrib/bc/tests/randmath.py
new file mode 100755
index 000000000000..7f14a345be3e
--- /dev/null
+++ b/contrib/bc/tests/randmath.py
@@ -0,0 +1,306 @@
+#! /usr/bin/python3 -B
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+import os, errno
+import random
+import sys
+import subprocess
+
+def gen(limit=4):
+ return random.randint(0, 2 ** (8 * limit))
+
+def negative():
+ return random.randint(0, 1) == 1
+
+def zero():
+ return random.randint(0, 2 ** (8) - 1) == 0
+
+def num(op, neg, real, z, limit=4):
+
+ if z:
+ z = zero()
+ else:
+ z = False
+
+ if z:
+ return 0
+
+ if neg:
+ neg = negative()
+
+ g = gen(limit)
+
+ if real and negative():
+ n = str(gen(25))
+ length = gen(7 / 8)
+ if len(n) < length:
+ n = ("0" * (length - len(n))) + n
+ else:
+ n = "0"
+
+ g = str(g)
+ if n != "0":
+ g = g + "." + n
+
+ if neg and g != "0":
+ if op != modexp:
+ g = "-" + g
+ else:
+ g = "_" + g
+
+ return g
+
+
+def add(test, op):
+
+ tests.append(test)
+ gen_ops.append(op)
+
+def compare(exe, options, p, test, halt, expected, op, do_add=True):
+
+ if p.returncode != 0:
+
+ print(" {} returned an error ({})".format(exe, p.returncode))
+
+ if do_add:
+ print(" adding to checklist...")
+ add(test, op)
+
+ return
+
+ actual = p.stdout.decode()
+
+ if actual != expected:
+
+ if op >= exponent:
+
+ indata = "scale += 10; {}; {}".format(test, halt)
+ args = [ exe, options ]
+ p2 = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ expected = p2.stdout[:-10].decode()
+
+ if actual == expected:
+ print(" failed because of bug in other {}".format(exe))
+ print(" continuing...")
+ return
+
+ if do_add:
+ print(" failed; adding to checklist...")
+ add(test, op)
+ else:
+ print(" failed {}".format(test))
+ print(" expected:")
+ print(" {}".format(expected))
+ print(" actual:")
+ print(" {}".format(actual))
+
+
+def gen_test(op):
+
+ scale = num(op, False, False, True, 5 / 8)
+
+ if op < div:
+ s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, True))
+ elif op == div or op == mod:
+ s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, False))
+ elif op == power:
+ s = fmts[op].format(scale, num(op, True, True, True, 7 / 8), num(op, True, False, True, 6 / 8))
+ elif op == modexp:
+ s = fmts[op].format(scale, num(op, True, False, True), num(op, True, False, True),
+ num(op, True, False, False))
+ elif op == sqrt:
+ s = "1"
+ while s == "1":
+ s = num(op, False, True, True, 1)
+ s = fmts[op].format(scale, s)
+ else:
+
+ if op == exponent:
+ first = num(op, True, True, True, 6 / 8)
+ elif op == bessel:
+ first = num(op, False, True, True, 6 / 8)
+ else:
+ first = num(op, True, True, True)
+
+ if op != bessel:
+ s = fmts[op].format(scale, first)
+ else:
+ s = fmts[op].format(scale, first, 6 / 8)
+
+ return s
+
+def run_test(t):
+
+ op = random.randrange(bessel + 1)
+
+ if op != modexp:
+ exe = "bc"
+ halt = "halt"
+ options = "-lq"
+ else:
+ exe = "dc"
+ halt = "q"
+ options = ""
+
+ test = gen_test(op)
+
+ if "c(0)" in test or "scale = 4; j(4" in test:
+ return
+
+ bcexe = exedir + "/" + exe
+ indata = test + "\n" + halt
+
+ print("Test {}: {}".format(t, test))
+
+ if exe == "bc":
+ args = [ exe, options ]
+ else:
+ args = [ exe ]
+
+ p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ output1 = p.stdout.decode()
+
+ if p.returncode != 0 or output1 == "":
+ print(" other {} returned an error ({}); continuing...".format(exe, p.returncode))
+ return
+
+ if output1 == "\n":
+ print(" other {} has a bug; continuing...".format(exe))
+ return
+
+ if output1 == "-0\n":
+ output1 = "0\n"
+ elif output1 == "-0":
+ output1 = "0"
+
+ args = [ bcexe, options ]
+
+ p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ compare(exe, options, p, test, halt, output1, op)
+
+
+if __name__ != "__main__":
+ sys.exit(1)
+
+script = sys.argv[0]
+testdir = os.path.dirname(script)
+
+exedir = testdir + "/../bin"
+
+ops = [ '+', '-', '*', '/', '%', '^', '|' ]
+files = [ "add", "subtract", "multiply", "divide", "modulus", "power", "modexp",
+ "sqrt", "exponent", "log", "arctangent", "sine", "cosine", "bessel" ]
+funcs = [ "sqrt", "e", "l", "a", "s", "c", "j" ]
+
+fmts = [ "scale = {}; {} + {}", "scale = {}; {} - {}", "scale = {}; {} * {}",
+ "scale = {}; {} / {}", "scale = {}; {} % {}", "scale = {}; {} ^ {}",
+ "{}k {} {} {}|pR", "scale = {}; sqrt({})", "scale = {}; e({})",
+ "scale = {}; l({})", "scale = {}; a({})", "scale = {}; s({})",
+ "scale = {}; c({})", "scale = {}; j({}, {})" ]
+
+div = 3
+mod = 4
+power = 5
+modexp = 6
+sqrt = 7
+exponent = 8
+bessel = 13
+
+gen_ops = []
+tests = []
+
+try:
+ i = 0
+ while True:
+ run_test(i)
+ i = i + 1
+except KeyboardInterrupt:
+ pass
+
+if len(tests) == 0:
+ print("\nNo items in checklist.")
+ print("Exiting")
+ sys.exit(0)
+
+print("\nGoing through the checklist...\n")
+
+if len(tests) != len(gen_ops):
+ print("Corrupted checklist!")
+ print("Exiting...")
+ sys.exit(1)
+
+for i in range(0, len(tests)):
+
+ print("\n{}".format(tests[i]))
+
+ op = int(gen_ops[i])
+
+ if op != modexp:
+ exe = "bc"
+ halt = "halt"
+ options = "-lq"
+ else:
+ exe = "dc"
+ halt = "q"
+ options = ""
+
+ indata = tests[i] + "\n" + halt
+
+ args = [ exe, options ]
+
+ p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ expected = p.stdout.decode()
+
+ bcexe = exedir + "/" + exe
+ args = [ bcexe, options ]
+
+ p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ compare(exe, options, p, tests[i], halt, expected, op, False)
+
+ answer = input("\nAdd test ({}/{}) to test suite? [y/N]: ".format(i + 1, len(tests)))
+
+ if 'Y' in answer or 'y' in answer:
+
+ print("Yes")
+
+ name = testdir + "/" + exe + "/" + files[op]
+
+ with open(name + ".txt", "a") as f:
+ f.write(tests[i] + "\n")
+
+ with open(name + "_results.txt", "a") as f:
+ f.write(expected)
+
+ else:
+ print("No")
+
+print("Done!")
diff --git a/contrib/bc/tests/read.sh b/contrib/bc/tests/read.sh
new file mode 100755
index 000000000000..0440a078d36c
--- /dev/null
+++ b/contrib/bc/tests/read.sh
@@ -0,0 +1,126 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+set -e
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../functions.sh"
+
+if [ "$#" -lt 1 ]; then
+ printf 'usage: %s dir [exe [args...]]\n' "$0"
+ printf 'valid dirs are:\n'
+ printf '\n'
+ cat "$testdir/all.txt"
+ printf '\n'
+ exit 1
+fi
+
+d="$1"
+shift
+
+if [ "$#" -gt 0 ]; then
+ exe="$1"
+ shift
+else
+ exe="$testdir/../bin/$d"
+fi
+
+name="$testdir/$d/read.txt"
+results="$testdir/$d/read_results.txt"
+errors="$testdir/$d/read_errors.txt"
+
+out="$testdir/../.log_${d}_test.txt"
+
+exebase=$(basename "$exe")
+
+if [ "$d" = "bc" ]; then
+ options="-lq"
+ halt="halt"
+else
+ options="-x"
+ halt="q"
+fi
+
+if [ "$d" = "bc" ]; then
+ read_call="read()"
+ read_expr="${read_call}\n5+5;"
+else
+ read_call="?"
+ read_expr="${read_call}"
+fi
+
+printf 'Running %s read...' "$d"
+
+while read line; do
+
+ printf '%s\n%s\n' "$read_call" "$line" | "$exe" "$@" "$options" > "$out"
+ diff "$results" "$out"
+
+done < "$name"
+
+printf 'pass\n'
+
+set +e
+
+printf 'Running %s read errors...' "$d"
+
+while read line; do
+
+ printf '%s\n%s\n' "$read_call" "$line" | "$exe" "$@" "$options" 2> "$out" > /dev/null
+ err="$?"
+
+ checktest "$d" "$err" "$line" "$out" "$exebase"
+
+done < "$errors"
+
+printf 'pass\n'
+
+printf 'Running %s empty read...' "$d"
+
+read_test=$(printf '%s\n' "$read_call")
+
+printf '%s\n' "$read_test" | "$exe" "$@" "$opts" 2> "$out" > /dev/null
+err="$?"
+
+checktest "$d" "$err" "$read_test" "$out" "$exebase"
+
+printf 'pass\n'
+
+printf 'Running %s read EOF...' "$d"
+
+read_test=$(printf '%s' "$read_call")
+
+printf '%s' "$read_test" | "$exe" "$@" "$opts" 2> "$out" > /dev/null
+err="$?"
+
+checktest "$d" "$err" "$read_test" "$out" "$exebase"
+
+printf 'pass\n'
diff --git a/contrib/bc/tests/script.sh b/contrib/bc/tests/script.sh
new file mode 100755
index 000000000000..279295829f75
--- /dev/null
+++ b/contrib/bc/tests/script.sh
@@ -0,0 +1,155 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+set -e
+
+script="$0"
+
+testdir=$(dirname "${script}")
+
+if [ "$#" -lt 2 ]; then
+ printf 'usage: %s dir script [run_extra_tests] [run_stack_tests] [generate_tests] [time_tests] [exec args...]\n' "$script"
+ exit 1
+fi
+
+d="$1"
+shift
+
+f="$1"
+shift
+
+if [ "$#" -gt 0 ]; then
+ run_extra_tests="$1"
+ shift
+else
+ run_extra_tests=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ run_stack_tests="$1"
+ shift
+else
+ run_stack_tests=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ generate="$1"
+ shift
+else
+ generate=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ time_tests="$1"
+ shift
+else
+ time_tests=0
+fi
+
+if [ "$#" -gt 0 ]; then
+ exe="$1"
+ shift
+else
+ exe="$testdir/../bin/$d"
+fi
+
+out="$testdir/../.log_${d}_test.txt"
+
+if [ "$d" = "bc" ]; then
+
+ if [ "$run_stack_tests" -ne 0 ]; then
+ options="-lgq"
+ else
+ options="-lq"
+ fi
+
+ halt="halt"
+
+else
+ options="-x"
+ halt="q"
+fi
+
+scriptdir="$testdir/$d/scripts"
+
+name="${f%.*}"
+
+if [ "$f" = "timeconst.bc" ]; then
+ exit 0
+fi
+
+if [ "$run_extra_tests" -eq 0 ]; then
+ if [ "$f" = "rand.bc" ]; then
+ printf 'Skipping %s script: %s\n' "$d" "$f"
+ exit 0
+ fi
+fi
+
+if [ "$run_stack_tests" -eq 0 ]; then
+
+ if [ "$f" = "globals.bc" -o "$f" = "references.bc" -o "$f" = "rand.bc" ]; then
+ printf 'Skipping %s script: %s\n' "$d" "$f"
+ exit 0
+ fi
+
+fi
+
+s="$scriptdir/$f"
+orig="$testdir/$name.txt"
+results="$scriptdir/$name.txt"
+
+if [ -f "$orig" ]; then
+ res="$orig"
+elif [ -f "$results" ]; then
+ res="$results"
+elif [ "$generate" -eq 0 ]; then
+ printf 'Skipping %s script %s\n' "$d" "$s"
+ exit 0
+else
+ printf 'Generating %s results...' "$f"
+ printf '%s\n' "$halt" | "$d" "$s" > "$results"
+ printf 'done\n'
+ res="$results"
+fi
+
+printf 'Running %s script %s...' "$d" "$f"
+
+if [ "$time_tests" -ne 0 ]; then
+ printf '\n'
+ printf '%s\n' "$halt" | /usr/bin/time -p "$exe" "$@" $options "$s" > "$out"
+ printf '\n'
+else
+ printf '%s\n' "$halt" | "$exe" "$@" $options "$s" > "$out"
+fi
+
+diff "$res" "$out"
+
+rm -f "$out"
+
+printf 'pass\n'
diff --git a/contrib/bc/tests/scripts.sh b/contrib/bc/tests/scripts.sh
new file mode 100755
index 000000000000..ff17260c909c
--- /dev/null
+++ b/contrib/bc/tests/scripts.sh
@@ -0,0 +1,86 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+set -e
+
+script="$0"
+
+testdir=$(dirname "${script}")
+
+if [ "$#" -eq 0 ]; then
+ printf 'usage: %s dir [run_extra_tests] [run_stack_tests] [generate_tests] [time_tests] [exec args...]\n' "$script"
+ exit 1
+else
+ d="$1"
+ shift
+fi
+
+if [ "$#" -gt 0 ]; then
+ run_extra_tests="$1"
+ shift
+else
+ run_extra_tests=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ run_stack_tests="$1"
+ shift
+else
+ run_stack_tests=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ generate="$1"
+ shift
+else
+ generate=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ time_tests="$1"
+ shift
+else
+ time_tests=0
+fi
+
+if [ "$#" -gt 0 ]; then
+ exe="$1"
+ shift
+else
+ exe="$testdir/../bin/$d"
+fi
+
+scriptdir="$testdir/$d/scripts"
+
+for s in $scriptdir/*.$d; do
+
+ f=$(basename "$s")
+ sh "$testdir/script.sh" "$d" "$f" "$run_extra_tests" "$run_stack_tests" "$generate" "$time_tests" "$exe" "$@"
+
+done
diff --git a/contrib/bc/tests/stdin.sh b/contrib/bc/tests/stdin.sh
new file mode 100755
index 000000000000..f66019d5ae65
--- /dev/null
+++ b/contrib/bc/tests/stdin.sh
@@ -0,0 +1,81 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+set -e
+
+script="$0"
+
+testdir=$(dirname "$script")
+
+if [ "$#" -lt 1 ]; then
+ printf 'usage: %s dir [exe [args...]]\n' "$0"
+ printf 'valid dirs are:\n'
+ printf '\n'
+ cat "$testdir/all.txt"
+ printf '\n'
+ exit 1
+fi
+
+d="$1"
+shift
+
+if [ "$#" -gt 0 ]; then
+ exe="$1"
+ shift
+else
+ exe="$testdir/../bin/$d"
+fi
+
+out="$testdir/../.log_${d}_test.txt"
+
+if [ "$d" = "bc" ]; then
+ options="-ilq"
+else
+ options="-x"
+fi
+
+rm -f "$out"
+
+printf 'Running %s stdin tests...' "$d"
+
+cat "$testdir/$d/stdin.txt" | "$exe" "$@" "$options" > "$out" 2> /dev/null
+diff "$testdir/$d/stdin_results.txt" "$out"
+
+if [ "$d" = "bc" ]; then
+
+ cat "$testdir/$d/stdin1.txt" | "$exe" "$@" "$options" > "$out" 2> /dev/null
+ diff "$testdir/$d/stdin1_results.txt" "$out"
+
+ cat "$testdir/$d/stdin2.txt" | "$exe" "$@" "$options" > "$out" 2> /dev/null
+ diff "$testdir/$d/stdin2_results.txt" "$out"
+fi
+
+rm -f "$out1"
+
+printf 'pass\n'
diff --git a/contrib/bc/tests/test.sh b/contrib/bc/tests/test.sh
new file mode 100755
index 000000000000..20f95413597b
--- /dev/null
+++ b/contrib/bc/tests/test.sh
@@ -0,0 +1,132 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2020 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.
+#
+
+set -e
+
+script="$0"
+
+testdir=$(dirname "$script")
+
+if [ "$#" -lt 2 ]; then
+ printf 'usage: %s dir test [generate_tests] [time_tests] [exe [args...]]\n' "$0"
+ printf 'valid dirs are:\n'
+ printf '\n'
+ cat "$testdir/all.txt"
+ printf '\n'
+ exit 1
+fi
+
+d="$1"
+shift
+
+t="$1"
+name="$testdir/$d/$t.txt"
+results="$testdir/$d/${t}_results.txt"
+shift
+
+if [ "$#" -gt 0 ]; then
+ generate_tests="$1"
+ shift
+else
+ generate_tests=1
+fi
+
+if [ "$#" -gt 0 ]; then
+ time_tests="$1"
+ shift
+else
+ time_tests=0
+fi
+
+if [ "$#" -gt 0 ]; then
+ exe="$1"
+ shift
+else
+ exe="$testdir/../bin/$d"
+fi
+
+out="$testdir/../.log_${d}_test.txt"
+
+if [ "$d" = "bc" ]; then
+ options="-lq"
+ var="BC_LINE_LENGTH"
+ halt="halt"
+else
+ options=""
+ var="DC_LINE_LENGTH"
+ halt="q"
+fi
+
+if [ "${exe#*toybox}" != "$exe" -o "${exe#*busybox}" != "$exe" ]; then
+ if [ "$t" = "print2" -o "$t" = "misc4" ]; then
+ base=$(basename "$exe")
+ printf 'Skipping %s test for %s...\n' "$t" "$base"
+ exit 0
+ fi
+fi
+
+if [ ! -f "$name" ]; then
+
+ if [ "$generate_tests" -eq 0 ]; then
+ printf 'Skipping %s %s test\n' "$d" "$t"
+ exit 0
+ fi
+
+ printf 'Generating %s %s...' "$d" "$t"
+ "$testdir/$d/scripts/$t.$d" > "$name"
+ printf 'done\n'
+fi
+
+if [ ! -f "$results" ]; then
+ printf 'Generating %s %s results...' "$d" "$t"
+ printf '%s\n' "$halt" | "$d" $options "$name" > "$results"
+ printf 'done\n'
+fi
+
+if [ "$d" = "dc" ]; then
+ options="-x"
+fi
+
+export $var=string
+
+printf 'Running %s %s...' "$d" "$t"
+
+if [ "$time_tests" -ne 0 ]; then
+ printf '\n'
+ printf '%s\n' "$halt" | /usr/bin/time -p "$exe" "$@" $options "$name" > "$out"
+ printf '\n'
+else
+ printf '%s\n' "$halt" | "$exe" "$@" $options "$name" > "$out"
+fi
+
+diff "$results" "$out"
+
+rm -f "$out"
+
+printf 'pass\n'