aboutsummaryrefslogtreecommitdiff
path: root/contrib/bc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bc')
-rw-r--r--contrib/bc/.gitattributes3
-rw-r--r--contrib/bc/.gitignore80
-rw-r--r--contrib/bc/LICENSE.md113
-rw-r--r--contrib/bc/Makefile.in615
-rw-r--r--contrib/bc/NEWS.md1203
-rw-r--r--contrib/bc/NOTICE.md14
-rw-r--r--contrib/bc/README.md419
l---------contrib/bc/configure1
-rwxr-xr-xcontrib/bc/configure.sh1658
-rw-r--r--contrib/bc/gen/bc_help.txt185
-rw-r--r--contrib/bc/gen/dc_help.txt144
-rw-r--r--contrib/bc/gen/lib.bc201
-rw-r--r--contrib/bc/gen/lib2.bc564
-rw-r--r--contrib/bc/gen/strgen.c294
-rwxr-xr-xcontrib/bc/gen/strgen.sh85
-rw-r--r--contrib/bc/include/args.h55
-rw-r--r--contrib/bc/include/bc.h458
-rw-r--r--contrib/bc/include/bcl.h242
-rw-r--r--contrib/bc/include/dc.h104
-rw-r--r--contrib/bc/include/file.h177
-rw-r--r--contrib/bc/include/history.h338
-rw-r--r--contrib/bc/include/lang.h700
-rw-r--r--contrib/bc/include/lex.h586
-rw-r--r--contrib/bc/include/library.h239
-rw-r--r--contrib/bc/include/num.h860
-rw-r--r--contrib/bc/include/opt.h140
-rw-r--r--contrib/bc/include/parse.h275
-rw-r--r--contrib/bc/include/program.h971
-rw-r--r--contrib/bc/include/rand.h519
-rw-r--r--contrib/bc/include/read.h82
-rw-r--r--contrib/bc/include/status.h793
-rw-r--r--contrib/bc/include/vector.h461
-rw-r--r--contrib/bc/include/version.h42
-rw-r--r--contrib/bc/include/vm.h876
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.msg111
l---------contrib/bc/locales/de_DE.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/de_DE.UTF-8.msg111
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.msg111
l---------contrib/bc/locales/en_US.utf8.msg1
-rw-r--r--contrib/bc/locales/es_ES.ISO8859-1.msg111
l---------contrib/bc/locales/es_ES.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/es_ES.UTF-8.msg111
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.msg111
l---------contrib/bc/locales/fr_FR.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/fr_FR.UTF-8.msg111
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.msg111
l---------contrib/bc/locales/pt_PT.ISO8859-15.msg1
-rw-r--r--contrib/bc/locales/pt_PT.UTF-8.msg111
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.msg110
-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.msg111
-rw-r--r--contrib/bc/locales/zh_CN.GB2312.msg111
-rw-r--r--contrib/bc/locales/zh_CN.GBK.msg111
-rw-r--r--contrib/bc/locales/zh_CN.UTF-8.msg111
-rw-r--r--contrib/bc/locales/zh_CN.eucCN.msg111
l---------contrib/bc/locales/zh_CN.utf8.msg1
-rw-r--r--contrib/bc/manuals/algorithms.md329
-rw-r--r--contrib/bc/manuals/bc/A.12784
-rw-r--r--contrib/bc/manuals/bc/A.1.md2347
-rw-r--r--contrib/bc/manuals/bc/E.11630
-rw-r--r--contrib/bc/manuals/bc/E.1.md1365
-rw-r--r--contrib/bc/manuals/bc/EH.11601
-rw-r--r--contrib/bc/manuals/bc/EH.1.md1339
-rw-r--r--contrib/bc/manuals/bc/EHN.11594
-rw-r--r--contrib/bc/manuals/bc/EHN.1.md1331
-rw-r--r--contrib/bc/manuals/bc/EN.11623
-rw-r--r--contrib/bc/manuals/bc/EN.1.md1357
-rw-r--r--contrib/bc/manuals/bc/H.12755
-rw-r--r--contrib/bc/manuals/bc/H.1.md2321
-rw-r--r--contrib/bc/manuals/bc/HN.12748
-rw-r--r--contrib/bc/manuals/bc/HN.1.md2313
-rw-r--r--contrib/bc/manuals/bc/N.12777
-rw-r--r--contrib/bc/manuals/bc/N.1.md2339
-rw-r--r--contrib/bc/manuals/bcl.31394
-rw-r--r--contrib/bc/manuals/bcl.3.md1202
-rw-r--r--contrib/bc/manuals/build.md838
-rw-r--r--contrib/bc/manuals/dc/A.11549
-rw-r--r--contrib/bc/manuals/dc/A.1.md1384
-rw-r--r--contrib/bc/manuals/dc/E.11342
-rw-r--r--contrib/bc/manuals/dc/E.1.md1217
-rw-r--r--contrib/bc/manuals/dc/EH.11316
-rw-r--r--contrib/bc/manuals/dc/EH.1.md1194
-rw-r--r--contrib/bc/manuals/dc/EHN.11312
-rw-r--r--contrib/bc/manuals/dc/EHN.1.md1189
-rw-r--r--contrib/bc/manuals/dc/EN.11338
-rw-r--r--contrib/bc/manuals/dc/EN.1.md1212
-rw-r--r--contrib/bc/manuals/dc/H.11523
-rw-r--r--contrib/bc/manuals/dc/H.1.md1361
-rw-r--r--contrib/bc/manuals/dc/HN.11519
-rw-r--r--contrib/bc/manuals/dc/HN.1.md1356
-rw-r--r--contrib/bc/manuals/dc/N.11545
-rw-r--r--contrib/bc/manuals/dc/N.1.md1379
-rwxr-xr-xcontrib/bc/scripts/exec-install.sh67
-rwxr-xr-xcontrib/bc/scripts/functions.sh328
-rwxr-xr-xcontrib/bc/scripts/karatsuba.py255
-rwxr-xr-xcontrib/bc/scripts/link.sh63
-rwxr-xr-xcontrib/bc/scripts/locale_install.sh299
-rwxr-xr-xcontrib/bc/scripts/locale_uninstall.sh67
-rwxr-xr-xcontrib/bc/scripts/safe-install.sh67
-rw-r--r--contrib/bc/src/args.c288
-rw-r--r--contrib/bc/src/bc.c63
-rw-r--r--contrib/bc/src/bc_lex.c479
-rw-r--r--contrib/bc/src/bc_parse.c2278
-rw-r--r--contrib/bc/src/data.c1320
-rw-r--r--contrib/bc/src/dc.c63
-rw-r--r--contrib/bc/src/dc_lex.c276
-rw-r--r--contrib/bc/src/dc_parse.c321
-rw-r--r--contrib/bc/src/file.c311
-rw-r--r--contrib/bc/src/history.c1765
-rw-r--r--contrib/bc/src/lang.c345
-rw-r--r--contrib/bc/src/lex.c311
-rw-r--r--contrib/bc/src/library.c1281
-rw-r--r--contrib/bc/src/main.c96
-rw-r--r--contrib/bc/src/num.c3931
-rw-r--r--contrib/bc/src/opt.c359
-rw-r--r--contrib/bc/src/parse.c251
-rw-r--r--contrib/bc/src/program.c3307
-rw-r--r--contrib/bc/src/rand.c581
-rw-r--r--contrib/bc/src/read.c299
-rw-r--r--contrib/bc/src/vector.c586
-rw-r--r--contrib/bc/src/vm.c1468
-rwxr-xr-xcontrib/bc/tests/all.sh214
-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.txt52
-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/bitfuncs.txt5400
-rw-r--r--contrib/bc/tests/bc/bitfuncs_results.txt5400
-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.txt65
-rw-r--r--contrib/bc/tests/bc/decimal_results.txt76
-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/divmod.txt64
-rw-r--r--contrib/bc/tests/bc/divmod_results.txt126
-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.txt304
-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/errors/25.txt4
-rw-r--r--contrib/bc/tests/bc/errors/26.txtbin0 -> 317 bytes
-rw-r--r--contrib/bc/tests/bc/errors/27.txt1
-rw-r--r--contrib/bc/tests/bc/errors/28.txt2
-rw-r--r--contrib/bc/tests/bc/errors/29.txt20
-rw-r--r--contrib/bc/tests/bc/errors/30.txt3
-rw-r--r--contrib/bc/tests/bc/errors/31.txt3
-rw-r--r--contrib/bc/tests/bc/errors/32.txtbin0 -> 1701 bytes
-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/leadingzero.txt12
-rw-r--r--contrib/bc/tests/bc/leadingzero_results.txt12
-rw-r--r--contrib/bc/tests/bc/length.txt132
-rw-r--r--contrib/bc/tests/bc/length_results.txt130
-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.txt476
-rw-r--r--contrib/bc/tests/bc/lib2_results.txt711
-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/modexp.txt103
-rw-r--r--contrib/bc/tests/bc/modexp_results.txt103
-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.txt134
-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.txt32
-rw-r--r--contrib/bc/tests/bc/power.txt86
-rw-r--r--contrib/bc/tests/bc/power_results.txt144
-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/recursive_arrays.txt353
-rw-r--r--contrib/bc/tests/bc/recursive_arrays_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
-rw-r--r--contrib/bc/tests/bc/scripts/all.txt16
-rw-r--r--contrib/bc/tests/bc/scripts/array.bc60
-rw-r--r--contrib/bc/tests/bc/scripts/array.txt428
-rw-r--r--contrib/bc/tests/bc/scripts/atan.bc11
-rw-r--r--contrib/bc/tests/bc/scripts/atan.txt301
-rw-r--r--contrib/bc/tests/bc/scripts/bessel.bc48
-rw-r--r--contrib/bc/tests/bc/scripts/divide.bc23
-rw-r--r--contrib/bc/tests/bc/scripts/functions.bc7
-rw-r--r--contrib/bc/tests/bc/scripts/functions.txt2
-rw-r--r--contrib/bc/tests/bc/scripts/globals.bc27
-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.bc20
-rw-r--r--contrib/bc/tests/bc/scripts/parse.bc20
-rw-r--r--contrib/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
-rw-r--r--contrib/bc/tests/bc/scripts/references.bc408
-rw-r--r--contrib/bc/tests/bc/scripts/references.txt1272
-rw-r--r--contrib/bc/tests/bc/scripts/screen.bc20
-rw-r--r--contrib/bc/tests/bc/scripts/screen.txt1
-rw-r--r--contrib/bc/tests/bc/scripts/strings2.bc7
-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.txt77
-rw-r--r--contrib/bc/tests/bc/strings_results.txt53
-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.sh116
-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.txt11
-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.c356
-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.txt25
-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.txt41
-rw-r--r--contrib/bc/tests/dc/decimal_results.txt54
-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.txt39
-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/errors/30.txt1
-rw-r--r--contrib/bc/tests/dc/errors/31.txt1
-rw-r--r--contrib/bc/tests/dc/errors/32.txt20
-rw-r--r--contrib/bc/tests/dc/errors/33.txtbin0 -> 323 bytes
-rw-r--r--contrib/bc/tests/dc/errors/34.txt117
-rw-r--r--contrib/bc/tests/dc/exec_stack_len.txt6
-rw-r--r--contrib/bc/tests/dc/exec_stack_len_results.txt8
-rw-r--r--contrib/bc/tests/dc/length.txt131
-rw-r--r--contrib/bc/tests/dc/length_results.txt131
-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.txt55
-rw-r--r--contrib/bc/tests/dc/scientific_results.txt54
-rw-r--r--contrib/bc/tests/dc/scripts/all.txt9
-rw-r--r--contrib/bc/tests/dc/scripts/array.dc3
-rw-r--r--contrib/bc/tests/dc/scripts/array.txt201
-rw-r--r--contrib/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/easter.sh47
-rw-r--r--contrib/bc/tests/dc/scripts/else.dc4
-rw-r--r--contrib/bc/tests/dc/scripts/else.txt34
-rw-r--r--contrib/bc/tests/dc/scripts/factorial.dc4
-rw-r--r--contrib/bc/tests/dc/scripts/factorial.txt50
-rw-r--r--contrib/bc/tests/dc/scripts/loop.dc3
-rw-r--r--contrib/bc/tests/dc/scripts/loop.txt20
-rw-r--r--contrib/bc/tests/dc/scripts/prime.dc1
-rw-r--r--contrib/bc/tests/dc/scripts/quit.dc2
-rw-r--r--contrib/bc/tests/dc/scripts/quit.txt99
-rw-r--r--contrib/bc/tests/dc/scripts/stream.dc1
-rw-r--r--contrib/bc/tests/dc/scripts/stream.txtbin0 -> 130834 bytes
-rw-r--r--contrib/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/stack_len.txt15
-rw-r--r--contrib/bc/tests/dc/stack_len_results.txt10
-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.txt51
-rw-r--r--contrib/bc/tests/dc/strings_results.txt52
-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/error.sh99
-rwxr-xr-xcontrib/bc/tests/errors.sh149
-rw-r--r--contrib/bc/tests/extra_required.txt9
-rwxr-xr-xcontrib/bc/tests/history.py1153
-rwxr-xr-xcontrib/bc/tests/history.sh110
-rwxr-xr-xcontrib/bc/tests/other.sh411
-rwxr-xr-xcontrib/bc/tests/read.sh140
-rw-r--r--contrib/bc/tests/script.sed9
-rwxr-xr-xcontrib/bc/tests/script.sh185
-rwxr-xr-xcontrib/bc/tests/scripts.sh132
-rwxr-xr-xcontrib/bc/tests/stdin.sh103
-rwxr-xr-xcontrib/bc/tests/test.sh151
-rw-r--r--contrib/bc/vs/bc.sln31
-rw-r--r--contrib/bc/vs/bc.vcxproj297
-rw-r--r--contrib/bc/vs/bc.vcxproj.filters173
-rw-r--r--contrib/bc/vs/bcl.sln37
-rw-r--r--contrib/bc/vs/bcl.vcxproj259
-rw-r--r--contrib/bc/vs/bcl.vcxproj.filters90
-rw-r--r--contrib/bc/vs/bin/some.txt0
-rw-r--r--contrib/bc/vs/tests/some.txt0
-rw-r--r--contrib/bc/vs/tests/tests_bc.bat104
-rw-r--r--contrib/bc/vs/tests/tests_dc.bat61
496 files changed, 138550 insertions, 0 deletions
diff --git a/contrib/bc/.gitattributes b/contrib/bc/.gitattributes
new file mode 100644
index 000000000000..1e2c56dde215
--- /dev/null
+++ b/contrib/bc/.gitattributes
@@ -0,0 +1,3 @@
+*.vcxproj eol=crlf
+*.vcxproj.filters eol=crlf
+*.sln eol=crlf
diff --git a/contrib/bc/.gitignore b/contrib/bc/.gitignore
new file mode 100644
index 000000000000..31e43aa61efc
--- /dev/null
+++ b/contrib/bc/.gitignore
@@ -0,0 +1,80 @@
+*.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
+
+tests/fuzzing/bc_outputs1/*
+tests/fuzzing/bc_outputs2/*
+tests/fuzzing/bc_outputs3/*
+tests/fuzzing/dc_outputs/*
+tests/bc_outputs/*
+tests/dc_outputs/*
+
+.gdb_history
+
+# Ignore the generated test files
+parse.txt
+parse_results.txt
+print.txt
+print_results.txt
+bessel.txt
+bessel_results.txt
+prime.txt
+strings2.txt
+strings2_results.txt
+tests/bc/scripts/add.txt
+tests/bc/scripts/divide.txt
+tests/bc/scripts/multiply.txt
+tests/bc/scripts/subtract.txt
+tests/bc/scripts/strings2.txt
+benchmarks/bc/*.txt
+benchmarks/dc/*.txt
+scripts/ministat
+scripts/bitgen
+perf.data
+perf.data.old
+*.gcda
+*.gcno
+*.gcov
+*.html
+*.profraw
+
+core.*
+
+cscope*.out
+tags
+
+*.vcxproj.user
+Debug/*
+Release/*
diff --git a/contrib/bc/LICENSE.md b/contrib/bc/LICENSE.md
new file mode 100644
index 000000000000..8ab2e6069881
--- /dev/null
+++ b/contrib/bc/LICENSE.md
@@ -0,0 +1,113 @@
+# License
+
+Copyright (c) 2018-2021 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-2021, 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.
+
+## Rand
+
+The files `src/rand.c` and `include/rand.h` are under the following copyrights
+and license:
+
+Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
+Copyright (c) 2018-2021 Gavin D. Howard <yzena.tech@gmail.com>
+
+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.
+
+## `scripts/safe-install.sh`
+
+The file `scripts/safe-install.sh` is under the following copyright and license:
+
+Copyright (c) 2021 Rich Felker
+
+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.
+
+## `scripts/ministat.c`
+
+The file `scripts/ministat.c` is under the following license:
+
+"THE BEER-WARE LICENSE" (Revision 42):
+
+<phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
+can do whatever you want with this stuff. If we meet some day, and you think
+this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
diff --git a/contrib/bc/Makefile.in b/contrib/bc/Makefile.in
new file mode 100644
index 000000000000..3d6780d6ac95
--- /dev/null
+++ b/contrib/bc/Makefile.in
@@ -0,0 +1,615 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# %%WARNING%%
+#
+.POSIX:
+
+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%%
+
+HEADERS = include/args.h include/file.h include/lang.h include/lex.h include/num.h include/opt.h include/parse.h include/program.h include/read.h include/status.h include/vector.h include/vm.h
+BC_HEADERS = include/bc.h
+DC_HEADERS = include/dc.h
+HISTORY_HEADERS = include/history.h
+EXTRA_MATH_HEADERS = include/rand.h
+LIBRARY_HEADERS = include/bcl.h include/library.h
+
+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)
+
+BC_TEST_OUTPUTS = tests/bc_outputs
+BC_FUZZ_OUTPUTS = tests/fuzzing/bc_outputs1 tests/fuzzing/bc_outputs2 tests/fuzzing/bc_outputs3
+DC_TEST_OUTPUTS = tests/dc_outputs
+DC_FUZZ_OUTPUTS = tests/fuzzing/dc_outputs
+
+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_BUILD_TYPE = %%BUILD_TYPE%%
+
+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_LONG_BIT = %%LONG_BIT%%
+
+BC_ENABLE_AFL = %%FUZZ%%
+BC_ENABLE_MEMCHECK = %%MEMCHECK%%
+
+BC_DEFAULT_BANNER = %%BC_DEFAULT_BANNER%%
+BC_DEFAULT_SIGINT_RESET = %%BC_DEFAULT_SIGINT_RESET%%
+DC_DEFAULT_SIGINT_RESET = %%DC_DEFAULT_SIGINT_RESET%%
+BC_DEFAULT_TTY_MODE = %%BC_DEFAULT_TTY_MODE%%
+DC_DEFAULT_TTY_MODE = %%DC_DEFAULT_TTY_MODE%%
+BC_DEFAULT_PROMPT = %%BC_DEFAULT_PROMPT%%
+DC_DEFAULT_PROMPT = %%DC_DEFAULT_PROMPT%%
+
+RM = rm
+MKDIR = mkdir
+
+SCRIPTS = ./scripts
+
+MINISTAT = ministat
+MINISTAT_EXEC = $(SCRIPTS)/$(MINISTAT)
+
+BITFUNCGEN = bitfuncgen
+BITFUNCGEN_EXEC = $(SCRIPTS)/$(BITFUNCGEN)
+
+INSTALL = $(SCRIPTS)/exec-install.sh
+SAFE_INSTALL = $(SCRIPTS)/safe-install.sh
+LINK = $(SCRIPTS)/link.sh
+MANPAGE = $(SCRIPTS)/manpage.sh
+KARATSUBA = $(SCRIPTS)/karatsuba.py
+LOCALE_INSTALL = $(SCRIPTS)/locale_install.sh
+LOCALE_UNINSTALL = $(SCRIPTS)/locale_uninstall.sh
+
+VALGRIND_ARGS = --error-exitcode=100 --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all
+
+TEST_STARS = ***********************************************************************
+
+BC_NUM_KARATSUBA_LEN = %%KARATSUBA_LEN%%
+
+BC_DEFS0 = -DBC_DEFAULT_BANNER=$(BC_DEFAULT_BANNER)
+BC_DEFS1 = -DBC_DEFAULT_SIGINT_RESET=$(BC_DEFAULT_SIGINT_RESET)
+BC_DEFS2 = -DBC_DEFAULT_TTY_MODE=$(BC_DEFAULT_TTY_MODE)
+BC_DEFS3 = -DBC_DEFAULT_PROMPT=$(BC_DEFAULT_PROMPT)
+BC_DEFS = $(BC_DEFS0) $(BC_DEFS1) $(BC_DEFS2) $(BC_DEFS3)
+DC_DEFS1 = -DDC_DEFAULT_SIGINT_RESET=$(DC_DEFAULT_SIGINT_RESET)
+DC_DEFS2 = -DDC_DEFAULT_TTY_MODE=$(DC_DEFAULT_TTY_MODE)
+DC_DEFS3 = -DDC_DEFAULT_PROMPT=$(DC_DEFAULT_PROMPT)
+DC_DEFS = $(DC_DEFS1) $(DC_DEFS2) $(DC_DEFS3)
+
+CPPFLAGS1 = -D$(BC_ENABLED_NAME)=$(BC_ENABLED) -D$(DC_ENABLED_NAME)=$(DC_ENABLED)
+CPPFLAGS2 = $(CPPFLAGS1) -I./include/ -DBUILD_TYPE=$(BC_BUILD_TYPE) %%LONG_BIT_DEFINE%%
+CPPFLAGS3 = $(CPPFLAGS2) -DEXECPREFIX=$(EXEC_PREFIX) -DMAINEXEC=$(MAIN_EXEC)
+CPPFLAGS4 = $(CPPFLAGS3) -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 %%BSD%%
+CPPFLAGS5 = $(CPPFLAGS4) -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN)
+CPPFLAGS6 = $(CPPFLAGS5) -DBC_ENABLE_NLS=$(BC_ENABLE_NLS)
+CPPFLAGS7 = $(CPPFLAGS6) -D$(BC_ENABLE_EXTRA_MATH_NAME)=$(BC_ENABLE_EXTRA_MATH)
+CPPFLAGS8 = $(CPPFLAGS7) -DBC_ENABLE_HISTORY=$(BC_ENABLE_HISTORY) -DBC_ENABLE_LIBRARY=$(BC_ENABLE_LIBRARY)
+CPPFLAGS = $(CPPFLAGS8) -DBC_ENABLE_MEMCHECK=$(BC_ENABLE_MEMCHECK) -DBC_ENABLE_AFL=$(BC_ENABLE_AFL)
+CFLAGS = $(CPPFLAGS) $(BC_DEFS) $(DC_DEFS) %%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 = $(DC_HELP_O) $(BC_HELP_O) $(BC_LIB_O) $(BC_LIB2_O) $(OBJ)
+
+all: %%DEFAULT_TARGET%%
+
+%%DEFAULT_TARGET%%: %%DEFAULT_TARGET_PREREQS%%
+ %%DEFAULT_TARGET_CMD%%
+
+%%SECOND_TARGET%%: %%SECOND_TARGET_PREREQS%%
+ %%SECOND_TARGET_CMD%%
+
+$(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_LIB_O): $(BC_LIB_C)
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+$(BC_LIB2_C): $(GEN_EXEC) $(BC_LIB2)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_LIB2) $(BC_LIB2_C) $(BC_LIB2_C_ARGS)
+
+$(BC_LIB2_O): $(BC_LIB2_C)
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+$(BC_HELP_C): $(GEN_EXEC) $(BC_HELP)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) bc_help "" $(BC_ENABLED_NAME)
+
+$(BC_HELP_O): $(BC_HELP_C)
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+$(DC_HELP_C): $(GEN_EXEC) $(DC_HELP)
+ $(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) dc_help "" $(DC_ENABLED_NAME)
+
+$(DC_HELP_O): $(DC_HELP_C)
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+$(BIN):
+ $(MKDIR) -p $(BIN)
+
+headers: %%HEADERS%%
+
+$(MINISTAT):
+ $(HOSTCC) $(HOSTCFLAGS) -lm -o $(MINISTAT_EXEC) scripts/ministat.c
+
+$(BITFUNCGEN):
+ $(HOSTCC) $(HOSTCFLAGS) -lm -o $(BITFUNCGEN_EXEC) scripts/bitfuncgen.c
+
+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'
+
+run_all_tests: bc_all_tests timeconst_all_tests dc_all_tests
+
+run_all_tests_np: bc_all_tests_np timeconst_all_tests dc_all_tests_np
+
+bc_all_tests:
+ %%BC_ALL_TESTS%%
+
+bc_all_tests_np:
+ %%BC_ALL_TESTS_NP%%
+
+timeconst_all_tests:
+ %%TIMECONST_ALL_TESTS%%
+
+dc_all_tests:
+ %%DC_ALL_TESTS%%
+
+dc_all_tests_np:
+ %%DC_ALL_TESTS_NP%%
+
+history_all_tests:
+ %%HISTORY_TESTS%%
+
+check: test
+
+test: %%TESTS%%
+
+test_bc: test_bc_header test_bc_tests test_bc_scripts test_bc_errors test_bc_stdin test_bc_read test_bc_other
+ @printf '\nAll bc tests passed.\n\n$(TEST_STARS)\n'
+
+test_bc_tests:%%BC_TESTS%%
+
+test_bc_scripts:%%BC_SCRIPT_TESTS%%
+
+test_bc_stdin:
+ @sh tests/stdin.sh bc %%BC_TEST_EXEC%%
+
+test_bc_read:
+ @sh tests/read.sh bc %%BC_TEST_EXEC%%
+
+test_bc_errors: test_bc_error_lines%%BC_ERROR_TESTS%%
+
+test_bc_error_lines:
+ @sh tests/errors.sh bc %%BC_TEST_EXEC%%
+
+test_bc_other:
+ @sh tests/other.sh bc $(BC_ENABLE_EXTRA_MATH) %%BC_TEST_EXEC%%
+
+test_bc_header:
+ @printf '$(TEST_STARS)\n\nRunning bc tests...\n\n'
+
+test_dc: test_dc_header test_dc_tests test_dc_scripts test_dc_errors test_dc_stdin test_dc_read test_dc_other
+ @printf '\nAll dc tests passed.\n\n$(TEST_STARS)\n'
+
+test_dc_tests:%%DC_TESTS%%
+
+test_dc_scripts:%%DC_SCRIPT_TESTS%%
+
+test_dc_stdin:
+ @sh tests/stdin.sh dc %%DC_TEST_EXEC%%
+
+test_dc_read:
+ @sh tests/read.sh dc %%DC_TEST_EXEC%%
+
+test_dc_errors: test_dc_error_lines%%DC_ERROR_TESTS%%
+
+test_dc_error_lines:
+ @sh tests/errors.sh dc %%DC_TEST_EXEC%%
+
+test_dc_other:
+ @sh tests/other.sh dc $(BC_ENABLE_EXTRA_MATH) %%DC_TEST_EXEC%%
+
+test_dc_header:
+ @printf '$(TEST_STARS)\n\nRunning dc tests...\n\n'
+
+timeconst:
+ %%TIMECONST%%
+
+test_history: test_history_header test_bc_history test_dc_history
+ @printf '\nAll history tests passed.\n\n$(TEST_STARS)\n'
+
+test_bc_history:%%BC_HISTORY_TEST_PREREQS%%
+
+test_bc_history_all: test_bc_history0 test_bc_history1 test_bc_history2 test_bc_history3 test_bc_history4 test_bc_history5 test_bc_history6 test_bc_history7 test_bc_history8 test_bc_history9 test_bc_history10 test_bc_history11 test_bc_history12 test_bc_history13 test_bc_history14 test_bc_history15 test_bc_history16 test_bc_history17 test_bc_history18 test_bc_history19 test_bc_history20 test_bc_history21
+
+test_bc_history_skip:
+ @printf 'No bc history tests to run\n'
+
+test_bc_history0:
+ @sh tests/history.sh bc 0 %%BC_TEST_EXEC%%
+
+test_bc_history1:
+ @sh tests/history.sh bc 1 %%BC_TEST_EXEC%%
+
+test_bc_history2:
+ @sh tests/history.sh bc 2 %%BC_TEST_EXEC%%
+
+test_bc_history3:
+ @sh tests/history.sh bc 3 %%BC_TEST_EXEC%%
+
+test_bc_history4:
+ @sh tests/history.sh bc 4 %%BC_TEST_EXEC%%
+
+test_bc_history5:
+ @sh tests/history.sh bc 5 %%BC_TEST_EXEC%%
+
+test_bc_history6:
+ @sh tests/history.sh bc 6 %%BC_TEST_EXEC%%
+
+test_bc_history7:
+ @sh tests/history.sh bc 7 %%BC_TEST_EXEC%%
+
+test_bc_history8:
+ @sh tests/history.sh bc 8 %%BC_TEST_EXEC%%
+
+test_bc_history9:
+ @sh tests/history.sh bc 9 %%BC_TEST_EXEC%%
+
+test_bc_history10:
+ @sh tests/history.sh bc 10 %%BC_TEST_EXEC%%
+
+test_bc_history11:
+ @sh tests/history.sh bc 11 %%BC_TEST_EXEC%%
+
+test_bc_history12:
+ @sh tests/history.sh bc 12 %%BC_TEST_EXEC%%
+
+test_bc_history13:
+ @sh tests/history.sh bc 13 %%BC_TEST_EXEC%%
+
+test_bc_history14:
+ @sh tests/history.sh bc 14 %%BC_TEST_EXEC%%
+
+test_bc_history15:
+ @sh tests/history.sh bc 15 %%BC_TEST_EXEC%%
+
+test_bc_history16:
+ @sh tests/history.sh bc 16 %%BC_TEST_EXEC%%
+
+test_bc_history17:
+ @sh tests/history.sh bc 17 %%BC_TEST_EXEC%%
+
+test_bc_history18:
+ @sh tests/history.sh bc 18 %%BC_TEST_EXEC%%
+
+test_bc_history19:
+ @sh tests/history.sh bc 19 %%BC_TEST_EXEC%%
+
+test_bc_history20:
+ @sh tests/history.sh bc 20 %%BC_TEST_EXEC%%
+
+test_bc_history21:
+ @sh tests/history.sh bc 21 %%BC_TEST_EXEC%%
+
+test_dc_history:%%DC_HISTORY_TEST_PREREQS%%
+
+test_dc_history_all: test_dc_history0 test_dc_history1 test_dc_history2 test_dc_history3 test_dc_history4 test_dc_history5 test_dc_history6 test_dc_history7 test_dc_history8 test_dc_history9
+
+test_dc_history_skip:
+ @printf 'No dc history tests to run\n'
+
+test_dc_history0:
+ @sh tests/history.sh dc 0 %%DC_TEST_EXEC%%
+
+test_dc_history1:
+ @sh tests/history.sh dc 1 %%DC_TEST_EXEC%%
+
+test_dc_history2:
+ @sh tests/history.sh dc 2 %%DC_TEST_EXEC%%
+
+test_dc_history3:
+ @sh tests/history.sh dc 3 %%DC_TEST_EXEC%%
+
+test_dc_history4:
+ @sh tests/history.sh dc 4 %%DC_TEST_EXEC%%
+
+test_dc_history5:
+ @sh tests/history.sh dc 5 %%DC_TEST_EXEC%%
+
+test_dc_history6:
+ @sh tests/history.sh dc 6 %%DC_TEST_EXEC%%
+
+test_dc_history7:
+ @sh tests/history.sh dc 7 %%DC_TEST_EXEC%%
+
+test_dc_history8:
+ @sh tests/history.sh dc 8 %%DC_TEST_EXEC%%
+
+test_dc_history9:
+ @sh tests/history.sh dc 9 %%DC_TEST_EXEC%%
+
+test_history_header:
+ @printf '$(TEST_STARS)\n\nRunning history tests...\n\n'
+
+library_test: $(LIBBC)
+ $(CC) $(CFLAGS) $(BCL_TEST_C) $(LIBBC) -o $(BCL_TEST)
+
+test_library: library_test
+ $(BCL_TEST)
+
+karatsuba:
+ %%KARATSUBA%%
+
+karatsuba_test:
+ %%KARATSUBA_TEST%%
+
+coverage_output:
+ %%COVERAGE_OUTPUT%%
+
+coverage:%%COVERAGE_PREREQS%%
+
+manpages:
+ $(MANPAGE) bc
+ $(MANPAGE) dc
+ $(MANPAGE) bcl
+
+clean_gen:
+ @$(RM) -f $(GEN_EXEC)
+
+clean:%%CLEAN_PREREQS%%
+ @printf 'Cleaning files...\n'
+ @$(RM) -f src/*.tmp gen/*.tmp
+ @$(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)
+ @$(RM) -fr Debug/ Release/
+
+clean_benchmarks:
+ @printf 'Cleaning benchmarks...\n'
+ @$(RM) -f $(MINISTAT_EXEC)
+ @$(RM) -f benchmarks/bc/*.txt
+ @$(RM) -f benchmarks/dc/*.txt
+
+clean_config: clean clean_benchmarks
+ @printf 'Cleaning config...\n'
+ @$(RM) -f Makefile
+ @$(RM) -f $(BC_MD) $(BC_MANPAGE)
+ @$(RM) -f $(DC_MD) $(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) -fr $(BC_TEST_OUTPUTS) $(DC_TEST_OUTPUTS)
+ @$(RM) -fr $(BC_FUZZ_OUTPUTS) $(DC_FUZZ_OUTPUTS)
+ @$(RM) -f tests/bc/parse.txt tests/bc/parse_results.txt
+ @$(RM) -f tests/bc/print.txt tests/bc/print_results.txt
+ @$(RM) -f tests/bc/bessel.txt tests/bc/bessel_results.txt
+ @$(RM) -f tests/bc/strings2.txt tests/bc/strings2_results.txt
+ @$(RM) -f tests/bc/scripts/bessel.txt
+ @$(RM) -f tests/bc/scripts/parse.txt
+ @$(RM) -f tests/bc/scripts/print.txt
+ @$(RM) -f tests/bc/scripts/add.txt
+ @$(RM) -f tests/bc/scripts/divide.txt
+ @$(RM) -f tests/bc/scripts/multiply.txt
+ @$(RM) -f tests/bc/scripts/subtract.txt
+ @$(RM) -f tests/bc/scripts/strings2.txt
+ @$(RM) -f tests/dc/scripts/prime.txt
+ @$(RM) -f .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
+ @$(RM) -f $(BITFUNCGEN_EXEC)
+
+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..98b52024b2e8
--- /dev/null
+++ b/contrib/bc/NEWS.md
@@ -0,0 +1,1203 @@
+# News
+
+## 5.1.0
+
+This is a production release with some fixes and new features.
+
+* Fixed a bug where an `if` statement without an `else` before defining a
+ function caused an error.
+* Fixed a bug with the `bc` banner and `-q`.
+* Fixed a bug on Windows where files were not read correctly.
+* Added a command-line flag (`-z`) to make `bc` and `dc` print leading zeroes on
+ numbers `-1 < x < 1`.
+* Added four functions to `lib2.bc` (`plz()`, `plznl()`, `pnlz()`, and
+ `pnlznl()`) to allow printing numbers with or without leading zeros, despite
+ the use of `-z` or not.
+* Added builtin functions to query global state like line length, global stacks,
+ and leading zeroes.
+* Added a command-line flag (`-L`) to disable wrapping when printing numbers.
+* Improved builds on Windows.
+
+## 5.0.2
+
+This is a production release with one fix for a flaky test. If you have not
+experienced problems with the test suite, you do ***NOT*** need to upgrade.
+
+The test was one that tested whether `bc` fails gracefully when it can't
+allocate memory. Unfortunately, there are cases when Linux and FreeBSD lie and
+pretend to allocate the memory.
+
+The reason they do this is because a lot of programs don't use all of the memory
+they allocate, so those OS's usually get away with it.
+
+However, this `bc` uses all of the memory it allocates (at least at page
+granularity), so when it tries to use the memory, FreeBSD and Linux kill it.
+
+This only happens sometimes, however. Other times (on my machine), they do, in
+fact, refuse the request.
+
+So I changed the test to not test for that because I think the graceful failure
+code won't really change much.
+
+## 5.0.1
+
+This is a production release with two fixes:
+
+* Fix for the build on Mac OSX.
+* Fix for the build on Android.
+
+Users that do not use those platforms do ***NOT*** need to update.
+
+## 5.0.0
+
+This is a major production release with several changes:
+
+* Added support for OpenBSD's `pledge()` and `unveil()`.
+* Fixed print bug where a backslash newline combo was printed even if only one
+ digit was left, something I blindly copied from GNU `bc`, like a fool.
+* Fixed bugs in the manuals.
+* Fixed a possible multiplication overflow in power.
+* Temporary numbers are garbage collected if allocation fails, and the
+ allocation is retried. This is to make `bc` and `dc` more resilient to running
+ out of memory.
+* Limited the number of temporary numbers and made the space for them static so
+ that allocating more space for them cannot fail.
+* Allowed integers with non-zero `scale` to be used with power, places, and
+ shift operators.
+* Added greatest common divisor and least common multiple to `lib2.bc`.
+* Added `SIGQUIT` handling to history.
+* Added a command to `dc` (`y`) to get the length of register stacks.
+* Fixed multi-digit bugs in `lib2.bc`.
+* Removed the no prompt build option.
+* Created settings that builders can set defaults for and users can set their
+ preferences for. This includes the `bc` banner, resetting on `SIGINT`, TTY
+ mode, and prompt.
+* Added history support to Windows.
+* Fixed bugs with the handling of register names in `dc`.
+* Fixed bugs with multi-line comments and strings in both calculators.
+* Added a new error type and message for `dc` when register stacks don't have
+ enough items.
+* Optimized string allocation.
+* Made `bc` and `dc` UTF-8 capable.
+* Fixed a bug with `void` functions.
+* Fixed a misspelled symbol in `bcl`. This is technically a breaking change,
+ which requires this to be `5.0.0`.
+* Added the ability for users to get the copyright banner back.
+* Added the ability for users to have `bc` and `dc` quit on `SIGINT`.
+* Added the ability for users to disable prompt and TTY mode by environment
+ variables.
+* Added the ability for users to redefine keywords. This is another reason this
+ is `5.0.0`.
+* Added `dc`'s modular exponentiation and divmod to `bc`.
+* Added the ability to assign strings to variables and array elements and pass
+ them to functions in `bc`.
+* Added `dc`'s asciify command and stream printing to `bc`.
+* Added a command to `dc` (`Y`) to get the length of an array.
+* Added a command to `dc` (`,`) to get the depth of the execution stack.
+* Added bitwise and, or, xor, left shift, right shift, reverse, left rotate,
+ right rotate, and mod functions to `lib2.bc`.
+* Added the functions `s2u(x)` and `s2un(x,n)`, to `lib2.bc`.
+
+## 4.0.2
+
+This is a production release that fixes two bugs:
+
+1. If no files are used and the first statement on `stdin` is invalid, `scale`
+ would not be set to `20` even if `-l` was used.
+2. When using history, `bc` failed to respond properly to `SIGSTOP` and
+ `SIGTSTP`.
+
+## 4.0.1
+
+This is a production release that only adds one thing: flushing output when it
+is printed with a print statement.
+
+## 4.0.0
+
+This is a production release with many fixes, a new command-line option, and a
+big surprise:
+
+* A bug was fixed in `dc`'s `P` command where the item on the stack was *not*
+ popped.
+* Various bugs in the manuals have been fixed.
+* A known bug was fixed where history did not interact well with prompts printed
+ by user code without newlines.
+* A new command-line option, `-R` and `--no-read-prompt` was added to disable
+ just the prompt when using `read()` (`bc`) or `?` (`dc`).
+* And finally, **official support for Windows was added**.
+
+The last item is why this is a major version bump.
+
+Currently, only one set of build options (extra math and prompt enabled, history
+and NLS/locale support disabled, both calculators enabled) is supported on
+Windows. However, both debug and release builds are supported.
+
+In addition, Windows builds are supported for the the library (`bcl`).
+
+For more details about how to build on Windows, see the [README][5] or the
+[build manual][13].
+
+## 3.3.4
+
+This is a production release that fixes a small bug.
+
+The bug was that output was not flushed before a `read()` call, so prompts
+without a newline on the end were not flushed before the `read()` call.
+
+This is such a tiny bug that users only need to upgrade if they are affected.
+
+## 3.3.3
+
+This is a production release with one tweak and fixes for manuals.
+
+The tweak is that `length(0)` returns `1` instead of `0`. In `3.3.1`, I changed
+it so `length(0.x)`, where `x` could be any number of digits, returned the
+`scale`, but `length(0)` still returned `0` because I believe that `0` has `0`
+significant digits.
+
+After request of FreeBSD and considering the arguments of a mathematician,
+compatibility with other `bc`'s, and the expectations of users, I decided to
+make the change.
+
+The fixes for manuals fixed a bug where `--` was rendered as `-`.
+
+## 3.3.2
+
+This is a production release that fixes a divide-by-zero bug in `root()` in the
+[extended math library][16]. All previous versions with `root()` have the bug.
+
+## 3.3.1
+
+This is a production release that fixes a bug.
+
+The bug was in the reporting of number length when the value was 0.
+
+## 3.3.0
+
+This is a production release that changes one behavior and fixes documentation
+bugs.
+
+The changed behavior is the treatment of `-e` and `-f` when given through
+`BC_ENV_ARGS` or `DC_ENV_ARGS`. Now `bc` and `dc` do not exit when those options
+(or their equivalents) are given through those environment variables. However,
+`bc` and `dc` still exit when they or their equivalents are given on the
+command-line.
+
+## 3.2.7
+
+This is a production release that removes a small non-portable shell operation
+in `configure.sh`. This problem was only noticed on OpenBSD, not FreeBSD or
+Linux.
+
+Non-OpenBSD users do ***NOT*** need to upgrade, although NetBSD users may also
+need to upgrade.
+
+## 3.2.6
+
+This is a production release that fixes the build on FreeBSD.
+
+There was a syntax error in `configure.sh` that the Linux shell did not catch,
+and FreeBSD depends on the existence of `tests/all.sh`.
+
+All users that already upgraded to `3.2.5` should update to this release, with
+my apologies for the poor release of `3.2.5`. Other users should skip `3.2.5` in
+favor of this version.
+
+## 3.2.5
+
+This is a production release that fixes several bugs and adds a couple small
+things.
+
+The two most important bugs were bugs that causes `dc` to access memory
+out-of-bounds (crash in debug builds). This was found by upgrading to `afl++`
+from `afl`. Both were caused by a failure to distinguish between the same two
+cases.
+
+Another bug was the failure to put all of the licenses in the `LICENSE.md` file.
+
+Third, some warnings by `scan-build` were found and eliminated. This needed one
+big change: `bc` and `dc` now bail out as fast as possible on fatal errors
+instead of unwinding the stack.
+
+Fourth, the pseudo-random number now attempts to seed itself with `/dev/random`
+if `/dev/urandom` fails.
+
+Finally, this release has a few quality-of-life changes to the build system. The
+usage should not change at all; the only thing that changed was making sure the
+`Makefile.in` was written to rebuild properly when headers changed and to not
+rebuild when not necessary.
+
+## 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`][22] 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 is 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]: ./scripts/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]: ./scripts/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/
+[22]: ./scripts/locale_uninstall.sh
diff --git a/contrib/bc/NOTICE.md b/contrib/bc/NOTICE.md
new file mode 100644
index 000000000000..56d2935ab4b3
--- /dev/null
+++ b/contrib/bc/NOTICE.md
@@ -0,0 +1,14 @@
+# Notice
+
+Copyright 2018-2021 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..c46d66b7e3ea
--- /dev/null
+++ b/contrib/bc/README.md
@@ -0,0 +1,419 @@
+# `bc`
+
+***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` also provides `bc`'s math as a library with C bindings, called `bcl`.
+
+For more information, see the full manual for `bcl`.
+
+## License
+
+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 either:
+
+1. Windows 10 or later, or
+2. A C99-compatible compiler and a (mostly) POSIX 2008-compatible system with
+ the XSI (X/Open System Interfaces) option group.
+
+Since POSIX 2008 with XSI requires the existence of a C99 compiler as `c99`, any
+POSIX and XSI-compatible system will have everything needed.
+
+POSIX-compatible systems that are known to work:
+
+* Linux
+* FreeBSD
+* OpenBSD
+* NetBSD
+* Mac OSX
+* Solaris* (as long as the Solaris version supports POSIX 2008)
+* AIX
+* HP-UX* (except for history)
+
+In addition, there is compatibility code to make this `bc` work on Windows.
+
+Please submit bug reports if this `bc` does not build out of the box on any
+system.
+
+## Build
+
+This `bc` should build unmodified on any POSIX-compliant system or on Windows
+starting with Windows 10 (though earlier versions may work).
+
+For more complex build requirements than the ones below, see the
+[build manual][5].
+
+### Windows
+
+There is no guarantee that this `bc` will work on any version of Windows earlier
+than Windows 10 (I cannot test on earlier versions), but it is guaranteed to
+work on Windows 10 at least.
+
+Also, if building with MSBuild, the MSBuild bundled with Visual Studio is
+required.
+
+**Note**: Unlike the POSIX-compatible platforms, only one build configuration is
+supported on Windows: extra math and prompt enabled, history and NLS (locale
+support) disabled, with both calculators built.
+
+#### `bc`
+
+To build `bc`, you can open the `bc.sln` file in Visual Studio, select the
+configuration, and build.
+
+You can also build using MSBuild with the following from the root directory:
+
+```
+msbuild -property:Configuration=<config> bc.sln
+```
+
+where `<config>` is either one of `Debug` or `Release`.
+
+#### `bcl` (Library)
+
+To build the library, you can open the `bcl.sln` file in Visual Studio, select
+the configuration, and build.
+
+You can also build using MSBuild with the following from the root directory:
+
+```
+msbuild -property:Configuration=<config> bcl.sln
+```
+
+where `<config>` is either one of `Debug` or `Release`.
+
+### POSIX-Compatible Systems
+
+On POSIX-compatible systems, `bc` is built as `bin/bc` and `dc` is built as
+`bin/dc` by default. On Windows, they are built as `Release/bc/bc.exe` and
+`Release/bc/dc.exe`.
+
+**Note**: On Windows, `dc.exe` is just copied from `bc.exe`; it is not linked.
+Patches are welcome for a way to do that.
+
+#### 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` on POSIX-compatible systems or as
+`Release/bcl/bcl.lib` on Windows.
+
+#### 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: `scripts/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.
+
+### Development
+
+If I (Gavin D. Howard) get [hit by a bus][27] and future programmers need to
+handle work themselves, the best place to start is the [Development manual][28].
+
+## Vim Syntax
+
+I have developed (using other people's code to start) [`vim` syntax files][17]
+for this `bc` and `dc`, including the extensions.
+
+## `bc` Libs
+
+I have gathered some excellent [`bc` and `dc` libraries][18]. These libraries
+may prove useful to any serious users.
+
+## Comparison to GNU `bc`
+
+This `bc` compares favorably to GNU `bc`.
+
+* This `bc` builds natively on Windows.
+* It has more extensions, which make this `bc` more useful for scripting.
+* This `bc` is a bit more POSIX compliant.
+* It has a much less buggy parser. The GNU `bc` will give parse errors for what
+ 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, there is no locale support on Windows.
+
+Additionally, this `bc` only has support for English (and US English), French,
+German, Portuguese, Dutch, Polish, Russian, Japanese, and Chinese locales.
+Patches are welcome for translations; use the existing `*.msg` files in
+`locales/` as a starting point.
+
+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 with custom Windows
+compatibility code.
+
+## 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).
+ .gitattributes The git attributes file (maintainer use only).
+ bc.sln The Visual Studio solution file for bc.
+ bc.vcxproj The Visual Studio project file for bc.
+ bc.vcxproj.filters The Visual Studio filters file for bc.
+ bcl.sln The Visual Studio solution file for bcl.
+ bcl.vcxproj The Visual Studio project file for bcl.
+ bcl.vcxproj.filters The Visual Studio filters file for bcl.
+ configure A symlink to configure.sh to make packaging easier.
+ configure.sh The configure script.
+ LICENSE.md A Markdown form of the BSD 2-clause License.
+ Makefile.in The Makefile template.
+ NOTICE.md List of contributors and copyright owners.
+ RELEASE.md A checklist for making a release (maintainer use only).
+
+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.
+ scripts A bunch of shell scripts to help with development and building.
+ tests All tests.
+
+[1]: https://www.gnu.org/software/bc/
+[4]: ./LICENSE.md
+[5]: ./manuals/build.md
+[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://git.yzena.com/gavin/vim-bc
+[18]: https://git.yzena.com/gavin/bc_libs
+[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://cgit.freebsd.org/src/tree/contrib/bc
+[24]: https://bugs.freebsd.org/
+[25]: https://reviews.freebsd.org/
+[26]: ./manuals/bcl.3.md
+[27]: https://en.wikipedia.org/wiki/Bus_factor
+[28]: ./manuals/development.md
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..de1339780073
--- /dev/null
+++ b/contrib/bc/configure.sh
@@ -0,0 +1,1658 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+script="$0"
+scriptdir=$(dirname "$script")
+script=$(basename "$script")
+
+. "$scriptdir/scripts/functions.sh"
+
+cd "$scriptdir"
+
+# Simply prints the help message and quits based on the argument.
+# @param val The value to pass to exit. Must be an integer.
+usage() {
+
+ if [ $# -gt 0 ]; then
+
+ _usage_val=1
+
+ printf "%s\n\n" "$1"
+
+ else
+ _usage_val=0
+ fi
+
+ printf 'usage:\n'
+ printf ' %s -h\n' "$script"
+ printf ' %s --help\n' "$script"
+ printf ' %s [-a|-bD|-dB|-c] [-CEfgGHlmMNPtTvz] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script"
+ printf ' %s \\\n' "$script"
+ printf ' [--library|--bc-only --disable-dc|--dc-only --disable-bc|--coverage] \\\n'
+ printf ' [--force --debug --disable-extra-math --disable-generated-tests] \\\n'
+ printf ' [--disable-history --disable-man-pages --disable-nls --disable-strip] \\\n'
+ printf ' [--install-all-locales] [--opt=OPT_LEVEL] \\\n'
+ printf ' [--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 libbcl 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 gcovr.\n'
+ printf ' It is an error if either "-b" ("-D") or "-d" ("-B") is specified.\n'
+ printf ' Requires a compiler that use gcc-compatible coverage options\n'
+ printf ' -C, --disable-clean\n'
+ printf ' Disable the clean that configure.sh does before configure.\n'
+ printf ' -d, --dc-only\n'
+ printf ' Build dc only. It is an error if "-b", "--bc-only", "-D", or\n'
+ printf ' "--disable-dc" are specified too.\n'
+ printf ' -D, --disable-dc\n'
+ printf ' Disable dc. It is an error if "-d", "--dc-only", "-B", or "--disable-bc"\n'
+ printf ' are specified too.\n'
+ printf ' -E, --disable-extra-math\n'
+ printf ' Disable extra math. This includes: "$" operator (truncate to integer),\n'
+ printf ' "@" operator (set number of decimal places), and r(x, p) (rounding\n'
+ printf ' function). Additionally, this option disables the extra printing\n'
+ printf ' functions in the math library.\n'
+ printf ' -f, --force\n'
+ printf ' Force use of all enabled options, even if they do not work. This\n'
+ printf ' option is to allow the maintainer a way to test that certain options\n'
+ printf ' are not failing invisibly. (Development only.)'
+ printf ' -g, --debug\n'
+ printf ' Build in debug mode. Adds the "-g" flag, and if there are no\n'
+ printf ' other CFLAGS, and "-O" was not given, this also adds the "-O0"\n'
+ printf ' flag. If this flag is *not* given, "-DNDEBUG" is added to CPPFLAGS\n'
+ printf ' and a strip flag is added to the link stage.\n'
+ printf ' -G, --disable-generated-tests\n'
+ printf ' Disable generating tests. This is for platforms that do not have a\n'
+ printf ' GNU bc-compatible bc to generate tests.\n'
+ printf ' -h, --help\n'
+ printf ' Print this help message and exit.\n'
+ printf ' -H, --disable-history\n'
+ printf ' Disable history.\n'
+ printf ' -k KARATSUBA_LEN, --karatsuba-len KARATSUBA_LEN\n'
+ printf ' Set the karatsuba length to KARATSUBA_LEN (default is 64).\n'
+ printf ' It is an error if KARATSUBA_LEN is not a number or is less than 16.\n'
+ printf ' -l, --install-all-locales\n'
+ printf ' Installs all locales, regardless of how many are on the system. This\n'
+ printf ' option is useful for package maintainers who want to make sure that\n'
+ printf ' a package contains all of the locales that end users might need.\n'
+ printf ' -m, --enable-memcheck\n'
+ printf ' Enable memcheck mode, to ensure no memory leaks. For development only.\n'
+ printf ' -M, --disable-man-pages\n'
+ printf ' Disable installing manpages.\n'
+ printf ' -N, --disable-nls\n'
+ printf ' Disable POSIX locale (NLS) support.\n'
+ printf ' -O OPT_LEVEL, --opt OPT_LEVEL\n'
+ printf ' Set the optimization level. This can also be included in the CFLAGS,\n'
+ printf ' but it is provided, so maintainers can build optimized debug builds.\n'
+ printf ' This is passed through to the compiler, so it must be supported.\n'
+ printf ' -s SETTING, --set-default-on SETTING\n'
+ printf ' Set the default named by SETTING to on. See below for possible values\n'
+ printf ' for SETTING. For multiple instances of the -s or -S for the the same\n'
+ printf ' setting, the last one is used.\n'
+ printf ' -S SETTING, --set-default-off SETTING\n'
+ printf ' Set the default named by SETTING to off. See below for possible values\n'
+ printf ' for SETTING. For multiple instances of the -s or -S for the the same\n'
+ printf ' setting, the last one is used.\n'
+ printf ' -t, --enable-test-timing\n'
+ printf ' Enable the timing of tests. This is for development only.\n'
+ printf ' -T, --disable-strip\n'
+ printf ' Disable stripping symbols from the compiled binary or binaries.\n'
+ printf ' Stripping symbols only happens when debug mode is off.\n'
+ printf ' -v, --enable-valgrind\n'
+ printf ' Enable a build appropriate for valgrind. For development only.\n'
+ printf ' -z, --enable-fuzz-mode\n'
+ printf ' Enable fuzzing mode. THIS IS FOR DEVELOPMENT ONLY.\n'
+ printf ' --prefix PREFIX\n'
+ printf ' The prefix to install to. Overrides "$PREFIX" if it exists.\n'
+ printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n'
+ printf ' Default is "/usr/local".\n'
+ printf ' --bindir BINDIR\n'
+ printf ' The directory to install binaries in. Overrides "$BINDIR" if it exists.\n'
+ printf ' Default is "$PREFIX/bin".\n'
+ printf ' --includedir INCLUDEDIR\n'
+ printf ' The directory to install headers in. Overrides "$INCLUDEDIR" if it\n'
+ printf ' exists. Default is "$PREFIX/include".\n'
+ printf ' --libdir LIBDIR\n'
+ printf ' The directory to install libraries in. Overrides "$LIBDIR" if it exists.\n'
+ printf ' Default is "$PREFIX/lib".\n'
+ printf ' --datarootdir DATAROOTDIR\n'
+ printf ' The root location for data files. Overrides "$DATAROOTDIR" if it exists.\n'
+ printf ' Default is "$PREFIX/share".\n'
+ printf ' --datadir DATADIR\n'
+ printf ' The location for data files. Overrides "$DATADIR" if it exists.\n'
+ printf ' Default is "$DATAROOTDIR".\n'
+ printf ' --mandir MANDIR\n'
+ printf ' The location to install manpages to. Overrides "$MANDIR" if it exists.\n'
+ printf ' Default is "$DATADIR/man".\n'
+ printf ' --man1dir MAN1DIR\n'
+ printf ' The location to install Section 1 manpages to. Overrides "$MAN1DIR" if\n'
+ printf ' it exists. Default is "$MANDIR/man1".\n'
+ printf ' --man3dir MAN3DIR\n'
+ printf ' The location to install Section 3 manpages to. Overrides "$MAN3DIR" if\n'
+ printf ' it exists. Default is "$MANDIR/man3".\n'
+ printf '\n'
+ printf 'In addition, the following environment variables are used:\n'
+ printf '\n'
+ printf ' CC C compiler. Must be compatible with POSIX c99. If there is a\n'
+ printf ' space in the basename of the compiler, the items after the\n'
+ printf ' first space are assumed to be compiler flags, and in that case,\n'
+ printf ' the flags are automatically moved into CFLAGS. Default is\n'
+ printf ' "c99".\n'
+ printf ' HOSTCC Host C compiler. Must be compatible with POSIX c99. If there is\n'
+ printf ' a space in the basename of the compiler, the items after the\n'
+ printf ' first space are assumed to be compiler flags, and in the case,\n'
+ printf ' the flags are automatically moved into HOSTCFLAGS. Default is\n'
+ printf ' "$CC".\n'
+ printf ' HOST_CC Same as HOSTCC. If HOSTCC also exists, it is used.\n'
+ printf ' CFLAGS C compiler flags.\n'
+ printf ' HOSTCFLAGS CFLAGS for HOSTCC. Default is "$CFLAGS".\n'
+ printf ' HOST_CFLAGS Same as HOST_CFLAGS. If HOST_CFLAGS also exists, it is used.\n'
+ printf ' CPPFLAGS C preprocessor flags. Default is "".\n'
+ printf ' LDFLAGS Linker flags. Default is "".\n'
+ printf ' PREFIX The prefix to install to. Default is "/usr/local".\n'
+ printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n'
+ printf ' BINDIR The directory to install binaries in. Default is "$PREFIX/bin".\n'
+ printf ' INCLUDEDIR The directory to install header files in. Default is\n'
+ printf ' "$PREFIX/include".\n'
+ printf ' LIBDIR The directory to install libraries in. Default is\n'
+ printf ' "$PREFIX/lib".\n'
+ printf ' DATAROOTDIR The root location for data files. Default is "$PREFIX/share".\n'
+ printf ' DATADIR The location for data files. Default is "$DATAROOTDIR".\n'
+ printf ' MANDIR The location to install manpages to. Default is "$DATADIR/man".\n'
+ printf ' MAN1DIR The location to install Section 1 manpages to. Default is\n'
+ printf ' "$MANDIR/man1".\n'
+ printf ' MAN3DIR The location to install Section 3 manpages to. Default is\n'
+ printf ' "$MANDIR/man3".\n'
+ printf ' NLSPATH The location to install locale catalogs to. Must be an absolute\n'
+ printf ' path (or contain one). This is treated the same as the POSIX\n'
+ printf ' definition of $NLSPATH (see POSIX environment variables for\n'
+ printf ' more information). Default is "/usr/share/locale/%%L/%%N".\n'
+ printf ' EXECSUFFIX The suffix to append to the executable names, used to not\n'
+ printf ' interfere with other installed bc executables. Default is "".\n'
+ printf ' EXECPREFIX The prefix to append to the executable names, used to not\n'
+ printf ' interfere with other installed bc executables. Default is "".\n'
+ printf ' DESTDIR For package creation. Default is "". If it is empty when\n'
+ printf ' `%s` is run, it can also be passed to `make install`\n' "$script"
+ printf ' later as an environment variable. If both are specified,\n'
+ printf ' the one given to `%s` takes precedence.\n' "$script"
+ printf ' LONG_BIT The number of bits in a C `long` type. This is mostly for the\n'
+ printf ' embedded space since this `bc` uses `long`s internally for\n'
+ printf ' overflow checking. In C99, a `long` is required to be 32 bits.\n'
+ printf ' For most normal desktop systems, setting this is unnecessary,\n'
+ printf ' except that 32-bit platforms with 64-bit longs may want to set\n'
+ printf ' it to `32`. Default is the default of `LONG_BIT` for the target\n'
+ printf ' platform. Minimum allowed is `32`. It is a build time error if\n'
+ printf ' the specified value of `LONG_BIT` is greater than the default\n'
+ printf ' value of `LONG_BIT` for the target platform.\n'
+ printf ' GEN_HOST Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to\n'
+ printf ' produce the C files that contain the help texts as well as the\n'
+ printf ' math libraries. By default, `gen/strgen.c` is used, compiled by\n'
+ printf ' "$HOSTCC" and run on the host machine. Using `gen/strgen.sh`\n'
+ printf ' removes the need to compile and run an executable on the host\n'
+ printf ' machine since `gen/strgen.sh` is a POSIX shell script. However,\n'
+ printf ' `gen/lib2.bc` is perilously close to 4095 characters, the max\n'
+ printf ' supported length of a string literal in C99 (and it could be\n'
+ printf ' added to in the future), and `gen/strgen.sh` generates a string\n'
+ printf ' literal instead of an array, as `gen/strgen.c` does. For most\n'
+ printf ' production-ready compilers, this limit probably is not\n'
+ printf ' enforced, but it could be. Both options are still available for\n'
+ printf ' this reason. If you are sure your compiler does not have the\n'
+ printf ' limit and do not want to compile and run a binary on the host\n'
+ printf ' machine, set this variable to "0". Any other value, or a\n'
+ printf ' non-existent value, will cause the build system to compile and\n'
+ printf ' run `gen/strgen.c`. Default is "".\n'
+ printf ' GEN_EMU Emulator to run string generator code under (leave empty if not\n'
+ printf ' necessary). This is not necessary when using `gen/strgen.sh`.\n'
+ printf ' Default is "".\n'
+ printf '\n'
+ printf 'WARNING: even though `configure.sh` supports both option types, short and\n'
+ printf 'long, it does not support handling both at the same time. Use only one type.\n'
+ printf '\n'
+ printf 'Settings\n'
+ printf '========\n'
+ printf '\n'
+ printf 'bc and dc have some settings that, while they cannot be removed by build time\n'
+ printf 'options, can have their defaults changed at build time by packagers. Users are\n'
+ printf 'also able to change each setting with environment variables.\n'
+ printf '\n'
+ printf 'The following is a table of settings, along with their default values and the\n'
+ printf 'environment variables users can use to change them. (For the defaults, non-zero\n'
+ printf 'means on, and zero means off.)\n'
+ printf '\n'
+ printf '| Setting | Description | Default | Env Variable |\n'
+ printf '| =============== | ==================== | ============ | ==================== |\n'
+ printf '| bc.banner | Whether to display | 0 | BC_BANNER |\n'
+ printf '| | the bc version | | |\n'
+ printf '| | banner when in | | |\n'
+ printf '| | interactive mode. | | |\n'
+ printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
+ printf '| bc.sigint_reset | Whether SIGINT will | 1 | BC_SIGINT_RESET |\n'
+ printf '| | reset bc, instead of | | |\n'
+ printf '| | exiting, when in | | |\n'
+ printf '| | interactive mode. | | |\n'
+ printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
+ printf '| dc.sigint_reset | Whether SIGINT will | 1 | DC_SIGINT_RESET |\n'
+ printf '| | reset dc, instead of | | |\n'
+ printf '| | exiting, when in | | |\n'
+ printf '| | interactive mode. | | |\n'
+ printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
+ printf '| bc.tty_mode | Whether TTY mode for | 1 | BC_TTY_MODE |\n'
+ printf '| | bc should be on when | | |\n'
+ printf '| | available. | | |\n'
+ printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
+ printf '| dc.tty_mode | Whether TTY mode for | 0 | BC_TTY_MODE |\n'
+ printf '| | dc should be on when | | |\n'
+ printf '| | available. | | |\n'
+ printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
+ printf '| bc.prompt | Whether the prompt | $BC_TTY_MODE | BC_PROMPT |\n'
+ printf '| | for bc should be on | | |\n'
+ printf '| | in tty mode. | | |\n'
+ printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
+ printf '| dc.prompt | Whether the prompt | $DC_TTY_MODE | DC_PROMPT |\n'
+ printf '| | for dc should be on | | |\n'
+ printf '| | in tty mode. | | |\n'
+ printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
+ printf '\n'
+ printf 'These settings are not meant to be changed on a whim. They are meant to ensure\n'
+ printf 'that this bc and dc will conform to the expectations of the user on each\n'
+ printf 'platform.\n'
+
+ exit "$_usage_val"
+}
+
+# Replaces a file extension in a filename. This is used mostly to turn filenames
+# like `src/num.c` into `src/num.o`. In other words, it helps to link targets to
+# the files they depend on.
+#
+# @param file The filename.
+# @param ext1 The extension to replace.
+# @param ext2 The new extension.
+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"
+}
+
+# Replaces a file extension in every filename given in a list. The list is just
+# a space-separated list of words, so filenames are expected to *not* have
+# spaces in them. See the documentation for `replace_ext()`.
+#
+# @param files The list of space-separated filenames to replace extensions for.
+# @param ext1 The extension to replace.
+# @param ext2 The new extension.
+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"
+}
+
+# Finds a placeholder in @a str and replaces it. This is the workhorse of
+# configure.sh. It's what replaces placeholders in Makefile.in with the data
+# needed for the chosen build. Below, you will see a lot of calls to this
+# function.
+#
+# Note that needle can never contain an exclamation point. For more information,
+# see substring_replace() in scripts/functions.sh.
+#
+# @param str The string to find and replace placeholders in.
+# @param needle The placeholder name.
+# @param replacement The string to use to replace the placeholder.
+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"
+}
+
+# This function finds all the source files that need to be built. If there is
+# only one argument and it is empty, then all source files are built. Otherwise,
+# the arguments are all assumed to be source files that should *not* be built.
+find_src_files() {
+
+ if [ "$#" -ge 1 ] && [ "$1" != "" ]; then
+
+ while [ "$#" -ge 1 ]; do
+ _find_src_files_a="${1## }"
+ shift
+ _find_src_files_args="$_find_src_files_args ! -path src/${_find_src_files_a}"
+ done
+
+ else
+ _find_src_files_args="-print"
+ fi
+
+ printf '%s\n' $(find src/ -depth -name "*.c" $_find_src_files_args)
+}
+
+# This function generates a list of files to go into the Makefile. It generates
+# the list of object files, as well as the list of test coverage files.
+#
+# @param contents The contents of the Makefile template to put the list of
+# files into.
+gen_file_list() {
+
+ if [ "$#" -lt 1 ]; then
+ err_exit "Invalid number of args to $0"
+ fi
+
+ _gen_file_list_contents="$1"
+ shift
+
+ p=$(pwd)
+
+ cd "$scriptdir"
+
+ if [ "$#" -ge 1 ]; then
+ _gen_file_list_unneeded="$@"
+ else
+ _gen_file_list_unneeded=""
+ fi
+
+ _gen_file_list_needle_src="SRC"
+ _gen_file_list_needle_obj="OBJ"
+ _gen_file_list_needle_gcda="GCDA"
+ _gen_file_list_needle_gcno="GCNO"
+
+ _gen_file_list_replacement=$(find_src_files $_gen_file_list_unneeded | tr '\n' ' ')
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_src" "$_gen_file_list_replacement")
+
+ _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "c" "o")
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_obj" "$_gen_file_list_replacement")
+
+ _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "o" "gcda")
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_gcda" "$_gen_file_list_replacement")
+
+ _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "gcda" "gcno")
+ _gen_file_list_contents=$(replace "$_gen_file_list_contents" \
+ "$_gen_file_list_needle_gcno" "$_gen_file_list_replacement")
+
+ cd "$p"
+
+ printf '%s\n' "$_gen_file_list_contents"
+}
+
+# Generates the proper test targets for each test to have its own target. This
+# allows `make test` to run in parallel.
+#
+# @param name Which calculator to generate tests for.
+# @param extra_math An integer that, if non-zero, activates extra math tests.
+# @param time_tests An integer that, if non-zero, tells the test suite to time
+# the execution of each test.
+gen_std_tests() {
+
+ _gen_std_tests_name="$1"
+ shift
+
+ _gen_std_tests_extra_math="$1"
+ shift
+
+ _gen_std_tests_time_tests="$1"
+ shift
+
+ _gen_std_tests_extra_required=$(cat "$scriptdir/tests/extra_required.txt")
+
+ for _gen_std_tests_t in $(cat "$scriptdir/tests/$_gen_std_tests_name/all.txt"); do
+
+ if [ "$_gen_std_tests_extra_math" -eq 0 ]; then
+
+ if [ -z "${_gen_std_tests_extra_required##*$_gen_std_tests_t*}" ]; then
+ printf 'test_%s_%s:\n\t@printf "Skipping %s %s\\n"\n\n' \
+ "$_gen_std_tests_name" "$_gen_std_tests_t" "$_gen_std_tests_name" \
+ "$_gen_std_tests_t" >> "$scriptdir/Makefile"
+ continue
+ fi
+
+ fi
+
+ printf 'test_%s_%s:\n\t@sh tests/test.sh %s %s %s %s %s\n\n' \
+ "$_gen_std_tests_name" "$_gen_std_tests_t" "$_gen_std_tests_name" \
+ "$_gen_std_tests_t" "$generate_tests" "$time_tests" \
+ "$*" >> "$scriptdir/Makefile"
+
+ done
+}
+
+# Generates a list of test targets that will be used as prerequisites for other
+# targets.
+#
+# @param name The name of the calculator to generate test targets for.
+gen_std_test_targets() {
+
+ _gen_std_test_targets_name="$1"
+ shift
+
+ _gen_std_test_targets_tests=$(cat "$scriptdir/tests/${_gen_std_test_targets_name}/all.txt")
+
+ for _gen_std_test_targets_t in $_gen_std_test_targets_tests; do
+ printf ' test_%s_%s' "$_gen_std_test_targets_name" "$_gen_std_test_targets_t"
+ done
+
+ printf '\n'
+}
+
+# Generates the proper test targets for each error test to have its own target.
+# This allows `make test_bc_errors` and `make test_dc_errors` to run in
+# parallel.
+#
+# @param name Which calculator to generate tests for.
+gen_err_tests() {
+
+ _gen_err_tests_name="$1"
+ shift
+
+ _gen_err_tests_fs=$(ls "$scriptdir/tests/$_gen_err_tests_name/errors/")
+
+ for _gen_err_tests_t in $_gen_err_tests_fs; do
+
+ printf 'test_%s_error_%s:\n\t@sh tests/error.sh %s %s %s\n\n' \
+ "$_gen_err_tests_name" "$_gen_err_tests_t" "$_gen_err_tests_name" \
+ "$_gen_err_tests_t" "$*" >> "$scriptdir/Makefile"
+
+ done
+
+}
+
+# Generates a list of error test targets that will be used as prerequisites for
+# other targets.
+#
+# @param name The name of the calculator to generate test targets for.
+gen_err_test_targets() {
+
+ _gen_err_test_targets_name="$1"
+ shift
+
+ _gen_err_test_targets_tests=$(ls "$scriptdir/tests/$_gen_err_test_targets_name/errors/")
+
+ for _gen_err_test_targets_t in $_gen_err_test_targets_tests; do
+ printf ' test_%s_error_%s' "$_gen_err_test_targets_name" "$_gen_err_test_targets_t"
+ done
+
+ printf '\n'
+}
+
+# Generates the proper script test targets for each script test to have its own
+# target. This allows `make test` to run in parallel.
+#
+# @param name Which calculator to generate tests for.
+# @param extra_math An integer that, if non-zero, activates extra math tests.
+# @param generate An integer that, if non-zero, activates generated tests.
+# @param time_tests An integer that, if non-zero, tells the test suite to time
+# the execution of each test.
+gen_script_tests() {
+
+ _gen_script_tests_name="$1"
+ shift
+
+ _gen_script_tests_extra_math="$1"
+ shift
+
+ _gen_script_tests_generate="$1"
+ shift
+
+ _gen_script_tests_time="$1"
+ shift
+
+ _gen_script_tests_tests=$(cat "$scriptdir/tests/$_gen_script_tests_name/scripts/all.txt")
+
+ for _gen_script_tests_f in $_gen_script_tests_tests; do
+
+ _gen_script_tests_b=$(basename "$_gen_script_tests_f" ".${_gen_script_tests_name}")
+
+ printf 'test_%s_script_%s:\n\t@sh tests/script.sh %s %s %s 1 %s %s %s\n\n' \
+ "$_gen_script_tests_name" "$_gen_script_tests_b" "$_gen_script_tests_name" \
+ "$_gen_script_tests_f" "$_gen_script_tests_extra_math" "$_gen_script_tests_generate" \
+ "$_gen_script_tests_time" "$*" >> "$scriptdir/Makefile"
+ done
+}
+
+set_default() {
+
+ _set_default_on="$1"
+ shift
+
+ _set_default_name="$1"
+ shift
+
+ # The reason that the variables that are being set do not have the same
+ # non-collision avoidance that the other variables do is that we *do* want
+ # the settings of these variables to leak out of the function. They adjust
+ # the settings outside of the function.
+ case "$_set_default_name" in
+
+ bc.banner) bc_default_banner="$_set_default_on" ;;
+ bc.sigint_reset) bc_default_sigint_reset="$_set_default_on" ;;
+ dc.sigint_reset) dc_default_sigint_reset="$_set_default_on" ;;
+ bc.tty_mode) bc_default_tty_mode="$_set_default_on" ;;
+ dc.tty_mode) dc_default_tty_mode="$_set_default_on" ;;
+ bc.prompt) bc_default_prompt="$_set_default_on" ;;
+ dc.prompt) dc_default_prompt="$_set_default_on" ;;
+ ?) usage "Invalid setting: $_set_default_name" ;;
+
+ esac
+}
+
+# Generates a list of script test targets that will be used as prerequisites for
+# other targets.
+#
+# @param name The name of the calculator to generate script test targets for.
+gen_script_test_targets() {
+
+ _gen_script_test_targets_name="$1"
+ shift
+
+ _gen_script_test_targets_tests=$(cat "$scriptdir/tests/$_gen_script_test_targets_name/scripts/all.txt")
+
+ for _gen_script_test_targets_f in $_gen_script_test_targets_tests; do
+ _gen_script_test_targets_b=$(basename "$_gen_script_test_targets_f" \
+ ".$_gen_script_test_targets_name")
+ printf ' test_%s_script_%s' "$_gen_script_test_targets_name" \
+ "$_gen_script_test_targets_b"
+ done
+
+ printf '\n'
+}
+
+# This is a list of defaults, but it is also the list of possible options for
+# users to change.
+#
+# The development options are: force (force options even if they fail), valgrind
+# (build in a way suitable for valgrind testing), memcheck (same as valgrind),
+# and fuzzing (build in a way suitable for fuzzing).
+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
+force=0
+strip_bin=1
+all_locales=0
+library=0
+fuzz=0
+time_tests=0
+vg=0
+memcheck=0
+clean=1
+
+# The empty strings are because they depend on TTY mode. If they are directly
+# set, though, they will be integers. We test for empty strings later.
+bc_default_banner=0
+bc_default_sigint_reset=1
+dc_default_sigint_reset=1
+bc_default_tty_mode=1
+dc_default_tty_mode=0
+bc_default_prompt=""
+dc_default_prompt=""
+
+# getopts is a POSIX utility, but it cannot handle long options. Thus, the
+# handling of long options is done by hand, and that's the reason that short and
+# long options cannot be mixed.
+while getopts "abBcdDEfgGhHk:lMmNO:S:s:tTvz-" opt; do
+
+ case "$opt" in
+ a) library=1 ;;
+ b) bc_only=1 ;;
+ B) dc_only=1 ;;
+ c) coverage=1 ;;
+ C) clean=0 ;;
+ d) dc_only=1 ;;
+ D) bc_only=1 ;;
+ E) extra_math=0 ;;
+ f) force=1 ;;
+ g) debug=1 ;;
+ G) generate_tests=0 ;;
+ h) usage ;;
+ H) hist=0 ;;
+ k) karatsuba_len="$OPTARG" ;;
+ l) all_locales=1 ;;
+ m) memcheck=1 ;;
+ M) install_manpages=0 ;;
+ N) nls=0 ;;
+ O) optimization="$OPTARG" ;;
+ S) set_default 0 "$OPTARG" ;;
+ s) set_default 1 "$OPTARG" ;;
+ t) time_tests=1 ;;
+ T) strip_bin=0 ;;
+ v) vg=1 ;;
+ z) fuzz=1 ;;
+ -)
+ arg="$1"
+ arg="${arg#--}"
+ LONG_OPTARG="${arg#*=}"
+ case $arg in
+ help) usage ;;
+ library) library=1 ;;
+ bc-only) bc_only=1 ;;
+ dc-only) dc_only=1 ;;
+ coverage) coverage=1 ;;
+ debug) debug=1 ;;
+ force) force=1 ;;
+ prefix=?*) PREFIX="$LONG_OPTARG" ;;
+ prefix)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ PREFIX="$2"
+ shift ;;
+ bindir=?*) BINDIR="$LONG_OPTARG" ;;
+ bindir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ BINDIR="$2"
+ shift ;;
+ includedir=?*) INCLUDEDIR="$LONG_OPTARG" ;;
+ includedir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ INCLUDEDIR="$2"
+ shift ;;
+ libdir=?*) LIBDIR="$LONG_OPTARG" ;;
+ libdir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ LIBDIR="$2"
+ shift ;;
+ datarootdir=?*) DATAROOTDIR="$LONG_OPTARG" ;;
+ datarootdir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ DATAROOTDIR="$2"
+ shift ;;
+ datadir=?*) DATADIR="$LONG_OPTARG" ;;
+ datadir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ DATADIR="$2"
+ shift ;;
+ mandir=?*) MANDIR="$LONG_OPTARG" ;;
+ mandir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ MANDIR="$2"
+ shift ;;
+ man1dir=?*) MAN1DIR="$LONG_OPTARG" ;;
+ man1dir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ MAN1DIR="$2"
+ shift ;;
+ man3dir=?*) MAN3DIR="$LONG_OPTARG" ;;
+ man3dir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ MAN3DIR="$2"
+ shift ;;
+ localedir=?*) LOCALEDIR="$LONG_OPTARG" ;;
+ localedir)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ LOCALEDIR="$2"
+ shift ;;
+ karatsuba-len=?*) karatsuba_len="$LONG_OPTARG" ;;
+ karatsuba-len)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ karatsuba_len="$1"
+ shift ;;
+ opt=?*) optimization="$LONG_OPTARG" ;;
+ opt)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ optimization="$1"
+ shift ;;
+ set-default-on=?*) set_default 1 "$LONG_OPTARG" ;;
+ set-default-on)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ set_default 1 "$1"
+ shift ;;
+ set-default-off=?*) set_default 0 "$LONG_OPTARG" ;;
+ set-default-off)
+ if [ "$#" -lt 2 ]; then
+ usage "No argument given for '--$arg' option"
+ fi
+ set_default 0 "$1"
+ shift ;;
+ disable-bc) dc_only=1 ;;
+ disable-dc) bc_only=1 ;;
+ disable-clean) clean=0 ;;
+ disable-extra-math) extra_math=0 ;;
+ disable-generated-tests) generate_tests=0 ;;
+ disable-history) hist=0 ;;
+ disable-man-pages) install_manpages=0 ;;
+ disable-nls) nls=0 ;;
+ disable-strip) strip_bin=0 ;;
+ enable-test-timing) time_tests=1 ;;
+ enable-valgrind) vg=1 ;;
+ enable-fuzz-mode) fuzz=1 ;;
+ enable-memcheck) memcheck=1 ;;
+ install-all-locales) all_locales=1 ;;
+ help* | bc-only* | dc-only* | coverage* | debug*)
+ usage "No arg allowed for --$arg option" ;;
+ disable-bc* | disable-dc* | disable-clean*)
+ usage "No arg allowed for --$arg option" ;;
+ disable-extra-math*)
+ usage "No arg allowed for --$arg option" ;;
+ disable-generated-tests* | disable-history*)
+ usage "No arg allowed for --$arg option" ;;
+ disable-man-pages* | disable-nls* | disable-strip*)
+ usage "No arg allowed for --$arg option" ;;
+ enable-fuzz-mode* | enable-test-timing* | enable-valgrind*)
+ usage "No arg allowed for --$arg option" ;;
+ enable-memcheck* | install-all-locales*)
+ usage "No arg allowed for --$arg option" ;;
+ '') break ;; # "--" terminates argument processing
+ * ) usage "Invalid option $LONG_OPTARG" ;;
+ esac
+ shift
+ OPTIND=1 ;;
+ ?) usage "Invalid option: $opt" ;;
+ esac
+
+done
+
+# Sometimes, developers don't want configure.sh to do a config clean. But
+# sometimes they do.
+if [ "$clean" -ne 0 ]; then
+ if [ -f ./Makefile ]; then
+ make clean_config > /dev/null
+ fi
+fi
+
+# It is an error to say that bc only should be built and likewise for dc.
+if [ "$bc_only" -eq 1 ] && [ "$dc_only" -eq 1 ]; then
+ usage "Can only specify one of -b(-D) or -d(-B)"
+fi
+
+# The library is mutually exclusive to the calculators, so it's an error to
+# give an option for either of them.
+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
+
+# KARATSUBA_LEN must be an integer and must be 16 or greater.
+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
+
+ # I had users complain that, if they gave CFLAGS as part of CC, which
+ # autotools allows in its braindead way, the build would fail with an error.
+ # I don't like adjusting for autotools, but oh well. These lines puts the
+ # stuff after the first space into CFLAGS.
+ 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
+
+ # Like above, this splits HOSTCC and HOSTCFLAGS.
+ 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
+
+# Store these for the cross compilation detection later.
+OLDCFLAGS="$CFLAGS"
+OLDHOSTCFLAGS="$HOSTCFLAGS"
+
+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 $time_tests \$(BC_EXEC)"
+bc_test_np="@tests/all.sh -n bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)"
+dc_test="@tests/all.sh dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
+dc_test_np="@tests/all.sh -n dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
+
+timeconst="@tests/bc/timeconst.sh tests/bc/scripts/timeconst.bc \$(BC_EXEC)"
+
+# In order to have cleanup at exit, we need to be in
+# debug mode, so don't run valgrind without that.
+if [ "$vg" -ne 0 ]; then
+ debug=1
+ bc_test_exec='valgrind $(VALGRIND_ARGS) $(BC_EXEC)'
+ dc_test_exec='valgrind $(VALGRIND_ARGS) $(DC_EXEC)'
+else
+ bc_test_exec='$(BC_EXEC)'
+ dc_test_exec='$(DC_EXEC)'
+fi
+
+test_bc_history_prereqs="test_bc_history_all"
+test_dc_history_prereqs="test_dc_history_all"
+
+karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
+karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
+
+bc_lib="\$(GEN_DIR)/lib.o"
+bc_help="\$(GEN_DIR)/bc_help.o"
+dc_help="\$(GEN_DIR)/dc_help.o"
+
+default_target_prereqs="\$(BIN) \$(OBJS)"
+default_target_cmd="\$(CC) \$(CFLAGS) \$(OBJS) \$(LDFLAGS) -o \$(EXEC)"
+default_target="\$(DC_EXEC)"
+
+second_target_prereqs=""
+second_target_cmd="$default_target_cmd"
+second_target="\$(BC_EXEC)"
+
+# This if/else if chain is for setting the defaults that change based on whether
+# the library is being built, bc only, dc only, or both calculators.
+if [ "$library" -ne 0 ]; then
+
+ extra_math=1
+ nls=0
+ hist=0
+ bc=1
+ dc=1
+
+ default_target_prereqs="\$(BIN) \$(OBJ)"
+ default_target_cmd="ar -r -cu \$(LIBBC) \$(OBJ)"
+ default_target="\$(LIBBC)"
+ tests="test_library"
+ test_bc_history_prereqs=" test_bc_history_skip"
+ test_dc_history_prereqs=" test_dc_history_skip"
+
+elif [ "$bc_only" -eq 1 ]; then
+
+ bc=1
+ dc=0
+
+ dc_help=""
+
+ executables="bc"
+
+ dc_test="@printf 'No dc tests to run\\\\n'"
+ dc_test_np="@printf 'No dc tests to run\\\\n'"
+ test_dc_history_prereqs=" test_dc_history_skip"
+
+ install_prereqs=" install_execs"
+ install_man_prereqs=" install_bc_manpage"
+ uninstall_prereqs=" uninstall_bc"
+ uninstall_man_prereqs=" uninstall_bc_manpage"
+
+ default_target="\$(BC_EXEC)"
+ second_target="\$(DC_EXEC)"
+ tests="test_bc timeconst"
+
+elif [ "$dc_only" -eq 1 ]; then
+
+ bc=0
+ dc=1
+
+ bc_lib=""
+ bc_help=""
+
+ executables="dc"
+
+ main_exec="DC"
+ executable="DC_EXEC"
+
+ bc_test="@printf 'No bc tests to run\\\\n'"
+ bc_test_np="@printf 'No bc tests to run\\\\n'"
+ test_bc_history_prereqs=" test_bc_history_skip"
+
+ timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'"
+
+ install_prereqs=" install_execs"
+ install_man_prereqs=" install_dc_manpage"
+ uninstall_prereqs=" uninstall_dc"
+ uninstall_man_prereqs=" uninstall_dc_manpage"
+
+ tests="test_dc"
+
+else
+
+ bc=1
+ dc=1
+
+ executables="bc and dc"
+
+ karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)"
+ karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)"
+
+ if [ "$library" -eq 0 ]; then
+ install_prereqs=" install_execs"
+ install_man_prereqs=" install_bc_manpage install_dc_manpage"
+ uninstall_prereqs=" uninstall_bc uninstall_dc"
+ uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
+ else
+ install_prereqs=" install_library install_bcl_header"
+ install_man_prereqs=" install_bcl_manpage"
+ uninstall_prereqs=" uninstall_library uninstall_bcl_header"
+ uninstall_man_prereqs=" uninstall_bcl_manpage"
+ tests="test_library"
+ fi
+
+ second_target_prereqs="$default_target_prereqs"
+ default_target_prereqs="$second_target"
+ default_target_cmd="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)"
+
+fi
+
+# We need specific stuff for fuzzing.
+if [ "$fuzz" -ne 0 ]; then
+ debug=1
+ hist=0
+ nls=0
+ optimization="3"
+fi
+
+# This sets some necessary things for debug mode.
+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
+
+# Set optimization CFLAGS.
+if [ -n "$optimization" ]; then
+ CFLAGS="-O$optimization $CFLAGS"
+fi
+
+# Set test coverage defaults.
+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 --exclude-unreachable-branches --exclude-throw-branches --html-details --output index.html"
+ COVERAGE_PREREQS=" test coverage_output"
+
+else
+ COVERAGE_OUTPUT="@printf 'Coverage not generated\\\\n'"
+ COVERAGE_PREREQS=""
+fi
+
+
+# Set some defaults.
+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
+
+# Set a default for the DATAROOTDIR. This is done if either manpages will be
+# installed, or locales are enabled because that's probably where NLS_PATH
+# points.
+if [ "$install_manpages" -ne 0 ] || [ "$nls" -ne 0 ]; then
+ if [ -z "${DATAROOTDIR+set}" ]; then
+ DATAROOTDIR="$PREFIX/share"
+ fi
+fi
+
+# Set defaults for manpage environment variables.
+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
+
+# Here is where we test NLS (the locale system). This is done by trying to
+# compile src/vm.c, which has the relevant code. If it fails, then it is
+# disabled.
+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 -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=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/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'
+
+ # It turns out that POSIX locales are really terrible, and running
+ # gencat on one machine is not guaranteed to make those cat files
+ # portable to another machine, so we had better warn the user here.
+ if [ "$HOSTCC" != "$CC" ] || [ "$OLDHOSTCFLAGS" != "$OLDCFLAGS" ]; 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
+
+# Like the above tested locale support, this tests history.
+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 -DBC_ENABLE_AFL=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
+
+# We have to disable the history tests if it is disabled or valgrind is on.
+if [ "$hist" -eq 0 ] || [ "$vg" -ne 0 ]; then
+ test_bc_history_prereqs=" test_bc_history_skip"
+ test_dc_history_prereqs=" test_dc_history_skip"
+ history_tests="@printf 'Skipping history tests...\\\\n'"
+else
+ history_tests="@printf '\$(TEST_STARS)\\\\n\\\\nRunning history tests...\\\\n\\\\n' \&\& tests/history.sh bc -a \&\& tests/history.sh dc -a \&\& printf '\\\\nAll history tests passed.\\\\n\\\\n\$(TEST_STARS)\\\\n'"
+fi
+
+# Test OpenBSD. This is not in an if statement because regardless of whatever
+# the user says, we need to know if we are on OpenBSD to activate _BSD_SOURCE.
+# No, I cannot `#define _BSD_SOURCE` in a header because OpenBSD's patched GCC
+# and Clang complain that that is only allowed for system headers. Sigh....So we
+# have to check at configure time and set it on the compiler command-line. And
+# we have to set it because we also set _POSIX_C_SOURCE, which OpenBSD headers
+# detect, and when they detect it, they turn off _BSD_SOURCE unless it is
+# specifically requested.
+set +e
+printf 'Testing for OpenBSD...\n'
+
+flags="-DBC_TEST_OPENBSD -DBC_ENABLE_AFL=0"
+"$CC" $CPPFLAGS $CFLAGS $flags -I./include -E "include/status.h" > /dev/null 2>&1
+
+err="$?"
+
+if [ "$err" -ne 0 ]; then
+ printf 'On OpenBSD. Using _BSD_SOURCE.\n\n'
+ bsd="-D_BSD_SOURCE"
+else
+ printf 'Not on OpenBSD.\n\n'
+ bsd=""
+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
+
+# These lines set the appropriate targets based on whether `gen/strgen.c` or
+# `gen/strgen.sh` is used.
+GEN="strgen"
+GEN_EXEC_TARGET="\$(HOSTCC) \$(HOSTCFLAGS) -o \$(GEN_EXEC) \$(GEN_C)"
+CLEAN_PREREQS=" clean_gen clean_coverage"
+
+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=" clean_coverage"
+ fi
+fi
+
+manpage_args=""
+unneeded=""
+headers="\$(HEADERS)"
+
+# This series of if statements figure out what source files are *not* needed.
+if [ "$extra_math" -eq 0 ]; then
+ manpage_args="E"
+ unneeded="$unneeded rand.c"
+else
+ headers="$headers \$(EXTRA_MATH_HEADERS)"
+fi
+
+# All of these next if statements set the build type and mark certain source
+# files as unneeded so that they won't have targets generated for them.
+
+if [ "$hist" -eq 0 ]; then
+ manpage_args="${manpage_args}H"
+ unneeded="$unneeded history.c"
+else
+ headers="$headers \$(HISTORY_HEADERS)"
+fi
+
+if [ "$nls" -eq 0 ]; then
+ manpage_args="${manpage_args}N"
+fi
+
+if [ "$bc" -eq 0 ]; then
+ unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
+else
+ headers="$headers \$(BC_HEADERS)"
+fi
+
+if [ "$dc" -eq 0 ]; then
+ unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
+else
+ headers="$headers \$(DC_HEADERS)"
+fi
+
+if [ "$library" -ne 0 ]; then
+ unneeded="$unneeded args.c opt.c read.c file.c main.c"
+ unneeded="$unneeded lang.c lex.c parse.c program.c"
+ unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
+ unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
+ headers="$headers \$(LIBRARY_HEADERS)"
+else
+ unneeded="$unneeded library.c"
+fi
+
+# library.c is not needed under normal circumstances.
+if [ "$unneeded" = "" ]; then
+ unneeded="library.c"
+fi
+
+# This sets the appropriate manpage for a full build.
+if [ "$manpage_args" = "" ]; then
+ manpage_args="A"
+fi
+
+if [ "$vg" -ne 0 ]; then
+ memcheck=1
+fi
+
+if [ "$bc_default_prompt" = "" ]; then
+ bc_default_prompt="$bc_default_tty_mode"
+fi
+
+if [ "$dc_default_prompt" = "" ]; then
+ dc_default_prompt="$dc_default_tty_mode"
+fi
+
+# Generate the test targets and prerequisites.
+bc_tests=$(gen_std_test_targets bc)
+bc_script_tests=$(gen_script_test_targets bc)
+bc_err_tests=$(gen_err_test_targets bc)
+dc_tests=$(gen_std_test_targets dc)
+dc_script_tests=$(gen_script_test_targets dc)
+dc_err_tests=$(gen_err_test_targets dc)
+
+# Print out the values; this is for debugging.
+if [ "$bc" -ne 0 ]; then
+ printf 'Building bc\n'
+else
+ printf 'Not building bc\n'
+fi
+if [ "$dc" -ne 0 ]; then
+ printf 'Building dc\n'
+else
+ printf 'Not building dc\n'
+fi
+printf '\n'
+printf 'BC_ENABLE_LIBRARY=%s\n\n' "$library"
+printf 'BC_ENABLE_HISTORY=%s\n' "$hist"
+printf 'BC_ENABLE_EXTRA_MATH=%s\n' "$extra_math"
+printf 'BC_ENABLE_NLS=%s\n' "$nls"
+printf 'BC_ENABLE_AFL=%s\n' "$fuzz"
+printf '\n'
+printf 'BC_NUM_KARATSUBA_LEN=%s\n' "$karatsuba_len"
+printf '\n'
+printf 'CC=%s\n' "$CC"
+printf 'CFLAGS=%s\n' "$CFLAGS"
+printf 'HOSTCC=%s\n' "$HOSTCC"
+printf 'HOSTCFLAGS=%s\n' "$HOSTCFLAGS"
+printf 'CPPFLAGS=%s\n' "$CPPFLAGS"
+printf 'LDFLAGS=%s\n' "$LDFLAGS"
+printf 'PREFIX=%s\n' "$PREFIX"
+printf 'BINDIR=%s\n' "$BINDIR"
+printf 'INCLUDEDIR=%s\n' "$INCLUDEDIR"
+printf 'LIBDIR=%s\n' "$LIBDIR"
+printf 'DATAROOTDIR=%s\n' "$DATAROOTDIR"
+printf 'DATADIR=%s\n' "$DATADIR"
+printf 'MANDIR=%s\n' "$MANDIR"
+printf 'MAN1DIR=%s\n' "$MAN1DIR"
+printf 'MAN3DIR=%s\n' "$MAN3DIR"
+printf 'NLSPATH=%s\n' "$NLSPATH"
+printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX"
+printf 'EXECPREFIX=%s\n' "$EXECPREFIX"
+printf 'DESTDIR=%s\n' "$DESTDIR"
+printf 'LONG_BIT=%s\n' "$LONG_BIT"
+printf 'GEN_HOST=%s\n' "$GEN_HOST"
+printf 'GEN_EMU=%s\n' "$GEN_EMU"
+printf '\n'
+printf 'Setting Defaults\n'
+printf '================\n'
+printf 'bc.banner=%s\n' "$bc_default_banner"
+printf 'bc.sigint_reset=%s\n' "$bc_default_sigint_reset"
+printf 'dc.sigint_reset=%s\n' "$dc_default_sigint_reset"
+printf 'bc.tty_mode=%s\n' "$bc_default_tty_mode"
+printf 'dc.tty_mode=%s\n' "$dc_default_tty_mode"
+printf 'bc.prompt=%s\n' "$bc_default_prompt"
+printf 'dc.prompt=%s\n' "$dc_default_prompt"
+
+# This is where the real work begins. This is the point at which the Makefile.in
+# template is edited and output to the Makefile.
+
+contents=$(cat "$scriptdir/Makefile.in")
+
+needle="WARNING"
+replacement='*** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***'
+
+contents=$(replace "$contents" "$needle" "$replacement")
+
+# The contents are edited to have the list of files to build.
+contents=$(gen_file_list "$contents" $unneeded)
+
+SRC_TARGETS=""
+
+# This line and loop generates the individual targets for source files. I used
+# to just use an implicit target, but that was found to be inadequate when I
+# added the library.
+src_files=$(find_src_files $unneeded)
+
+for f in $src_files; do
+ o=$(replace_ext "$f" "c" "o")
+ SRC_TARGETS=$(printf '%s\n\n%s: %s %s\n\t$(CC) $(CFLAGS) -o %s -c %s\n' \
+ "$SRC_TARGETS" "$o" "$headers" "$f" "$o" "$f")
+done
+
+# Replace all the placeholders.
+contents=$(replace "$contents" "HEADERS" "$headers")
+
+contents=$(replace "$contents" "BC_ENABLED" "$bc")
+contents=$(replace "$contents" "DC_ENABLED" "$dc")
+
+contents=$(replace "$contents" "BC_ALL_TESTS" "$bc_test")
+contents=$(replace "$contents" "BC_ALL_TESTS_NP" "$bc_test_np")
+contents=$(replace "$contents" "BC_TESTS" "$bc_tests")
+contents=$(replace "$contents" "BC_SCRIPT_TESTS" "$bc_script_tests")
+contents=$(replace "$contents" "BC_ERROR_TESTS" "$bc_err_tests")
+contents=$(replace "$contents" "BC_TEST_EXEC" "$bc_test_exec")
+contents=$(replace "$contents" "TIMECONST_ALL_TESTS" "$timeconst")
+
+contents=$(replace "$contents" "DC_ALL_TESTS" "$dc_test")
+contents=$(replace "$contents" "DC_ALL_TESTS_NP" "$dc_test_np")
+contents=$(replace "$contents" "DC_TESTS" "$dc_tests")
+contents=$(replace "$contents" "DC_SCRIPT_TESTS" "$dc_script_tests")
+contents=$(replace "$contents" "DC_ERROR_TESTS" "$dc_err_tests")
+contents=$(replace "$contents" "DC_TEST_EXEC" "$dc_test_exec")
+
+contents=$(replace "$contents" "BUILD_TYPE" "$manpage_args")
+
+contents=$(replace "$contents" "LIBRARY" "$library")
+contents=$(replace "$contents" "HISTORY" "$hist")
+contents=$(replace "$contents" "EXTRA_MATH" "$extra_math")
+contents=$(replace "$contents" "NLS" "$nls")
+contents=$(replace "$contents" "FUZZ" "$fuzz")
+contents=$(replace "$contents" "MEMCHECK" "$memcheck")
+
+contents=$(replace "$contents" "BC_LIB_O" "$bc_lib")
+contents=$(replace "$contents" "BC_HELP_O" "$bc_help")
+contents=$(replace "$contents" "DC_HELP_O" "$dc_help")
+contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O")
+contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len")
+
+contents=$(replace "$contents" "NLSPATH" "$NLSPATH")
+contents=$(replace "$contents" "DESTDIR" "$destdir")
+contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX")
+contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX")
+contents=$(replace "$contents" "BINDIR" "$BINDIR")
+contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR")
+contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
+contents=$(replace "$contents" "MAN1DIR" "$MAN1DIR")
+contents=$(replace "$contents" "MAN3DIR" "$MAN3DIR")
+contents=$(replace "$contents" "CFLAGS" "$CFLAGS")
+contents=$(replace "$contents" "HOSTCFLAGS" "$HOSTCFLAGS")
+contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS")
+contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS")
+contents=$(replace "$contents" "CC" "$CC")
+contents=$(replace "$contents" "HOSTCC" "$HOSTCC")
+contents=$(replace "$contents" "COVERAGE_OUTPUT" "$COVERAGE_OUTPUT")
+contents=$(replace "$contents" "COVERAGE_PREREQS" "$COVERAGE_PREREQS")
+contents=$(replace "$contents" "INSTALL_PREREQS" "$install_prereqs")
+contents=$(replace "$contents" "INSTALL_MAN_PREREQS" "$install_man_prereqs")
+contents=$(replace "$contents" "INSTALL_LOCALES" "$install_locales")
+contents=$(replace "$contents" "INSTALL_LOCALES_PREREQS" "$install_locales_prereqs")
+contents=$(replace "$contents" "UNINSTALL_MAN_PREREQS" "$uninstall_man_prereqs")
+contents=$(replace "$contents" "UNINSTALL_PREREQS" "$uninstall_prereqs")
+contents=$(replace "$contents" "UNINSTALL_LOCALES_PREREQS" "$uninstall_locales_prereqs")
+
+contents=$(replace "$contents" "DEFAULT_TARGET" "$default_target")
+contents=$(replace "$contents" "DEFAULT_TARGET_PREREQS" "$default_target_prereqs")
+contents=$(replace "$contents" "DEFAULT_TARGET_CMD" "$default_target_cmd")
+contents=$(replace "$contents" "SECOND_TARGET" "$second_target")
+contents=$(replace "$contents" "SECOND_TARGET_PREREQS" "$second_target_prereqs")
+contents=$(replace "$contents" "SECOND_TARGET_CMD" "$second_target_cmd")
+
+contents=$(replace "$contents" "ALL_PREREQ" "$ALL_PREREQ")
+contents=$(replace "$contents" "BC_EXEC_PREREQ" "$bc_exec_prereq")
+contents=$(replace "$contents" "BC_EXEC_CMD" "$bc_exec_cmd")
+contents=$(replace "$contents" "DC_EXEC_PREREQ" "$dc_exec_prereq")
+contents=$(replace "$contents" "DC_EXEC_CMD" "$dc_exec_cmd")
+
+contents=$(replace "$contents" "EXECUTABLES" "$executables")
+contents=$(replace "$contents" "MAIN_EXEC" "$main_exec")
+contents=$(replace "$contents" "EXEC" "$executable")
+contents=$(replace "$contents" "TESTS" "$tests")
+
+contents=$(replace "$contents" "BC_HISTORY_TEST_PREREQS" "$test_bc_history_prereqs")
+contents=$(replace "$contents" "DC_HISTORY_TEST_PREREQS" "$test_dc_history_prereqs")
+contents=$(replace "$contents" "HISTORY_TESTS" "$history_tests")
+
+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")
+
+contents=$(replace "$contents" "BSD" "$bsd")
+
+contents=$(replace "$contents" "BC_DEFAULT_BANNER" "$bc_default_banner")
+contents=$(replace "$contents" "BC_DEFAULT_SIGINT_RESET" "$bc_default_sigint_reset")
+contents=$(replace "$contents" "DC_DEFAULT_SIGINT_RESET" "$dc_default_sigint_reset")
+contents=$(replace "$contents" "BC_DEFAULT_TTY_MODE" "$bc_default_tty_mode")
+contents=$(replace "$contents" "DC_DEFAULT_TTY_MODE" "$dc_default_tty_mode")
+contents=$(replace "$contents" "BC_DEFAULT_PROMPT" "$bc_default_prompt")
+contents=$(replace "$contents" "DC_DEFAULT_PROMPT" "$dc_default_prompt")
+
+# Do the first print to the Makefile.
+printf '%s\n%s\n\n' "$contents" "$SRC_TARGETS" > "$scriptdir/Makefile"
+
+# Generate the individual test targets.
+if [ "$bc" -ne 0 ]; then
+ gen_std_tests bc "$extra_math" "$time_tests" $bc_test_exec
+ gen_script_tests bc "$extra_math" "$generate_tests" "$time_tests" $bc_test_exec
+ gen_err_tests bc $bc_test_exec
+fi
+
+if [ "$dc" -ne 0 ]; then
+ gen_std_tests dc "$extra_math" "$time_tests" $dc_test_exec
+ gen_script_tests dc "$extra_math" "$generate_tests" "$time_tests" $dc_test_exec
+ gen_err_tests dc $dc_test_exec
+fi
+
+cd "$scriptdir"
+
+# Copy the correct manuals to the expected places.
+cp -f manuals/bc/$manpage_args.1.md manuals/bc.1.md
+cp -f manuals/bc/$manpage_args.1 manuals/bc.1
+cp -f manuals/dc/$manpage_args.1.md manuals/dc.1.md
+cp -f manuals/dc/$manpage_args.1 manuals/dc.1
+
+make clean > /dev/null
diff --git a/contrib/bc/gen/bc_help.txt b/contrib/bc/gen/bc_help.txt
new file mode 100644
index 000000000000..9ba34c606481
--- /dev/null
+++ b/contrib/bc/gen/bc_help.txt
@@ -0,0 +1,185 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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` or see the online documentation at
+https://git.yzena.com/gavin/bc/src/tag/%s/manuals/bc/%s.1.md.
+
+This bc is compatible with both the GNU bc and the POSIX bc spec. See the GNU bc
+manual (https://www.gnu.org/software/bc/manual/bc.html) and bc spec
+(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 or online documentation.
+
+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 or online
+ documentation for more details.
+
+ -h --help
+
+ Print this usage message and exit.
+
+ -i --interactive
+
+ Force interactive mode.
+
+ -L --no-line-length
+
+ Disable line length checking.
+
+ -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 or
+ online documentation for details.
+
+ -P --no-prompt
+
+ Disable the prompts in interactive mode.
+
+ -R --no-read-prompt
+
+ Disable the read prompt in interactive mode.
+
+ -r keyword --redefine=keyword
+
+ Redefines "keyword" and allows it to be used as a function, variable, and
+ array name. This is useful when this bc gives parse errors on scripts
+ meant for other bc implementations.
+
+ Only keywords that are not in the POSIX bc spec may be redefined.
+
+ It is a fatal error to attempt to redefine a keyword that cannot be
+ redefined or does not exist.
+
+ -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.
+
+ -z --leading-zeroes
+
+ Enable leading zeroes on numbers greater than -1 and less than 1.
+
+Environment variables:
+
+ POSIXLY_CORRECT
+
+ Error if any non-POSIX extensions are used.
+
+ BC_ENV_ARGS
+
+ Command-line arguments to use on every run.
+
+ BC_LINE_LENGTH
+
+ If an integer, the number of characters to print on a line before
+ wrapping. Using 0 will disable line length checking.
+
+ BC_BANNER
+
+ If an integer and non-zero, display the copyright banner in interactive
+ mode.
+
+ Overrides the default, which is %s print the banner.
+
+ BC_SIGINT_RESET
+
+ If an integer and non-zero, reset on SIGINT, rather than exit, when in
+ interactive mode.
+
+ Overrides the default, which is %s.
+
+ BC_TTY_MODE
+
+ If an integer and non-zero, enable TTY mode when it is available.
+
+ Overrides the default, which is TTY mode %s.
+
+ BC_PROMPT
+
+ If an integer and non-zero, enable prompt when TTY mode is possible.
+
+ Overrides the default, which is prompt %s.
diff --git a/contrib/bc/gen/dc_help.txt b/contrib/bc/gen/dc_help.txt
new file mode 100644
index 000000000000..4cf10826cd7f
--- /dev/null
+++ b/contrib/bc/gen/dc_help.txt
@@ -0,0 +1,144 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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` or see the online documentation
+at https://git.yzena.com/gavin/bc/src/tag/%s/manuals/bc/%s.1.md.
+
+This dc is (mostly) compatible with the OpenBSD dc and the GNU dc. See the
+OpenBSD man page (http://man.openbsd.org/OpenBSD-current/man1/dc.1) and the GNU
+dc manual (https://www.gnu.org/software/bc/manual/dc-1.05/html_mono/dc.html)
+for details.
+
+This dc has a few differences from the two above:
+
+ 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.
+
+ -L --no-line-length
+
+ Disable line length checking.
+
+ -P --no-prompt
+
+ Disable the prompts in interactive mode.
+
+ -R --no-read-prompt
+
+ Disable the read prompt in interactive mode.
+
+ -V --version
+
+ Print version and copyright and exit.
+
+ -x --extended-register
+
+ Enable extended register mode.
+
+ -z --leading-zeroes
+
+ Enable leading zeroes on numbers greater than -1 and less than 1.
+
+Environment variables:
+
+ DC_ENV_ARGS
+
+ Command-line arguments to use on every run.
+
+ DC_LINE_LENGTH
+
+ If an integer, the number of characters to print on a line before
+ wrapping. Using 0 will disable line length checking.
+
+ DC_SIGINT_RESET
+
+ If an integer and non-zero, reset on SIGINT, rather than exit, when in
+ interactive mode.
+
+ Overrides the default, which is %s.
+
+ DC_TTY_MODE
+
+ If an integer and non-zero, enable TTY mode when it is available.
+
+ Overrides the default, which is TTY mode %s.
+
+ DC_PROMPT
+
+ If an integer and non-zero, enable prompt when TTY mode is possible.
+
+ Overrides the default, which is prompt %s.
diff --git a/contrib/bc/gen/lib.bc b/contrib/bc/gen/lib.bc
new file mode 100644
index 000000000000..c0cd7f7dc8d4
--- /dev/null
+++ b/contrib/bc/gen/lib.bc
@@ -0,0 +1,201 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The bc math library.
+ *
+ */
+
+scale=2*A
+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..23cbec104d02
--- /dev/null
+++ b/contrib/bc/gen/lib2.bc
@@ -0,0 +1,564 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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(x==0||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=A^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 gcd(a,b){
+ auto g,s
+ if(!b)return a
+ s=scale
+ scale=0
+ a=abs(a)$
+ b=abs(b)$
+ if(a<b){
+ g=a
+ a=b
+ b=g
+ }
+ while(b){
+ g=a%b
+ a=b
+ b=g
+ }
+ scale=s
+ return a
+}
+define lcm(a,b){
+ auto r,s
+ if(!a&&!b)return 0
+ s=scale
+ scale=0
+ a=abs(a)$
+ b=abs(b)$
+ r=a*b/gcd(a,b)
+ scale=s
+ return r
+}
+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=scale
+ scale+=2
+ s=s(x)
+ c=c(x)
+ scale-=2
+ 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(A^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,i
+ x=abs(x)$
+ i=2^8
+ for(p=1;i-1<x;p*=2){i*=i}
+ return p
+}
+define sbytes(x){
+ auto p,n,z
+ z=(x<0)
+ x=abs(x)
+ x=x$
+ n=ubytes(x)
+ p=2^(n*8-1)
+ if(x>p||(!z&&x==p))n*=2
+ return n
+}
+define s2un(x,n){
+ auto t,u,s
+ x=x$
+ if(x<0){
+ x=abs(x)
+ s=scale
+ scale=0
+ t=n*8
+ u=2^(t-1)
+ if(x==u)return x
+ else if(x>u)x%=u
+ scale=s
+ return 2^(t)-x
+ }
+ return x
+}
+define s2u(x){return s2un(x,sbytes(x))}
+define void plz(x){
+ if(leading_zero())print x
+ else{
+ if(x>-1&&x<1&&x!=0){
+ if(x<0)print"-"
+ print 0,abs(x)
+ }
+ else print x
+ }
+}
+define void plznl(x){
+ plz(x)
+ print"\n"
+}
+define void pnlz(x){
+ auto s,i
+ if(leading_zero()){
+ if(x>-1&&x<1&&x!=0){
+ s=scale(x)
+ if(x<0)print"-"
+ print"."
+ x=abs(x)
+ for(i=0;i<s;++i){
+ x<<=1
+ print x$
+ x-=x$
+ }
+ return
+ }
+ }
+ print x
+}
+define void pnlznl(x){
+ pnlz(x)
+ print"\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%=256
+ 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
+ for(i=n-1;i>=0;--i){
+ output_byte(x,i)
+ if(i)print" "
+ else print"\n"
+ }
+}
+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
+ }
+ x=s2un(x,n)
+ 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))}
+define bunrev(t){
+ auto a,s,m[]
+ s=scale
+ scale=0
+ t=abs(t)$
+ while(t!=1){
+ t=divmod(t,2,m[])
+ a*=2
+ a+=m[0]
+ }
+ scale=s
+ return a
+}
+define band(a,b){
+ auto s,t,m[],n[]
+ a=abs(a)$
+ b=abs(b)$
+ if(b>a){
+ t=b
+ b=a
+ a=t
+ }
+ s=scale
+ scale=0
+ t=1
+ while(b){
+ a=divmod(a,2,m[])
+ b=divmod(b,2,n[])
+ t*=2
+ t+=(m[0]&&n[0])
+ }
+ scale=s
+ return bunrev(t)
+}
+define bor(a,b){
+ auto s,t,m[],n[]
+ a=abs(a)$
+ b=abs(b)$
+ if(b>a){
+ t=b
+ b=a
+ a=t
+ }
+ s=scale
+ scale=0
+ t=1
+ while(b){
+ a=divmod(a,2,m[])
+ b=divmod(b,2,n[])
+ t*=2
+ t+=(m[0]||n[0])
+ }
+ while(a){
+ a=divmod(a,2,m[])
+ t*=2
+ t+=m[0]
+ }
+ scale=s
+ return bunrev(t)
+}
+define bxor(a,b){
+ auto s,t,m[],n[]
+ a=abs(a)$
+ b=abs(b)$
+ if(b>a){
+ t=b
+ b=a
+ a=t
+ }
+ s=scale
+ scale=0
+ t=1
+ while(b){
+ a=divmod(a,2,m[])
+ b=divmod(b,2,n[])
+ t*=2
+ t+=(m[0]+n[0]==1)
+ }
+ while(a){
+ a=divmod(a,2,m[])
+ t*=2
+ t+=m[0]
+ }
+ scale=s
+ return bunrev(t)
+}
+define bshl(a,b){return abs(a)$*2^abs(b)$}
+define bshr(a,b){return (abs(a)$/2^abs(b)$)$}
+define bnotn(x,n){
+ auto s,t,m[]
+ s=scale
+ scale=0
+ t=2^(abs(n)$*8)
+ x=abs(x)$%t+t
+ t=1
+ while(x!=1){
+ x=divmod(x,2,m[])
+ t*=2
+ t+=!m[0]
+ }
+ scale=s
+ return bunrev(t)
+}
+define bnot8(x){return bnotn(x,1)}
+define bnot16(x){return bnotn(x,2)}
+define bnot32(x){return bnotn(x,4)}
+define bnot64(x){return bnotn(x,8)}
+define bnot(x){return bnotn(x,ubytes(x))}
+define brevn(x,n){
+ auto s,t,m[]
+ s=scale
+ scale=0
+ t=2^(abs(n)$*8)
+ x=abs(x)$%t+t
+ scale=s
+ return bunrev(x)
+}
+define brev8(x){return brevn(x,1)}
+define brev16(x){return brevn(x,2)}
+define brev32(x){return brevn(x,4)}
+define brev64(x){return brevn(x,8)}
+define brev(x){return brevn(x,ubytes(x))}
+define broln(x,p,n){
+ auto s,t,m[]
+ s=scale
+ scale=0
+ n=abs(n)$*8
+ p=abs(p)$%n
+ t=2^n
+ x=abs(x)$%t
+ if(!p)return x
+ x=divmod(x,2^(n-p),m[])
+ x+=m[0]*2^p%t
+ scale=s
+ return x
+}
+define brol8(x,p){return broln(x,p,1)}
+define brol16(x,p){return broln(x,p,2)}
+define brol32(x,p){return broln(x,p,4)}
+define brol64(x,p){return broln(x,p,8)}
+define brol(x,p){return broln(x,p,ubytes(x))}
+define brorn(x,p,n){
+ auto s,t,m[]
+ s=scale
+ scale=0
+ n=abs(n)$*8
+ p=abs(p)$%n
+ t=2^n
+ x=abs(x)$%t
+ if(!p)return x
+ x=divmod(x,2^p,m[])
+ x+=m[0]*2^(n-p)%t
+ scale=s
+ return x
+}
+define bror8(x,p){return brorn(x,p,1)}
+define bror16(x,p){return brorn(x,p,2)}
+define bror32(x,p){return brorn(x,p,4)}
+define bror64(x,p){return brorn(x,p,8)}
+define brol(x,p){return brorn(x,p,ubytes(x))}
+define bmodn(x,n){
+ auto s
+ s=scale
+ scale=0
+ x=abs(x)$%2^(abs(n)$*8)
+ scale=s
+ return x
+}
+define bmod8(x){return bmodn(x,1)}
+define bmod16(x){return bmodn(x,2)}
+define bmod32(x){return bmodn(x,4)}
+define bmod64(x){return bmodn(x,8)}
diff --git a/contrib/bc/gen/strgen.c b/contrib/bc/gen/strgen.c
new file mode 100644
index 000000000000..63faf1ec3472
--- /dev/null
+++ b/contrib/bc/gen/strgen.c
@@ -0,0 +1,294 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Generates a const array from a bc script.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <errno.h>
+
+// For some reason, Windows needs this header.
+#ifndef _WIN32
+#include <libgen.h>
+#endif // _WIN32
+
+// This is exactly what it looks like. It just slaps a simple license header on
+// the generated C source file.
+static const char* const bc_gen_header =
+ "// Copyright (c) 2018-2021 Gavin D. Howard and contributors.\n"
+ "// Licensed under the 2-clause BSD license.\n"
+ "// *** AUTOMATICALLY GENERATED FROM %s. DO NOT MODIFY. ***\n\n";
+
+// These are just format strings used to generate the C source.
+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";
+
+// Error codes. We can't use 0 because these are used as exit statuses, and 0
+// as an exit status is not an error.
+#define IO_ERR (1)
+#define INVALID_INPUT_FILE (2)
+#define INVALID_PARAMS (3)
+
+// This is the max width to print characters to the screen. This is to ensure
+// that lines don't go much over 80 characters.
+#define MAX_WIDTH (72)
+
+/**
+ * Open a file. This function is to smooth over differences between POSIX and
+ * Windows.
+ * @param f A pointer to the FILE pointer that will be initialized.
+ * @param filename The name of the file.
+ * @param mode The mode to open the file in.
+ */
+static void open_file(FILE** f, const char* filename, const char* mode) {
+
+#ifndef _WIN32
+
+ *f = fopen(filename, mode);
+
+#else // _WIN32
+
+ // We want the file pointer to be NULL on failure, but fopen_s() is not
+ // guaranteed to set it.
+ *f = NULL;
+ fopen_s(f, filename, mode);
+
+#endif // _WIN32
+}
+
+/**
+ * Outputs a label, which is a string literal that the code can use as a name
+ * for the file that is being turned into a string. This is important for the
+ * math libraries because the parse and lex code expects a filename. The label
+ * becomes the filename for the purposes of lexing and parsing.
+ *
+ * The label is generated from bc_gen_label (above). It has the form:
+ *
+ * const char *<label_name> = <label>;
+ *
+ * This function is also needed to smooth out differences between POSIX and
+ * Windows, specifically, the fact that Windows uses backslashes for filenames
+ * and that backslashes have to be escaped in a string literal.
+ *
+ * @param out The file to output to.
+ * @param label The label name.
+ * @param name The actual label text, which is a filename.
+ * @return Positive if no error, negative on error, just like *printf().
+ */
+static int output_label(FILE* out, const char* label, const char* name) {
+
+#ifndef _WIN32
+
+ return fprintf(out, bc_gen_label, label, name);
+
+#else // _WIN32
+
+ size_t i, count = 0, len = strlen(name);
+ char* buf;
+ int ret;
+
+ // This loop counts how many backslashes there are in the label.
+ for (i = 0; i < len; ++i) count += (name[i] == '\\');
+
+ buf = (char*) malloc(len + 1 + count);
+ if (buf == NULL) return -1;
+
+ count = 0;
+
+ // This loop is the meat of the Windows version. What it does is copy the
+ // label byte-for-byte, unless it encounters a backslash, in which case, it
+ // copies the backslash twice to have it escaped properly in the string
+ // literal.
+ for (i = 0; i < len; ++i) {
+
+ buf[i + count] = name[i];
+
+ if (name[i] == '\\') {
+ count += 1;
+ buf[i + count] = name[i];
+ }
+ }
+
+ buf[i + count] = '\0';
+
+ ret = fprintf(out, bc_gen_label, label, buf);
+
+ free(buf);
+
+ return ret;
+
+#endif // _WIN32
+}
+
+/**
+ * This program generates C strings (well, actually, C char arrays) from text
+ * files. It generates 1 C source file. The resulting file has this structure:
+ *
+ * <Copyright Header>
+ *
+ * [<Label Extern>]
+ *
+ * <Char Array Extern>
+ *
+ * [<Preprocessor Guard Begin>]
+ * [<Label Definition>]
+ *
+ * <Char Array Definition>
+ * [<Preprocessor Guard End>]
+ *
+ * Anything surrounded by square brackets may not be in the final generated
+ * source file.
+ *
+ * The required command-line parameters are:
+ *
+ * input Input filename.
+ * output Output filename.
+ * name The name of the char array.
+ *
+ * The optional parameters are:
+ *
+ * label If given, a label for the char array. See the comment for the
+ * output_label() function. It is meant as a "filename" for the
+ * text when processed by bc and dc. If label is given, then the
+ * <Label Extern> and <Label Definition> will exist in the
+ * generated source file.
+ * define If given, a preprocessor macro that should be used as a guard
+ * for the char array and its label. If define is given, then
+ * <Preprocessor Guard Begin> will exist in the form
+ * "#if <define>" as part of the generated source file, and
+ * <Preprocessor Guard End> will exist in the form
+ * "endif // <define>".
+ * remove_tabs If this parameter exists, it must be an integer. If it is
+ * non-zero, then tabs are removed from the input file text before
+ * outputting to the output char array.
+ *
+ * All text files that are transformed have license comments. This program finds
+ * the end of that comment and strips it out as well.
+ */
+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 < 4) {
+ printf("usage: %s input output name [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);
+
+ open_file(&in, argv[1], "r");
+ if (!in) return INVALID_INPUT_FILE;
+
+ open_file(&out, argv[2], "w");
+ if (!out) goto out_err;
+
+ if (fprintf(out, bc_gen_header, argv[1]) < 0) goto err;
+ if (has_label && fprintf(out, bc_gen_label_extern, label) < 0) goto err;
+ if (fprintf(out, bc_gen_name_extern, name) < 0) goto err;
+ if (has_define && fprintf(out, bc_gen_ifdef, define) < 0) goto err;
+ if (has_label && output_label(out, label, argv[1]) < 0) goto err;
+ if (fprintf(out, bc_gen_name, name) < 0) goto err;
+
+ c = count = slashes = 0;
+
+ // This is where the end of the license comment is found.
+ while (slashes < 2 && (c = fgetc(in)) >= 0) {
+ slashes += (slashes == 1 && c == '/' && fgetc(in) == '\n');
+ slashes += (!slashes && c == '/' && fgetc(in) == '*');
+ }
+
+ // The file is invalid if the end of the license comment could not be found.
+ if (c < 0) {
+ err = INVALID_INPUT_FILE;
+ goto err;
+ }
+
+ // Do not put extra newlines at the beginning of the char array.
+ while ((c = fgetc(in)) == '\n');
+
+ // This loop is what generates the actual char array. It counts how many
+ // chars it has printed per line in order to insert newlines at appropriate
+ // places. It also skips tabs if they should be removed.
+ 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);
+ }
+
+ // Make sure the end looks nice and insert the NUL byte at the end.
+ 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..acaa6cdf0791
--- /dev/null
+++ b/contrib/bc/gen/strgen.sh
@@ -0,0 +1,85 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+export LANG=C
+export LC_CTYPE=C
+
+progname=${0##*/}
+
+# See strgen.c comment on main() for what these mean. Note, however, that this
+# script generates a string literal, not a char array. To understand the
+# consequences of that, see manuals/development.md#strgenc.
+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-2021 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..a2f5b416ce9b
--- /dev/null
+++ b/contrib/bc/include/args.h
@@ -0,0 +1,55 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for processing command-line arguments.
+ *
+ */
+
+#ifndef BC_ARGS_H
+#define BC_ARGS_H
+
+#include <status.h>
+#include <opt.h>
+#include <vm.h>
+
+/**
+ * Processes command-line arguments.
+ * @param argc How many arguments there are.
+ * @param argv The array of arguments.
+ * @param exit_exprs True if bc/dc should exit when there are expressions,
+ * false otherwise.
+ */
+void bc_args(int argc, char *argv[], bool exit_exprs);
+
+// A reference to the list of long options.
+extern const BcOptLong bc_args_lopt[];
+
+#endif // BC_ARGS_H
diff --git a/contrib/bc/include/bc.h b/contrib/bc/include/bc.h
new file mode 100644
index 000000000000..3d4a11592875
--- /dev/null
+++ b/contrib/bc/include/bc.h
@@ -0,0 +1,458 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for bc only.
+ *
+ */
+
+#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>
+
+/**
+ * The main function for bc. It just sets variables and passes its arguments
+ * through to @a bc_vm_boot().
+ */
+void bc_main(int argc, char *argv[]);
+
+// These are references to the help text, the library text, and the "filename"
+// for the library.
+extern const char bc_help[];
+extern const char bc_lib[];
+extern const char* bc_lib_name;
+
+// These are references to the second math library and its "filename."
+#if BC_ENABLE_EXTRA_MATH
+extern const char bc_lib2[];
+extern const char* bc_lib2_name;
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * A struct containing information about a bc keyword.
+ */
+typedef struct BcLexKeyword {
+
+ /// Holds the length of the keyword along with a bit that, if set, means the
+ /// keyword is used in POSIX bc.
+ uchar data;
+
+ /// The keyword text.
+ const char name[14];
+} BcLexKeyword;
+
+/// Sets the most significant bit. Used for setting the POSIX bit in
+/// BcLexKeyword's data field.
+#define BC_LEX_CHAR_MSB(bit) ((bit) << (CHAR_BIT - 1))
+
+/// Returns non-zero if the keyword is POSIX, zero otherwise.
+#define BC_LEX_KW_POSIX(kw) ((kw)->data & (BC_LEX_CHAR_MSB(1)))
+
+/// Returns the length of the keyword.
+#define BC_LEX_KW_LEN(kw) ((size_t) ((kw)->data & ~(BC_LEX_CHAR_MSB(1))))
+
+/// A macro to easily build a keyword entry. See bc_lex_kws in src/data.c.
+#define BC_LEX_KW_ENTRY(a, b, c) \
+ { .data = ((b) & ~(BC_LEX_CHAR_MSB(1))) | BC_LEX_CHAR_MSB(c), .name = a }
+
+#if BC_ENABLE_EXTRA_MATH
+
+/// A macro for the number of keywords bc has. This has to be updated if any are
+/// added. This is for the redefined_kws field of the BcVm struct.
+#define BC_LEX_NKWS (35)
+
+#else // BC_ENABLE_EXTRA_MATH
+
+/// A macro for the number of keywords bc has. This has to be updated if any are
+/// added. This is for the redefined_kws field of the BcVm struct.
+#define BC_LEX_NKWS (31)
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+// The array of keywords and its length.
+extern const BcLexKeyword bc_lex_kws[];
+extern const size_t bc_lex_kws_len;
+
+/**
+ * The @a BcLexNext function for bc. (See include/lex.h for a definition of
+ * @a BcLexNext.)
+ * @param l The lexer.
+ */
+void bc_lex_token(BcLex *l);
+
+// The following section is for flags needed when parsing bc code. These flags
+// are complicated, but necessary. Why you ask? Because bc's standard is awful.
+//
+// If you don't believe me, go read the bc Parsing section of the Development
+// manual (manuals/development.md). Then come back.
+//
+// In other words, these flags are the sign declaring, "Here be dragons."
+
+/**
+ * This returns a pointer to the set of flags at the top of the flag stack.
+ * @a p is expected to be a BcParse pointer.
+ * @param p The parser.
+ * @return A pointer to the top flag set.
+ */
+#define BC_PARSE_TOP_FLAG_PTR(p) ((uint16_t*) bc_vec_top(&(p)->flags))
+
+/**
+ * This returns the flag set at the top of the flag stack. @a p is expected to
+ * be a BcParse pointer.
+ * @param p The parser.
+ * @return The top flag set.
+ */
+#define BC_PARSE_TOP_FLAG(p) (*(BC_PARSE_TOP_FLAG_PTR(p)))
+
+// After this point, all flag #defines are in sets of 2: one to define the flag,
+// and one to define a way to grab the flag from the flag set at the top of the
+// flag stack. All `p` arguments are pointers to a BcParse.
+
+// This flag is set if the parser has seen a left brace.
+#define BC_PARSE_FLAG_BRACE (UINTMAX_C(1)<<0)
+#define BC_PARSE_BRACE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BRACE)
+
+// This flag is set if the parser is parsing inside of the braces of a function
+// body.
+#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)
+
+// This flag is set if the parser is parsing a function. It is different from
+// the one above because it is set if it is parsing a function body *or* header,
+// not just if it's parsing a function body.
+#define BC_PARSE_FLAG_FUNC (UINTMAX_C(1)<<2)
+#define BC_PARSE_FUNC(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC)
+
+// This flag is set if the parser is expecting to parse a body, whether of a
+// function, an if statement, or a loop.
+#define BC_PARSE_FLAG_BODY (UINTMAX_C(1)<<3)
+#define BC_PARSE_BODY(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BODY)
+
+// This flag is set if bc is parsing a loop. This is important because the break
+// and continue keywords are only valid inside of a loop.
+#define BC_PARSE_FLAG_LOOP (UINTMAX_C(1)<<4)
+#define BC_PARSE_LOOP(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP)
+
+// This flag is set if bc is parsing the body of a loop. It is different from
+// the one above the same way @a BC_PARSE_FLAG_FUNC_INNER is different from
+// @a BC_PARSE_FLAG_FUNC.
+#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)
+
+// This flag is set if bc is parsing an if statement.
+#define BC_PARSE_FLAG_IF (UINTMAX_C(1)<<6)
+#define BC_PARSE_IF(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF)
+
+// This flag is set if bc is parsing an else statement. This is important
+// because of "else if" constructions, among other things.
+#define BC_PARSE_FLAG_ELSE (UINTMAX_C(1)<<7)
+#define BC_PARSE_ELSE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_ELSE)
+
+// This flag is set if bc just finished parsing an if statement and its body.
+// It tells the parser that it can probably expect an else statement next. This
+// flag is, thus, one of the most subtle.
+#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)
+
+/**
+ * This returns true if bc is in a state where it should not execute any code
+ * at all.
+ * @param p The parser.
+ * @return True if execution cannot proceed, false otherwise.
+ */
+#define BC_PARSE_NO_EXEC(p) ((p)->flags.len != 1 || BC_PARSE_TOP_FLAG(p) != 0)
+
+/**
+ * This returns true if the token @a t is a statement delimiter, which is
+ * either a newline or a semicolon.
+ * @param t The token to check.
+ * @return True if t is a statement delimiter token; false otherwise.
+ */
+#define BC_PARSE_DELIMITER(t) \
+ ((t) == BC_LEX_SCOLON || (t) == BC_LEX_NLINE || (t) == BC_LEX_EOF)
+
+/**
+ * This is poorly named, but it basically returns whether or not the current
+ * state is valid for the end of an else statement.
+ * @param f The flag set to be checked.
+ * @return True if the state is valid for the end of an else statement.
+ */
+#define BC_PARSE_BLOCK_STMT(f) \
+ ((f) & (BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_LOOP_INNER))
+
+/**
+ * This returns the value of the data for an operator with precedence @a p and
+ * associativity @a l (true if left associative, false otherwise). This is used
+ * to construct an array of operators, bc_parse_ops, in src/data.c.
+ * @param p The precedence.
+ * @param l True if the operator is left associative, false otherwise.
+ * @return The data for the operator.
+ */
+#define BC_PARSE_OP(p, l) (((p) & ~(BC_LEX_CHAR_MSB(1))) | (BC_LEX_CHAR_MSB(l)))
+
+/**
+ * Returns the operator data for the lex token @a t.
+ * @param t The token to return operator data for.
+ * @return The operator data for @a t.
+ */
+#define BC_PARSE_OP_DATA(t) bc_parse_ops[((t) - BC_LEX_OP_INC)]
+
+/**
+ * Returns non-zero if operator @a op is left associative, zero otherwise.
+ * @param op The operator to test for associativity.
+ * @return Non-zero if the operator is left associative, zero otherwise.
+ */
+#define BC_PARSE_OP_LEFT(op) (BC_PARSE_OP_DATA(op) & BC_LEX_CHAR_MSB(1))
+
+/**
+ * Returns the precedence of operator @a op. Lower number means higher
+ * precedence.
+ * @param op The operator to return the precedence of.
+ * @return The precedence of @a op.
+ */
+#define BC_PARSE_OP_PREC(op) (BC_PARSE_OP_DATA(op) & ~(BC_LEX_CHAR_MSB(1)))
+
+/**
+ * A macro to easily define a series of bits for whether a lex token is an
+ * expression token or not. It takes 8 expression bits, corresponding to the 8
+ * bits in a uint8_t. You can see this in use for bc_parse_exprs in src/data.c.
+ * @param e1 The first bit.
+ * @param e2 The second bit.
+ * @param e3 The third bit.
+ * @param e4 The fourth bit.
+ * @param e5 The fifth bit.
+ * @param e6 The sixth bit.
+ * @param e7 The seventh bit.
+ * @param e8 The eighth bit.
+ * @return An expression entry for bc_parse_exprs[].
+ */
+#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))
+
+/**
+ * Returns true if token @a i is a token that belongs in an expression.
+ * @param i The token to test.
+ * @return True if i is an expression token, false otherwise.
+ */
+#define BC_PARSE_EXPR(i) \
+ (bc_parse_exprs[(((i) & (uchar) ~(0x07)) >> 3)] & (1 << (7 - ((i) & 0x07))))
+
+/**
+ * Returns the operator (by lex token) that is at the top of the operator
+ * stack.
+ * @param p The parser.
+ * @return The operator that is at the top of the operator stack, as a lex
+ * token.
+ */
+#define BC_PARSE_TOP_OP(p) (*((BcLexType*) bc_vec_top(&(p)->ops)))
+
+/**
+ * Returns true if bc has a "leaf" token. A "leaf" token is one that can stand
+ * alone in an expression. For example, a number by itself can be an expression,
+ * but a binary operator, while valid for an expression, cannot be alone in the
+ * expression. It must have an expression to the left and right of itself. See
+ * the documentation for @a bc_parse_expr_err() in src/bc_parse.c.
+ * @param prev The previous token as an instruction.
+ * @param bin_last True if that last operator was a binary operator, false
+ * otherwise.
+ * @param rparen True if the last operator was a right paren.
+ * return True if the last token was a leaf token, false otherwise.
+ */
+#define BC_PARSE_LEAF(prev, bin_last, rparen) \
+ (!(bin_last) && ((rparen) || bc_parse_inst_isLeaf(prev)))
+
+/**
+ * This returns true if the token @a t should be treated as though it's a
+ * variable. This goes for actual variables, array elements, and globals.
+ * @param t The token to test.
+ * @return True if @a t should be treated as though it's a variable, false
+ * otherwise.
+ */
+#if BC_ENABLE_EXTRA_MATH
+#define BC_PARSE_INST_VAR(t) \
+ ((t) >= BC_INST_VAR && (t) <= BC_INST_SEED && (t) != BC_INST_ARRAY)
+#else // BC_ENABLE_EXTRA_MATH
+#define BC_PARSE_INST_VAR(t) \
+ ((t) >= BC_INST_VAR && (t) <= BC_INST_SCALE && (t) != BC_INST_ARRAY)
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * Returns true if the previous token @a p (in the form of a bytecode
+ * instruction) is a prefix operator. The fact that it is for bytecode
+ * instructions is what makes it different from @a BC_PARSE_OP_PREFIX below.
+ * @param p The previous token.
+ * @return True if @a p is a prefix operator.
+ */
+#define BC_PARSE_PREV_PREFIX(p) ((p) >= BC_INST_NEG && (p) <= BC_INST_BOOL_NOT)
+
+/**
+ * Returns true if token @a t is a prefix operator.
+ * @param t The token to test.
+ * @return True if @a t is a prefix operator, false otherwise.
+ */
+#define BC_PARSE_OP_PREFIX(t) ((t) == BC_LEX_OP_BOOL_NOT || (t) == BC_LEX_NEG)
+
+/**
+ * We can calculate the conversion between tokens and bytecode instructions by
+ * subtracting the position of the first operator in the lex enum and adding the
+ * position of the first in the instruction enum. Note: This only works for
+ * binary operators.
+ * @param t The token to turn into an instruction.
+ * @return The token as an instruction.
+ */
+#define BC_PARSE_TOKEN_INST(t) ((uchar) ((t) - BC_LEX_NEG + BC_INST_NEG))
+
+/**
+ * Returns true if the token is a bc keyword.
+ * @param t The token to check.
+ * @return True if @a t is a bc keyword, false otherwise.
+ */
+#define BC_PARSE_IS_KEYWORD(t) ((t) >= BC_LEX_KW_AUTO && (t) <= BC_LEX_KW_ELSE)
+
+/// A struct that holds data about what tokens should be expected next. There
+/// are a few instances of these, all named because they are used in specific
+/// cases. Basically, in certain situations, it's useful to use the same code,
+/// but have a list of valid tokens.
+///
+/// Obviously, @a len is the number of tokens in the @a tokens array. If more
+/// than 4 is needed in the future, @a tokens will have to be changed.
+typedef struct BcParseNext {
+
+ /// The number of tokens in the tokens array.
+ uchar len;
+
+ /// The tokens that can be expected next.
+ uchar tokens[4];
+
+} BcParseNext;
+
+/// A macro to construct an array literal of tokens from a parameter list.
+#define BC_PARSE_NEXT_TOKENS(...) .tokens = { __VA_ARGS__ }
+
+/// A macro to generate a BcParseNext literal from BcParseNext data. See
+/// src/data.c for examples.
+#define BC_PARSE_NEXT(a, ...) \
+ { .len = (uchar) (a), BC_PARSE_NEXT_TOKENS(__VA_ARGS__) }
+
+/// A status returned by @a bc_parse_expr_err(). It can either return success or
+/// an error indicating an empty expression.
+typedef enum BcParseStatus {
+
+ BC_PARSE_STATUS_SUCCESS,
+ BC_PARSE_STATUS_EMPTY_EXPR,
+
+} BcParseStatus;
+
+/**
+ * The @a BcParseExpr function for bc. (See include/parse.h for a definition of
+ * @a BcParseExpr.)
+ * @param p The parser.
+ * @param flags Flags that define the requirements that the parsed code must
+ * meet or an error will result. See @a BcParseExpr for more info.
+ */
+void bc_parse_expr(BcParse *p, uint8_t flags);
+
+/**
+ * The @a BcParseParse function for bc. (See include/parse.h for a definition of
+ * @a BcParseParse.)
+ * @param p The parser.
+ */
+void bc_parse_parse(BcParse *p);
+
+/// References to the signal message and its length.
+extern const char bc_sig_msg[];
+extern const uchar bc_sig_msg_len;
+
+/// A reference to an array of bits that are set if the corresponding lex token
+/// is valid in an expression.
+extern const uint8_t bc_parse_exprs[];
+
+/// A reference to an array of bc operators.
+extern const uchar bc_parse_ops[];
+
+// References to the various instances of BcParseNext's.
+
+/// A reference to what tokens are valid as next tokens when parsing normal
+/// expressions. More accurately. these are the tokens that are valid for
+/// *ending* the expression.
+extern const BcParseNext bc_parse_next_expr;
+
+/// A reference to what tokens are valid as next tokens when parsing function
+/// parameters (well, actually arguments).
+extern const BcParseNext bc_parse_next_arg;
+
+/// A reference to what tokens are valid as next tokens when parsing a print
+/// statement.
+extern const BcParseNext bc_parse_next_print;
+
+/// A reference to what tokens are valid as next tokens when parsing things like
+/// loop headers and builtin functions where the only thing expected is a right
+/// paren.
+///
+/// The name is an artifact of history, and is related to @a BC_PARSE_REL (see
+/// include/parse.h). It refers to how POSIX only allows some operators as part
+/// of the conditional of for loops, while loops, and if statements.
+extern const BcParseNext bc_parse_next_rel;
+
+// What tokens are valid as next tokens when parsing an array element
+// expression.
+extern const BcParseNext bc_parse_next_elem;
+
+/// A reference to what tokens are valid as next tokens when parsing the first
+/// two parts of a for loop header.
+extern const BcParseNext bc_parse_next_for;
+
+/// A reference to what tokens are valid as next tokens when parsing a read
+/// expression.
+extern const BcParseNext bc_parse_next_read;
+
+/// A reference to what tokens are valid as next tokens when parsing a builtin
+/// function with multiple arguments.
+extern const BcParseNext bc_parse_next_builtin;
+
+#else // BC_ENABLED
+
+// If bc is not enabled, execution is always possible because dc has strict
+// rules that ensure execution can always proceed safely.
+#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..9c0e5e59cfd0
--- /dev/null
+++ b/contrib/bc/include/bcl.h
@@ -0,0 +1,242 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The public header for the bc library.
+ *
+ */
+
+#ifndef BC_BCL_H
+#define BC_BCL_H
+
+#ifdef _WIN32
+#include <Windows.h>
+#include <BaseTsd.h>
+#include <stdio.h>
+#include <io.h>
+#endif // _WIN32
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+// Windows has deprecated isatty() and the rest of these. Or doesn't have them.
+// So these are just fixes for Windows.
+#ifdef _WIN32
+
+// This one is special. Windows did not like me defining an
+// inline function that was not given a definition in a header
+// file. This suppresses that by making inline functions non-inline.
+#define inline
+
+#define restrict __restrict
+#define strdup _strdup
+#define write(f, b, s) _write((f), (b), (unsigned int) (s))
+#define read(f, b, s) _read((f), (b), (unsigned int) (s))
+#define close _close
+#define open(f, n, m) \
+ _sopen_s((f), (n), (m) | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE)
+#define sigjmp_buf jmp_buf
+#define sigsetjmp(j, s) setjmp(j)
+#define siglongjmp longjmp
+#define isatty _isatty
+#define STDIN_FILENO _fileno(stdin)
+#define STDOUT_FILENO _fileno(stdout)
+#define STDERR_FILENO _fileno(stderr)
+#define ssize_t SSIZE_T
+#define S_ISDIR(m) ((m) & _S_IFDIR)
+#define O_RDONLY _O_RDONLY
+#define stat _stat
+#define fstat _fstat
+#define BC_FILE_SEP '\\'
+
+#else // _WIN32
+#define BC_FILE_SEP '/'
+#endif // _WIN32
+
+#define BCL_SEED_ULONGS (4)
+#define BCL_SEED_SIZE (sizeof(long) * BCL_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
+
+// For more information about the items here, see the either the
+// manuals/bcl.3.md or manuals/bcl.3 manuals.
+
+// BclBigDig is a fixed-size integer type that bcl can convert numbers to.
+//
+// BclRandInt is the type of fixed-size integer natively returned by the
+// pseudo-random number generator.
+#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
+
+#ifndef BC_ENABLE_LIBRARY
+#define BC_ENABLE_LIBRARY (1)
+#endif // BC_ENABLE_LIBRARY
+
+#if BC_ENABLE_LIBRARY
+
+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);
+bool bcl_leadingZeroes(void);
+void bcl_setLeadingZeroes(bool leadingZeroes);
+
+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[BCL_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_ENABLE_LIBRARY
+
+#endif // BC_BCL_H
diff --git a/contrib/bc/include/dc.h b/contrib/bc/include/dc.h
new file mode 100644
index 000000000000..88b5e054f878
--- /dev/null
+++ b/contrib/bc/include/dc.h
@@ -0,0 +1,104 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for dc only.
+ *
+ */
+
+#ifndef BC_DC_H
+#define BC_DC_H
+
+#if DC_ENABLED
+
+#include <status.h>
+#include <lex.h>
+#include <parse.h>
+
+/**
+ * The main function for dc. It just sets variables and passes its arguments
+ * through to @a bc_vm_boot().
+ */
+void dc_main(int argc, char *argv[]);
+
+// A reference to the dc help text.
+extern const char dc_help[];
+
+/**
+ * The @a BcLexNext function for dc. (See include/lex.h for a definition of
+ * @a BcLexNext.)
+ * @param l The lexer.
+ */
+void dc_lex_token(BcLex *l);
+
+/**
+ * Returns true if the negative char `_` should be treated as a command or not.
+ * dc considers negative a command if it does *not* immediately proceed a
+ * number. Otherwise, it's just considered a negative.
+ * @param l The lexer.
+ * @return True if a negative should be treated as a command, false if it
+ * should be treated as a negative sign on a number.
+ */
+bool dc_lex_negCommand(BcLex *l);
+
+// References to the signal message and its length.
+extern const char dc_sig_msg[];
+extern const uchar dc_sig_msg_len;
+
+// References to an array and its length. This array is an array of lex tokens
+// that, when encountered, should be treated as commands that take a register.
+extern const uint8_t dc_lex_regs[];
+extern const size_t dc_lex_regs_len;
+
+// References to an array of tokens and its length. This array corresponds to
+// the ASCII table, starting at double quotes. This makes it easy to look up
+// tokens for characters.
+extern const uint8_t dc_lex_tokens[];
+extern const uint8_t dc_parse_insts[];
+
+/**
+ * The @a BcParseParse function for dc. (See include/parse.h for a definition of
+ * @a BcParseParse.)
+ * @param p The parser.
+ */
+void dc_parse_parse(BcParse *p);
+
+/**
+ * The @a BcParseExpr function for dc. (See include/parse.h for a definition of
+ * @a BcParseExpr.)
+ * @param p The parser.
+ * @param flags Flags that define the requirements that the parsed code must
+ * meet or an error will result. See @a BcParseExpr for more info.
+ */
+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..b30b932c9abb
--- /dev/null
+++ b/contrib/bc/include/file.h
@@ -0,0 +1,177 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for 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)
+
+/// The file struct.
+typedef struct BcFile {
+
+ // The actual file descriptor.
+ int fd;
+
+ // The buffer for the file.
+ char *buf;
+
+ // The length (number of actual chars) in the buffer.
+ size_t len;
+
+ // The capacity (max number of chars) of the buffer.
+ size_t cap;
+
+} BcFile;
+
+#if BC_ENABLE_HISTORY
+
+/// Types of flushing. These are important because of history and printing
+/// strings without newlines, something that users could use as their own
+/// prompts.
+typedef enum BcFlushType {
+
+ /// Do not clear the stored partial line, but don't add to it.
+ BC_FLUSH_NO_EXTRAS_NO_CLEAR,
+
+ /// Do not clear the stored partial line and add to it.
+ BC_FLUSH_SAVE_EXTRAS_NO_CLEAR,
+
+ /// Clear the stored partial line and do not save the new stuff either.
+ BC_FLUSH_NO_EXTRAS_CLEAR,
+
+ /// Clear the stored partial line, but save the new stuff.
+ BC_FLUSH_SAVE_EXTRAS_CLEAR,
+
+} BcFlushType;
+
+#else // BC_ENABLE_HISTORY
+
+// These make sure that the BcFlushType parameter disappears if history is not
+// used.
+
+#define bc_file_putchar(f, t, c) bc_file_putchar(f, c)
+#define bc_file_flushErr(f, t) bc_file_flushErr(f)
+#define bc_file_flush(f, t) bc_file_flush(f)
+#define bc_file_write(f, t, b, n) bc_file_write(f, b, n)
+#define bc_file_puts(f, t, s) bc_file_puts(f, s)
+
+#endif // BC_ENABLE_HISTORY
+
+/**
+ * Initialize a file.
+ * @param f The file to initialize.
+ * @param fd The file descriptor.
+ * @param buf The buffer for the file.
+ * @param cap The capacity of the buffer.
+ */
+void bc_file_init(BcFile *f, int fd, char *buf, size_t cap);
+
+/**
+ * Frees a file, including flushing it.
+ * @param f The file to free.
+ */
+void bc_file_free(BcFile *f);
+
+/**
+ * Print a char into the file.
+ * @param f The file to print to.
+ * @param type The flush type.
+ * @param c The character to write.
+ */
+void bc_file_putchar(BcFile *restrict f, BcFlushType type, uchar c);
+
+/**
+ * Flush and return an error if it failed. This is meant to be used when needing
+ * to flush in error situations when an error is already in flight. It would be
+ * a very bad deal to throw another error.
+ * @param f The file to flush.
+ * @param type The flush type.
+ * @return A status indicating if an error occurred.
+ */
+BcStatus bc_file_flushErr(BcFile *restrict f, BcFlushType type);
+
+/**
+ * Flush and throw an error on failure.
+ * @param f The file to flush.
+ * @param type The flush type.
+ */
+void bc_file_flush(BcFile *restrict f, BcFlushType type);
+
+/**
+ * Write the contents of buf to the file.
+ * @param f The file to flush.
+ * @param type The flush type.
+ * @param buf The buffer whose contents will be written to the file.
+ * @param n The length of buf.
+ */
+void bc_file_write(BcFile *restrict f, BcFlushType type,
+ const char *buf, size_t n);
+
+/**
+ * Write to the file like fprintf would. This is very rudimentary.
+ * @param f The file to flush.
+ * @param fmt The format string.
+ */
+void bc_file_printf(BcFile *restrict f, const char *fmt, ...);
+
+/**
+ * Write to the file like vfprintf would. This is very rudimentary.
+ * @param f The file to flush.
+ * @param fmt The format string.
+ */
+void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args);
+
+/**
+ * Write str to the file.
+ * @param f The file to flush.
+ * @param type The flush type.
+ * @param str The string to write to the file.
+ */
+void bc_file_puts(BcFile *restrict f, BcFlushType type, const char *str);
+
+#if BC_ENABLE_HISTORY
+
+// Some constant flush types for ease of use.
+extern const BcFlushType bc_flush_none;
+extern const BcFlushType bc_flush_err;
+extern const BcFlushType bc_flush_save;
+
+#endif // BC_ENABLE_HISTORY
+
+#endif // BC_FILE_H
diff --git a/contrib/bc/include/history.h b/contrib/bc/include/history.h
new file mode 100644
index 000000000000..8d9c3417d897
--- /dev/null
+++ b/contrib/bc/include/history.h
@@ -0,0 +1,338 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <signal.h>
+
+#ifndef _WIN32
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/select.h>
+#else // _WIN32
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif // WIN32_LEAN_AND_MEAN
+
+#include <Windows.h>
+#include <io.h>
+#include <conio.h>
+
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+
+#endif // _WIN32
+
+#include <status.h>
+#include <vector.h>
+#include <read.h>
+
+#if BC_DEBUG_CODE
+#include <file.h>
+#endif // BC_DEBUG_CODE
+
+/// Default columns.
+#define BC_HIST_DEF_COLS (80)
+
+/// Max number of history entries.
+#define BC_HIST_MAX_LEN (128)
+
+/// Max length of a line.
+#define BC_HIST_MAX_LINE (4095)
+
+/// Max size for cursor position buffer.
+#define BC_HIST_SEQ_SIZE (64)
+
+/**
+ * The number of entries in the history.
+ * @param h The history data.
+ */
+#define BC_HIST_BUF_LEN(h) ((h)->buf.len - 1)
+
+/**
+ * Read n characters into s and check the error.
+ * @param s The buffer to read into.
+ * @param n The number of bytes to read.
+ * @return True if there was an error, false otherwise.
+ */
+#define BC_HIST_READ(s, n) (bc_history_read((s), (n)) == -1)
+
+/// Markers for direction when using arrow keys.
+#define BC_HIST_NEXT (false)
+#define BC_HIST_PREV (true)
+
+#if BC_DEBUG_CODE
+
+// These are just for debugging.
+
+#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
+
+/// An enum of useful actions. To understand what these mean, check terminal
+/// emulators for their shortcuts or the VT100 codes.
+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_S = 19,
+ 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_CTRL_BSLASH = 28,
+ 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;
+
+ /// Any material printed without a trailing newline.
+ BcVec extras;
+
+ /// Prompt to display.
+ const char *prompt;
+
+ /// Prompt length.
+ size_t plen;
+
+ /// 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;
+
+#ifndef _WIN32
+ /// The original terminal state.
+ struct termios orig_termios;
+#else // _WIN32
+ /// The original input console mode.
+ DWORD orig_in;
+
+ /// The original output console mode.
+ DWORD orig_out;
+#endif // _WIN32
+
+ /// These next two are here because pahole found a 4 byte hole here.
+
+ /// Whether we are in rawmode.
+ bool rawMode;
+
+ /// Whether the terminal is bad.
+ bool badTerm;
+
+#ifndef _WIN32
+ /// 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;
+#endif // _WIN32
+
+} BcHistory;
+
+/**
+ * Get a line from stdin using history. This returns a status because I don't
+ * want to throw errors while the terminal is in raw mode.
+ * @param h The history data.
+ * @param vec A vector to put the line into.
+ * @param prompt The prompt to display, if desired.
+ * @return A status indicating an error, if any. Returning a status here
+ * is better because if we throw an error out of history, we
+ * leave the terminal in raw mode or in some other half-baked
+ * state.
+ */
+BcStatus bc_history_line(BcHistory *h, BcVec *vec, const char *prompt);
+
+/**
+ * Initialize history data.
+ * @param h The struct to initialize.
+ */
+void bc_history_init(BcHistory *h);
+
+/**
+ * Free history data (and recook the terminal).
+ * @param h The struct to free.
+ */
+void bc_history_free(BcHistory *h);
+
+/**
+ * Frees strings used by history.
+ * @param str The string to free.
+ */
+void bc_history_string_free(void *str);
+
+// A list of terminals that don't work.
+extern const char *bc_history_bad_terms[];
+
+// A tab in history and its length.
+extern const char bc_history_tab[];
+extern const size_t bc_history_tab_len;
+
+// A ctrl+c string.
+extern const char bc_history_ctrlc[];
+
+// UTF-8 data arrays.
+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
+
+// Debug data.
+extern BcFile bc_history_debug_fp;
+extern char *bc_history_debug_buf;
+
+/**
+ * A function to print keycodes for debugging.
+ * @param h The history data.
+ */
+void bc_history_printKeyCodes(BcHistory* h);
+
+#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..705aca35df1c
--- /dev/null
+++ b/contrib/bc/include/lang.h
@@ -0,0 +1,700 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for program data.
+ *
+ */
+
+#ifndef BC_LANG_H
+#define BC_LANG_H
+
+#include <stdbool.h>
+
+#include <status.h>
+#include <vector.h>
+#include <num.h>
+
+/// The instructions for bytecode.
+typedef enum BcInst {
+
+#if BC_ENABLED
+
+ /// Postfix increment and decrement. Prefix are translated into
+ /// BC_INST_ONE with either BC_INST_ASSIGN_PLUS or BC_INST_ASSIGN_MINUS.
+ BC_INST_INC = 0,
+ BC_INST_DEC,
+#endif // BC_ENABLED
+
+ /// Unary negation.
+ BC_INST_NEG,
+
+ /// Boolean not.
+ BC_INST_BOOL_NOT,
+#if BC_ENABLE_EXTRA_MATH
+ /// Truncation operator.
+ BC_INST_TRUNC,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// These should be self-explanatory.
+ BC_INST_POWER,
+ BC_INST_MULTIPLY,
+ BC_INST_DIVIDE,
+ BC_INST_MODULUS,
+ BC_INST_PLUS,
+ BC_INST_MINUS,
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// Places operator.
+ BC_INST_PLACES,
+
+ /// Shift operators.
+ BC_INST_LSHIFT,
+ BC_INST_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// Comparison operators.
+ BC_INST_REL_EQ,
+ BC_INST_REL_LE,
+ BC_INST_REL_GE,
+ BC_INST_REL_NE,
+ BC_INST_REL_LT,
+ BC_INST_REL_GT,
+
+ /// Boolean or and and.
+ BC_INST_BOOL_OR,
+ BC_INST_BOOL_AND,
+
+#if BC_ENABLED
+ /// Same as the normal operators, but assigment. So ^=, *=, /=, etc.
+ 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
+ /// Places and shift assignment operators.
+ BC_INST_ASSIGN_PLACES,
+ BC_INST_ASSIGN_LSHIFT,
+ BC_INST_ASSIGN_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// Normal assignment.
+ BC_INST_ASSIGN,
+
+ /// bc and dc detect when the value from an assignment is not necessary.
+ /// For example, a plain assignment statement means the value is never used.
+ /// In those cases, we can get lots of performance back by not even creating
+ /// a copy at all. In fact, it saves a copy, a push onto the results stack,
+ /// a pop from the results stack, and a free. Definitely worth it to detect.
+ 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
+ /// Same as above.
+ 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
+
+ /// Normal assignment that pushes no value on the stack.
+ BC_INST_ASSIGN_NO_VAL,
+
+ /// Push a constant onto the results stack.
+ BC_INST_NUM,
+
+ /// Push a variable onto the results stack.
+ BC_INST_VAR,
+
+ /// Push an array element onto the results stack.
+ BC_INST_ARRAY_ELEM,
+
+ /// Push an array onto the results stack. This is different from pushing an
+ /// array *element* onto the results stack; it pushes a reference to the
+ /// whole array. This is needed in bc for function arguments that are
+ /// arrays. It is also needed for returning the length of an array.
+ BC_INST_ARRAY,
+
+ /// Push a zero or a one onto the stack. These are special cased because it
+ /// does help performance, particularly for one since inc/dec operators
+ /// use it.
+ BC_INST_ZERO,
+ BC_INST_ONE,
+
+#if BC_ENABLED
+ /// Push the last printed value onto the stack.
+ BC_INST_LAST,
+#endif // BC_ENABLED
+
+ /// Push the value of any of the globals onto the stack.
+ BC_INST_IBASE,
+ BC_INST_OBASE,
+ BC_INST_SCALE,
+
+#if BC_ENABLE_EXTRA_MATH
+ /// Push the value of the seed global onto the stack.
+ BC_INST_SEED,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// These are builtin functions.
+ BC_INST_LENGTH,
+ BC_INST_SCALE_FUNC,
+ BC_INST_SQRT,
+ BC_INST_ABS,
+
+#if BC_ENABLE_EXTRA_MATH
+ /// Another builtin function.
+ BC_INST_IRAND,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// Asciify.
+ BC_INST_ASCIIFY,
+
+ /// Another builtin function.
+ BC_INST_READ,
+
+#if BC_ENABLE_EXTRA_MATH
+ /// Another builtin function.
+ BC_INST_RAND,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// Return the max for the various globals.
+ BC_INST_MAXIBASE,
+ BC_INST_MAXOBASE,
+ BC_INST_MAXSCALE,
+#if BC_ENABLE_EXTRA_MATH
+ /// Return the max value returned by rand().
+ BC_INST_MAXRAND,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// bc line_length() builtin function.
+ BC_INST_LINE_LENGTH,
+
+#if BC_ENABLED
+
+ /// bc global_stacks() builtin function.
+ BC_INST_GLOBAL_STACKS,
+
+#endif // BC_ENABLED
+
+ /// bc leading_zero() builtin function.
+ BC_INST_LEADING_ZERO,
+
+ /// This is slightly misnamed versus BC_INST_PRINT_POP. Well, it is in bc.
+ /// dc uses this instruction to print, but not pop. That's valid in dc.
+ /// However, in bc, it is *never* valid to print without popping. In bc,
+ /// BC_INST_PRINT_POP is used to indicate when a string should be printed
+ /// because of a print statement or whether it should be printed raw. The
+ /// reason for this is because a print statement handles escaped characters.
+ /// So BC_INST_PRINT_POP is for printing a string from a print statement,
+ /// BC_INST_PRINT_STR is for printing a string by itself.
+ ///
+ /// In dc, BC_INST_PRINT_POP prints and pops, and BC_INST_PRINT just prints.
+ ///
+ /// Oh, and BC_INST_STR pushes a string onto the results stack.
+ BC_INST_PRINT,
+ BC_INST_PRINT_POP,
+ BC_INST_STR,
+#if BC_ENABLED
+ BC_INST_PRINT_STR,
+
+ /// Jumps unconditionally.
+ BC_INST_JUMP,
+
+ /// Jumps if the top of the results stack is zero (condition failed). It
+ /// turns out that we only want to jump when conditions fail to "skip" code.
+ BC_INST_JUMP_ZERO,
+
+ /// Call a function.
+ BC_INST_CALL,
+
+ /// Return the top of the stack to the caller.
+ BC_INST_RET,
+
+ /// Return 0 to the caller.
+ BC_INST_RET0,
+
+ /// Special return instruction for void functions.
+ BC_INST_RET_VOID,
+
+ /// Special halt instruction.
+ BC_INST_HALT,
+#endif // BC_ENABLED
+
+ /// Pop an item off of the results stack.
+ BC_INST_POP,
+
+ /// Swaps the top two items on the results stack.
+ BC_INST_SWAP,
+
+ /// Modular exponentiation.
+ BC_INST_MODEXP,
+
+ /// Do divide and modulus at the same time.
+ BC_INST_DIVMOD,
+
+ /// Turns a number into a string and prints it.
+ BC_INST_PRINT_STREAM,
+
+#if DC_ENABLED
+
+ /// dc's return; it pops an executing string off of the stack.
+ BC_INST_POP_EXEC,
+
+ /// Unconditionally execute a string.
+ BC_INST_EXECUTE,
+
+ /// Conditionally execute a string.
+ BC_INST_EXEC_COND,
+
+ /// Prints each item on the results stack, separated by newlines.
+ BC_INST_PRINT_STACK,
+
+ /// Pops everything off of the results stack.
+ BC_INST_CLEAR_STACK,
+
+ /// Pushes the current length of a register stack onto the results stack.
+ BC_INST_REG_STACK_LEN,
+
+ /// Pushes the current length of the results stack onto the results stack.
+ BC_INST_STACK_LEN,
+
+ /// Pushes a copy of the item on the top of the results stack onto the
+ /// results stack.
+ BC_INST_DUPLICATE,
+
+ /// Copies the value in a register and pushes the copy onto the results
+ /// stack.
+ BC_INST_LOAD,
+
+ /// Pops an item off of a register stack and pushes it onto the results
+ /// stack.
+ BC_INST_PUSH_VAR,
+
+ /// Pops an item off of the results stack and pushes it onto a register's
+ /// stack.
+ BC_INST_PUSH_TO_VAR,
+
+ /// Quit.
+ BC_INST_QUIT,
+
+ /// Quit executing some number of strings.
+ BC_INST_NQUIT,
+
+ /// Push the depth of the execution stack onto the stack.
+ BC_INST_EXEC_STACK_LEN,
+
+#endif // DC_ENABLED
+
+ /// Invalid instruction.
+ BC_INST_INVALID,
+
+} BcInst;
+
+/// Used by maps to identify where items are in the array.
+typedef struct BcId {
+
+ /// The name of the item.
+ char *name;
+
+ /// The index into the array where the item is.
+ size_t idx;
+
+} BcId;
+
+/// The location of a var, array, or array element.
+typedef struct BcLoc {
+
+ /// The index of the var or array.
+ size_t loc;
+
+ /// The index of the array element. Only used for array elements.
+ size_t idx;
+
+} BcLoc;
+
+/// An entry for a constant.
+typedef struct BcConst {
+
+ /// The original string as parsed from the source code.
+ char *val;
+
+ /// The last base that the constant was parsed in.
+ BcBigDig base;
+
+ /// The parsed constant.
+ BcNum num;
+
+} BcConst;
+
+/// A function. This is also used in dc, not just bc. The reason is that strings
+/// are executed in dc, and they are converted to functions in order to be
+/// executed.
+typedef struct BcFunc {
+
+ /// The bytecode instructions.
+ BcVec code;
+
+#if BC_ENABLED
+
+ /// The labels. This is a vector of indices. The index is the index into
+ /// the bytecode vector where the label is.
+ BcVec labels;
+
+ /// The autos for the function. The first items are the parameters, and the
+ /// arguments to the parameters must match the types in this vector.
+ BcVec autos;
+
+ /// The number of parameters the function takes.
+ size_t nparams;
+
+#endif // BC_ENABLED
+
+ /// The strings encountered in the function.
+ BcVec strs;
+
+ /// The constants encountered in the function.
+ BcVec consts;
+
+ /// The function's name.
+ const char *name;
+
+#if BC_ENABLED
+ /// True if the function is a void function.
+ bool voidfn;
+#endif // BC_ENABLED
+
+} BcFunc;
+
+/// Types of results that can be pushed onto the results stack.
+typedef enum BcResultType {
+
+ /// Result is a variable.
+ BC_RESULT_VAR,
+
+ /// Result is an array element.
+ BC_RESULT_ARRAY_ELEM,
+
+ /// Result is an array. This is only allowed for function arguments or
+ /// returning the length of the array.
+ BC_RESULT_ARRAY,
+
+ /// Result is a string.
+ BC_RESULT_STR,
+
+ /// Result is a temporary. This is used for the result of almost all
+ /// expressions.
+ BC_RESULT_TEMP,
+
+ /// Special casing the two below gave performance improvements.
+
+ /// Result is a 0.
+ BC_RESULT_ZERO,
+
+ /// Result is a 1. Useful for inc/dec operators.
+ BC_RESULT_ONE,
+
+#if BC_ENABLED
+
+ /// Result is the special "last" variable.
+ BC_RESULT_LAST,
+
+ /// Result is the return value of a void function.
+ BC_RESULT_VOID,
+#endif // BC_ENABLED
+
+ /// Result is the value of ibase.
+ BC_RESULT_IBASE,
+
+ /// Result is the value of obase.
+ BC_RESULT_OBASE,
+
+ /// Result is the value of scale.
+ BC_RESULT_SCALE,
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// Result is the value of seed.
+ BC_RESULT_SEED,
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+} BcResultType;
+
+/// A union to store data for various result types.
+typedef union BcResultData {
+
+ /// A number. Strings are stored here too; they are numbers with
+ /// cap == 0 && num == NULL. The string's index into the strings vector is
+ /// stored in the scale field. But this is only used for strings stored in
+ /// variables.
+ BcNum n;
+
+ /// A vector.
+ BcVec v;
+
+ /// A variable, array, or array element reference. This could also be a
+ /// string if a string is not stored in a variable (dc only).
+ BcLoc loc;
+
+} BcResultData;
+
+/// A tagged union for results.
+typedef struct BcResult {
+
+ /// The tag. The type of the result.
+ BcResultType t;
+
+ /// The data. The data for the result.
+ BcResultData d;
+
+} BcResult;
+
+/// An instruction pointer. This is how bc knows where in the bytecode vector,
+/// and which function, the current execution is.
+typedef struct BcInstPtr {
+
+ /// The index of the currently executing function in the fns vector.
+ size_t func;
+
+ /// The index into the bytecode vector of the *next* instruction.
+ size_t idx;
+
+ /// The length of the results vector when this function started executing.
+ /// This is mostly used for bc where functions should not affect the results
+ /// of their callers.
+ size_t len;
+
+} BcInstPtr;
+
+/// Types of identifiers.
+typedef enum BcType {
+
+ /// Variable.
+ BC_TYPE_VAR,
+
+ /// Array.
+ BC_TYPE_ARRAY,
+
+#if BC_ENABLED
+
+ /// Array reference.
+ BC_TYPE_REF,
+
+#endif // BC_ENABLED
+
+} BcType;
+
+#if BC_ENABLED
+/// An auto variable in bc.
+typedef struct BcAuto {
+
+ /// The index of the variable in the vars or arrs vectors.
+ size_t idx;
+
+ /// The type of the variable.
+ BcType type;
+
+} BcAuto;
+#endif // BC_ENABLED
+
+/// Forward declaration.
+struct BcProgram;
+
+/**
+ * Initializes a function.
+ * @param f The function to initialize.
+ * @param name The name of the function. The string is assumed to be owned by
+ * some other entity.
+ */
+void bc_func_init(BcFunc *f, const char* name);
+
+/**
+ * Inserts an auto into the function.
+ * @param f The function to insert into.
+ * @param p The program. This is to search for the variable or array name.
+ * @param name The name of the auto to insert.
+ * @param type The type of the auto.
+ * @param line The line in the source code where the insert happened. This is
+ * solely for error reporting.
+ */
+void bc_func_insert(BcFunc *f, struct BcProgram* p, char* name,
+ BcType type, size_t line);
+
+/**
+ * Resets a function in preparation for it to be reused. This can happen in bc
+ * because it is a dynamic language and functions can be redefined.
+ * @param f The functio to reset.
+ */
+void bc_func_reset(BcFunc *f);
+
+#ifndef NDEBUG
+/**
+ * Frees a function. This is a destructor. This is only used in debug builds
+ * because all functions are freed at exit. We free them in debug builds to
+ * check for memory leaks.
+ * @param func The function to free as a void pointer.
+ */
+void bc_func_free(void *func);
+#endif // NDEBUG
+
+/**
+ * Initializes an array, which is the array type in bc and dc source code. Since
+ * variables and arrays are both arrays (see the development manual,
+ * manuals/development.md#execution, for more information), the @a nums
+ * parameter tells bc whether to initialize an array of numbers or an array of
+ * arrays of numbers. If the latter, it does a recursive call with nums set to
+ * true.
+ * @param a The array to initialize.
+ * @param nums True if the array should be for numbers, false if it should be
+ * for vectors.
+ */
+void bc_array_init(BcVec *a, bool nums);
+
+/**
+ * Copies an array to another array. This is used to do pass arrays to functions
+ * that do not take references to arrays. The arrays are passed entirely by
+ * value, which means that they need to be copied.
+ * @param d The destination array.
+ * @param s The source array.
+ */
+void bc_array_copy(BcVec *d, const BcVec *s);
+
+/**
+ * Frees a string stored in a function. This is a destructor.
+ * @param string The string to free as a void pointer.
+ */
+void bc_string_free(void *string);
+
+/**
+ * Frees a constant stored in a function. This is a destructor.
+ * @param constant The constant to free as a void pointer.
+ */
+void bc_const_free(void *constant);
+
+/**
+ * Clears a result. It sets the type to BC_RESULT_TEMP and clears the union by
+ * clearing the BcNum in the union. This is to ensure that bc does not use
+ * uninitialized data.
+ * @param r The result to clear.
+ */
+void bc_result_clear(BcResult *r);
+
+/**
+ * Copies a result into another. This is done for things like duplicating the
+ * top of the results stack or copying the result of an assignment to put back
+ * on the results stack.
+ * @param d The destination result.
+ * @param src The source result.
+ */
+void bc_result_copy(BcResult *d, BcResult *src);
+
+/**
+ * Frees a result. This is a destructor.
+ * @param result The result to free as a void pointer.
+ */
+void bc_result_free(void *result);
+
+/**
+ * Expands an array to @a len. This can happen because in bc, you do not have to
+ * explicitly initialize elements of an array. If you access an element that is
+ * not initialized, the array is expanded to fit it, and all missing elements
+ * are initialized to 0 if they are numbers, or arrays with one element of 0.
+ * This function does that expansion.
+ * @param a The array to expand.
+ * @param len The length to expand to.
+ */
+void bc_array_expand(BcVec *a, size_t len);
+
+/**
+ * Compare two BcId's and return the result. Since they are just comparing the
+ * names in the BcId, I return the result from strcmp() exactly. This is used by
+ * maps in their binary search.
+ * @param e1 The first id.
+ * @param e2 The second id.
+ * @return The result of strcmp() on the BcId's names.
+ */
+int bc_id_cmp(const BcId *e1, const BcId *e2);
+
+#if BC_ENABLED
+
+/**
+ * Returns non-zero if the bytecode instruction i is an assignment instruction.
+ * @param i The instruction to test.
+ * @return Non-zero if i is an assignment instruction, zero otherwise.
+ */
+#define BC_INST_IS_ASSIGN(i) \
+ ((i) == BC_INST_ASSIGN || (i) == BC_INST_ASSIGN_NO_VAL)
+
+/**
+ * Returns true if the bytecode instruction @a i requires the value to be
+ * returned for use.
+ * @param i The instruction to test.
+ * @return True if @a i requires the value to be returned for use, false
+ * otherwise.
+ */
+#define BC_INST_USE_VAL(i) ((i) <= BC_INST_ASSIGN)
+
+#else // BC_ENABLED
+
+/**
+ * Returns non-zero if the bytecode instruction i is an assignment instruction.
+ * @param i The instruction to test.
+ * @return Non-zero if i is an assignment instruction, zero otherwise.
+ */
+#define BC_INST_IS_ASSIGN(i) ((i) == BC_INST_ASSIGN_NO_VAL)
+
+/**
+ * Returns true if the bytecode instruction @a i requires the value to be
+ * returned for use.
+ * @param i The instruction to test.
+ * @return True if @a i requires the value to be returned for use, false
+ * otherwise.
+ */
+#define BC_INST_USE_VAL(i) (false)
+
+#endif // BC_ENABLED
+
+#if BC_DEBUG_CODE
+/// Reference to string names for all of the instructions. For debugging.
+extern const char* bc_inst_names[];
+#endif // BC_DEBUG_CODE
+
+/// References to the names of the main and read functions.
+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..0e7af1742001
--- /dev/null
+++ b/contrib/bc/include/lex.h
@@ -0,0 +1,586 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for 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>
+
+// Two convencience macros for throwing errors in lex code. They take care of
+// plumbing like passing in the current line the lexer is on.
+#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__))
+
+// BC_LEX_NEG_CHAR returns the char that corresponds to negative for the
+// current calculator.
+//
+// BC_LEX_LAST_NUM_CHAR returns the char that corresponds to the last valid
+// char for numbers. In bc and dc, capital letters are part of numbers, to a
+// point. (dc only goes up to hex, so its last valid char is 'F'.)
+#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
+
+/**
+ * Returns true if c is a valid number character.
+ * @param c The char to check.
+ * @param pt If a decimal point has already been seen.
+ * @param int_only True if the number is expected to be an int only, false if
+ * non-integers are allowed.
+ * @return True if @a c is a valid number character.
+ */
+#define BC_LEX_NUM_CHAR(c, pt, int_only) \
+ (isdigit(c) != 0 || ((c) >= 'A' && (c) <= BC_LEX_LAST_NUM_CHAR) || \
+ ((c) == '.' && !(pt) && !(int_only)))
+
+/// An enum of lex token types.
+typedef enum BcLexType {
+
+ /// End of file.
+ BC_LEX_EOF,
+
+ /// Marker for invalid tokens, used by bc and dc for const data.
+ BC_LEX_INVALID,
+
+#if BC_ENABLED
+
+ /// Increment operator.
+ BC_LEX_OP_INC,
+
+ /// Decrement operator.
+ BC_LEX_OP_DEC,
+
+#endif // BC_ENABLED
+
+ /// BC_LEX_NEG is not used in lexing; it is only for parsing. The lexer
+ /// marks all '-' characters as BC_LEX_OP_MINUS, but the parser needs to be
+ /// able to distinguish them.
+ BC_LEX_NEG,
+
+ /// Boolean not.
+ BC_LEX_OP_BOOL_NOT,
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// Truncation operator.
+ BC_LEX_OP_TRUNC,
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// Power operator.
+ BC_LEX_OP_POWER,
+
+ /// Multiplication operator.
+ BC_LEX_OP_MULTIPLY,
+
+ /// Division operator.
+ BC_LEX_OP_DIVIDE,
+
+ /// Modulus operator.
+ BC_LEX_OP_MODULUS,
+
+ /// Addition operator.
+ BC_LEX_OP_PLUS,
+
+ /// Subtraction operator.
+ BC_LEX_OP_MINUS,
+
+#if BC_ENABLE_EXTRA_MATH
+ /// Places (truncate or extend) operator.
+ BC_LEX_OP_PLACES,
+
+ /// Left (decimal) shift operator.
+ BC_LEX_OP_LSHIFT,
+
+ /// Right (decimal) shift operator.
+ BC_LEX_OP_RSHIFT,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// Equal operator.
+ BC_LEX_OP_REL_EQ,
+
+ /// Less than or equal operator.
+ BC_LEX_OP_REL_LE,
+
+ /// Greater than or equal operator.
+ BC_LEX_OP_REL_GE,
+
+ /// Not equal operator.
+ BC_LEX_OP_REL_NE,
+
+ /// Less than operator.
+ BC_LEX_OP_REL_LT,
+
+ /// Greater than operator.
+ BC_LEX_OP_REL_GT,
+
+ /// Boolean or operator.
+ BC_LEX_OP_BOOL_OR,
+
+ /// Boolean and operator.
+ BC_LEX_OP_BOOL_AND,
+
+#if BC_ENABLED
+ /// Power assignment operator.
+ BC_LEX_OP_ASSIGN_POWER,
+
+ /// Multiplication assignment operator.
+ BC_LEX_OP_ASSIGN_MULTIPLY,
+
+ /// Division assignment operator.
+ BC_LEX_OP_ASSIGN_DIVIDE,
+
+ /// Modulus assignment operator.
+ BC_LEX_OP_ASSIGN_MODULUS,
+
+ /// Addition assignment operator.
+ BC_LEX_OP_ASSIGN_PLUS,
+
+ /// Subtraction assignment operator.
+ BC_LEX_OP_ASSIGN_MINUS,
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// Places (truncate or extend) assignment operator.
+ BC_LEX_OP_ASSIGN_PLACES,
+
+ /// Left (decimal) shift assignment operator.
+ BC_LEX_OP_ASSIGN_LSHIFT,
+
+ /// Right (decimal) shift assignment operator.
+ BC_LEX_OP_ASSIGN_RSHIFT,
+
+#endif // BC_ENABLE_EXTRA_MATH
+#endif // BC_ENABLED
+
+ /// Assignment operator.
+ BC_LEX_OP_ASSIGN,
+
+ /// Newline.
+ BC_LEX_NLINE,
+
+ /// Whitespace.
+ BC_LEX_WHITESPACE,
+
+ /// Left parenthesis.
+ BC_LEX_LPAREN,
+
+ /// Right parenthesis.
+ BC_LEX_RPAREN,
+
+ /// Left bracket.
+ BC_LEX_LBRACKET,
+
+ /// Comma.
+ BC_LEX_COMMA,
+
+ /// Right bracket.
+ BC_LEX_RBRACKET,
+
+ /// Left brace.
+ BC_LEX_LBRACE,
+
+ /// Semicolon.
+ BC_LEX_SCOLON,
+
+ /// Right brace.
+ BC_LEX_RBRACE,
+
+ /// String.
+ BC_LEX_STR,
+
+ /// Identifier/name.
+ BC_LEX_NAME,
+
+ /// Constant number.
+ BC_LEX_NUMBER,
+
+ // These keywords are in the order they are in for a reason. Don't change
+ // the order unless you want a bunch of weird failures in the test suite.
+ // In fact, almost all of these tokens are in a specific order for a reason.
+
+#if BC_ENABLED
+
+ /// bc auto keyword.
+ BC_LEX_KW_AUTO,
+
+ /// bc break keyword.
+ BC_LEX_KW_BREAK,
+
+ /// bc continue keyword.
+ BC_LEX_KW_CONTINUE,
+
+ /// bc define keyword.
+ BC_LEX_KW_DEFINE,
+
+ /// bc for keyword.
+ BC_LEX_KW_FOR,
+
+ /// bc if keyword.
+ BC_LEX_KW_IF,
+
+ /// bc limits keyword.
+ BC_LEX_KW_LIMITS,
+
+ /// bc return keyword.
+ BC_LEX_KW_RETURN,
+
+ /// bc while keyword.
+ BC_LEX_KW_WHILE,
+
+ /// bc halt keyword.
+ BC_LEX_KW_HALT,
+
+ /// bc last keyword.
+ BC_LEX_KW_LAST,
+
+#endif // BC_ENABLED
+
+ /// bc ibase keyword.
+ BC_LEX_KW_IBASE,
+
+ /// bc obase keyword.
+ BC_LEX_KW_OBASE,
+
+ /// bc scale keyword.
+ BC_LEX_KW_SCALE,
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// bc seed keyword.
+ BC_LEX_KW_SEED,
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// bc length keyword.
+ BC_LEX_KW_LENGTH,
+
+ /// bc print keyword.
+ BC_LEX_KW_PRINT,
+
+ /// bc sqrt keyword.
+ BC_LEX_KW_SQRT,
+
+ /// bc abs keyword.
+ BC_LEX_KW_ABS,
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// bc irand keyword.
+ BC_LEX_KW_IRAND,
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// bc asciffy keyword.
+ BC_LEX_KW_ASCIIFY,
+
+ /// bc modexp keyword.
+ BC_LEX_KW_MODEXP,
+
+ /// bc divmod keyword.
+ BC_LEX_KW_DIVMOD,
+
+ /// bc quit keyword.
+ BC_LEX_KW_QUIT,
+
+ /// bc read keyword.
+ BC_LEX_KW_READ,
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// bc rand keyword.
+ BC_LEX_KW_RAND,
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// bc maxibase keyword.
+ BC_LEX_KW_MAXIBASE,
+
+ /// bc maxobase keyword.
+ BC_LEX_KW_MAXOBASE,
+
+ /// bc maxscale keyword.
+ BC_LEX_KW_MAXSCALE,
+
+#if BC_ENABLE_EXTRA_MATH
+ /// bc maxrand keyword.
+ BC_LEX_KW_MAXRAND,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// bc line_length keyword.
+ BC_LEX_KW_LINE_LENGTH,
+
+#if BC_ENABLED
+
+ /// bc global_stacks keyword.
+ BC_LEX_KW_GLOBAL_STACKS,
+
+#endif // BC_ENABLED
+
+ /// bc leading_zero keyword.
+ BC_LEX_KW_LEADING_ZERO,
+
+ /// bc stream keyword.
+ BC_LEX_KW_STREAM,
+
+ /// bc else keyword.
+ BC_LEX_KW_ELSE,
+
+#if DC_ENABLED
+
+ /// A special token for dc to calculate equal without a register.
+ BC_LEX_EQ_NO_REG,
+
+ /// Colon (array) operator.
+ BC_LEX_COLON,
+
+ /// Execute command.
+ BC_LEX_EXECUTE,
+
+ /// Print stack command.
+ BC_LEX_PRINT_STACK,
+
+ /// Clear stack command.
+ BC_LEX_CLEAR_STACK,
+
+ /// Register stack level command.
+ BC_LEX_REG_STACK_LEVEL,
+
+ /// Main stack level command.
+ BC_LEX_STACK_LEVEL,
+
+ /// Duplicate command.
+ BC_LEX_DUPLICATE,
+
+ /// Swap (reverse) command.
+ BC_LEX_SWAP,
+
+ /// Pop (remove) command.
+ BC_LEX_POP,
+
+ /// Store ibase command.
+ BC_LEX_STORE_IBASE,
+
+ /// Store obase command.
+ BC_LEX_STORE_OBASE,
+
+ /// Store scale command.
+ BC_LEX_STORE_SCALE,
+
+#if BC_ENABLE_EXTRA_MATH
+ /// Store seed command.
+ BC_LEX_STORE_SEED,
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// Load variable onto stack command.
+ BC_LEX_LOAD,
+
+ /// Pop off of variable stack onto results stack command.
+ BC_LEX_LOAD_POP,
+
+ /// Push onto variable stack command.
+ BC_LEX_STORE_PUSH,
+
+ /// Print with pop command.
+ BC_LEX_PRINT_POP,
+
+ /// Parameterized quit command.
+ BC_LEX_NQUIT,
+
+ /// Execution stack depth command.
+ BC_LEX_EXEC_STACK_LENGTH,
+
+ /// Scale of number command. This is needed specifically for dc because bc
+ /// parses the scale function in parts.
+ BC_LEX_SCALE_FACTOR,
+
+ /// Array length command. This is needed specifically for dc because bc
+ /// just reuses its length keyword.
+ BC_LEX_ARRAY_LENGTH,
+
+#endif // DC_ENABLED
+
+} BcLexType;
+
+struct BcLex;
+
+/**
+ * A function pointer to call when another token is needed. Mostly called by the
+ * parser.
+ * @param l The lexer.
+ */
+typedef void (*BcLexNext)(struct BcLex* l);
+
+/// The lexer.
+typedef struct BcLex {
+
+ /// A pointer to the text to lex.
+ const char *buf;
+
+ /// The current index into buf.
+ size_t i;
+
+ /// The current line.
+ size_t line;
+
+ /// The length of buf.
+ size_t len;
+
+ /// The current token.
+ BcLexType t;
+
+ /// The previous token.
+ BcLexType last;
+
+ /// A string to store extra data for tokens. For example, the @a BC_LEX_STR
+ /// token really needs to store the actual string, and numbers also need the
+ /// string.
+ BcVec str;
+
+ /// If this is true, the lexer is processing stdin and can ask for more data
+ /// if a string or comment are not properly terminated.
+ bool is_stdin;
+
+} BcLex;
+
+/**
+ * Initializes a lexer.
+ * @param l The lexer to initialize.
+ */
+void bc_lex_init(BcLex *l);
+
+/**
+ * Frees a lexer. This is not guarded by #ifndef NDEBUG because a separate
+ * parser is created at runtime to parse read() expressions and dc strings, and
+ * that parser needs a lexer.
+ * @param l The lexer to free.
+ */
+void bc_lex_free(BcLex *l);
+
+/**
+ * Sets the filename that the lexer will be lexing.
+ * @param l The lexer.
+ * @param file The filename that the lexer will lex.
+ */
+void bc_lex_file(BcLex *l, const char *file);
+
+/**
+ * Sets the text the lexer will lex.
+ * @param l The lexer.
+ * @param text The text to lex.
+ * @param is_stdin True if the text is from stdin, false otherwise.
+ */
+void bc_lex_text(BcLex *l, const char *text, bool is_stdin);
+
+/**
+ * Generic next function for the parser to call. It takes care of calling the
+ * correct @a BcLexNext function and consuming whitespace.
+ * @param l The lexer.
+ */
+void bc_lex_next(BcLex *l);
+
+/**
+ * Lexes a line comment (one beginning with '#' and going to a newline).
+ * @param l The lexer.
+ */
+void bc_lex_lineComment(BcLex *l);
+
+/**
+ * Lexes a general comment (C-style comment).
+ * @param l The lexer.
+ */
+void bc_lex_comment(BcLex *l);
+
+/**
+ * Lexes whitespace, finding as much as possible.
+ * @param l The lexer.
+ */
+void bc_lex_whitespace(BcLex *l);
+
+/**
+ * Lexes a number that begins with char @a start. This takes care of parsing
+ * numbers in scientific and engineering notations.
+ * @param l The lexer.
+ * @param start The starting char of the number. To detect a number and call
+ * this function, the lexer had to eat the first char. It fixes
+ * that by passing it in.
+ */
+void bc_lex_number(BcLex *l, char start);
+
+/**
+ * Lexes a name/identifier.
+ * @param l The lexer.
+ */
+void bc_lex_name(BcLex *l);
+
+/**
+ * Lexes common whitespace characters.
+ * @param l The lexer.
+ * @param c The character to lex.
+ */
+void bc_lex_commonTokens(BcLex *l, char c);
+
+/**
+ * Throws a parse error because char @a c was invalid.
+ * @param l The lexer.
+ * @param c The problem character.
+ */
+void bc_lex_invalidChar(BcLex *l, char c);
+
+/**
+ * Reads a line from stdin and puts it into the lexer's buffer.
+ * @param l The lexer.
+ */
+bool bc_lex_readLine(BcLex *l);
+
+#endif // BC_LEX_H
diff --git a/contrib/bc/include/library.h b/contrib/bc/include/library.h
new file mode 100644
index 000000000000..8a055eb81063
--- /dev/null
+++ b/contrib/bc/include/library.h
@@ -0,0 +1,239 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The private header for the bc library.
+ *
+ */
+
+#ifndef LIBBC_PRIVATE_H
+#define LIBBC_PRIVATE_H
+
+#include <bcl.h>
+
+#include <num.h>
+
+/**
+ * A header for functions that need to lock and setjmp(). It also sets the
+ * variable that tells bcl that it is running.
+ * @param l The label to jump to on error.
+ */
+#define BC_FUNC_HEADER_LOCK(l) \
+ do { \
+ BC_SIG_LOCK; \
+ BC_SETJMP_LOCKED(l); \
+ vm.err = BCL_ERROR_NONE; \
+ vm.running = 1; \
+ } while (0)
+
+/**
+ * A footer to unlock and stop the jumping if an error happened. It also sets
+ * the variable that tells bcl that it is running.
+ * @param e The error variable to set.
+ */
+#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)
+
+/**
+ * A header that sets a jump and sets running.
+ * @param l The label to jump to on error.
+ */
+#define BC_FUNC_HEADER(l) \
+ do { \
+ BC_SETJMP(l); \
+ vm.err = BCL_ERROR_NONE; \
+ vm.running = 1; \
+ } while (0)
+
+/**
+ * A header that assumes that signals are already locked. It sets a jump and
+ * running.
+ * @param l The label to jump to on error.
+ */
+#define BC_FUNC_HEADER_INIT(l) \
+ do { \
+ BC_SETJMP_LOCKED(l); \
+ vm.err = BCL_ERROR_NONE; \
+ vm.running = 1; \
+ } while (0)
+
+/**
+ * A footer for functions that do not return an error code. It clears running
+ * and unlocks the signals. It also stops the jumping.
+ */
+#define BC_FUNC_FOOTER_NO_ERR \
+ do { \
+ vm.running = 0; \
+ BC_UNSETJMP; \
+ BC_LONGJMP_STOP; \
+ vm.sig_lock = 0; \
+ } while (0)
+
+/**
+ * A footer for functions that *do* return an error code. It clears running and
+ * unlocks the signals. It also stops the jumping.
+ * @param e The error variable to set.
+ */
+#define BC_FUNC_FOOTER(e) \
+ do { \
+ e = vm.err; \
+ BC_FUNC_FOOTER_NO_ERR; \
+ } while (0)
+
+/**
+ * A footer that sets up n based the value of e and sets up the return value in
+ * idx.
+ * @param c The context.
+ * @param e The error.
+ * @param n The number.
+ * @param idx The idx to set as the return value.
+ */
+#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)
+
+/**
+ * A header to check the context and return an error encoded in a number if it
+ * is bad.
+ * @param c The context.
+ */
+#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)
+
+
+/**
+ * A header to check the context and return an error directly if it is bad.
+ * @param c The context.
+ */
+#define BC_CHECK_CTXT_ERR(c) \
+ do { \
+ c = bcl_context(); \
+ if (BC_ERR(c == NULL)) { \
+ return BCL_ERROR_INVALID_CONTEXT; \
+ } \
+ } while (0)
+
+/**
+ * A header to check the context and abort if it is bad.
+ * @param c The context.
+ */
+#define BC_CHECK_CTXT_ASSERT(c) \
+ do { \
+ c = bcl_context(); \
+ assert(c != NULL); \
+ } while (0)
+
+/**
+ * A header to check the number in the context and return an error encoded as a
+ * @param c The context.
+ * number if it is bad.
+ * @param n The BclNumber.
+ */
+#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)
+
+/**
+ * A header to check the number in the context and return an error directly if
+ * it is bad.
+ * @param c The context.
+ * @param n The BclNumber.
+ */
+#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)
+
+/**
+ * Turns a BclNumber into a BcNum.
+ * @param c The context.
+ * @param n The BclNumber.
+ */
+#define BC_NUM(c, n) ((BcNum*) bc_vec_item(&(c)->nums, (n).i))
+
+/**
+ * Frees a BcNum for bcl. This is a destructor.
+ * @param num The BcNum to free, as a void pointer.
+ */
+void bcl_num_destruct(void *num);
+
+/// The actual context struct.
+typedef struct BclCtxt {
+
+ /// The context's scale.
+ size_t scale;
+
+ /// The context's ibase.
+ size_t ibase;
+
+ /// The context's obase.
+ size_t obase;
+
+ /// A vector of BcNum numbers.
+ BcVec nums;
+
+ /// A vector of BclNumbers. These are the indices in nums that are currently
+ /// not used (because they were freed).
+ 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..bfd360b520f3
--- /dev/null
+++ b/contrib/bc/include/num.h
@@ -0,0 +1,860 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for 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
+
+/// Everything in bc is base 10..
+#define BC_BASE (10)
+
+/// Alias.
+typedef unsigned long ulong;
+
+/// This is here because BcBigDig came first, but when I created bcl, it's
+/// definition has to be defined first.
+typedef BclBigDig BcBigDig;
+
+#if BC_LONG_BIT >= 64
+
+/// The biggest number held by a BcBigDig.
+#define BC_NUM_BIGDIG_MAX ((BcBigDig) UINT64_MAX)
+
+/// The number of decimal digits in one limb.
+#define BC_BASE_DIGS (9)
+
+/// The max number + 1 that one limb can hold.
+#define BC_BASE_POW (1000000000)
+
+/// An alias for portability.
+#define BC_NUM_BIGDIG_C UINT64_C
+
+/// The actual limb type.
+typedef int_least32_t BcDig;
+
+#elif BC_LONG_BIT >= 32
+
+/// The biggest number held by a BcBigDig.
+#define BC_NUM_BIGDIG_MAX ((BcBigDig) UINT32_MAX)
+
+/// The number of decimal digits in one limb.
+#define BC_BASE_DIGS (4)
+
+/// The max number + 1 that one limb can hold.
+#define BC_BASE_POW (10000)
+
+/// An alias for portability.
+#define BC_NUM_BIGDIG_C UINT32_C
+
+/// The actual limb type.
+typedef int_least16_t BcDig;
+
+#else
+
+/// LONG_BIT must be at least 32 on POSIX. We depend on that.
+#error BC_LONG_BIT must be at least 32
+
+#endif // BC_LONG_BIT >= 64
+
+/// The default (and minimum) number of limbs when allocating a number.
+#define BC_NUM_DEF_SIZE (8)
+
+/// The actual number struct. This is where the magic happens.
+typedef struct BcNum {
+
+ /// The limb array. It is restrict because *no* other item should own the
+ /// array. For more information, see the development manual
+ /// (manuals/development.md#numbers).
+ BcDig *restrict num;
+
+ /// The number of limbs before the decimal (radix) point. This also stores
+ /// the negative bit in the least significant bit since it uses at least two
+ /// bits less than scale. It is also used less than scale. See the
+ /// development manual (manuals/development.md#numbers) for more info.
+ size_t rdx;
+
+ /// The actual scale of the number. This is different from rdx because there
+ /// are multiple digits in one limb, and in the last limb, only some of the
+ /// digits may be part of the scale. However, scale must always match rdx
+ /// (except when the number is 0), or there is a bug. For more information,
+ /// see the development manual (manuals/development.md#numbers).
+ size_t scale;
+
+ /// The number of valid limbs in the array. If this is 0, then the number is
+ /// 0 as well.
+ size_t len;
+
+ /// The capacity of the limbs array. This is how many limbs the number could
+ /// expand to without reallocation.
+ size_t cap;
+
+} BcNum;
+
+#if BC_ENABLE_EXTRA_MATH
+
+// Forward declaration
+struct BcRNG;
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+/// The minimum obase.
+#define BC_NUM_MIN_BASE (BC_NUM_BIGDIG_C(2))
+
+/// The maximum ibase allowed by POSIX.
+#define BC_NUM_MAX_POSIX_IBASE (BC_NUM_BIGDIG_C(16))
+
+/// The actual ibase supported by this implementation.
+#define BC_NUM_MAX_IBASE (BC_NUM_BIGDIG_C(36))
+
+/// The max base allowed by bc_num_parseChar().
+#define BC_NUM_MAX_LBASE (BC_NUM_BIGDIG_C('Z' + BC_BASE + 1))
+
+/// The default number of characters to print before a backslash newline.
+#define BC_NUM_PRINT_WIDTH (BC_NUM_BIGDIG_C(69))
+
+/// The base for printing streams from numbers.
+#define BC_NUM_STREAM_BASE (256)
+
+// This sets a default for the Karatsuba length.
+#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)
+
+/**
+ * Returns non-zero if the BcNum @a n is non-zero.
+ * @param n The number to test.
+ * @return Non-zero if @a n is non-zero, zero otherwise.
+ */
+#define BC_NUM_NONZERO(n) ((n)->len)
+
+/**
+ * Returns true if the BcNum @a n is zero.
+ * @param n The number to test.
+ * @return True if @a n is zero, false otherwise.
+ */
+#define BC_NUM_ZERO(n) (!BC_NUM_NONZERO(n))
+
+/**
+ * Returns true if the BcNum @a n is one with no scale.
+ * @param n The number to test.
+ * @return True if @a n equals 1 with no scale, false otherwise.
+ */
+#define BC_NUM_ONE(n) ((n)->len == 1 && (n)->rdx == 0 && (n)->num[0] == 1)
+
+/**
+ * Converts the letter @a c into a number.
+ * @param c The letter to convert.
+ * @return The number corresponding to the letter.
+ */
+#define BC_NUM_NUM_LETTER(c) ((c) - 'A' + BC_BASE)
+
+/// The number of allocations done by bc_num_k(). If you change the number of
+/// allocations, you must change this. This is done in order to allocate them
+/// all as one allocation and just give them all pointers to different parts.
+/// Works pretty well, but you have to be careful.
+#define BC_NUM_KARATSUBA_ALLOCS (6)
+
+/**
+ * Rounds @a s (scale) up to the next power of BC_BASE_DIGS. This also check for
+ * overflow and gives a fatal error if that happens because we just can't go
+ * over the limits we have imposed.
+ * @param s The scale to round up.
+ * @return @a s rounded up to the next power of BC_BASE_DIGS.
+ */
+#define BC_NUM_ROUND_POW(s) (bc_vm_growSize((s), BC_BASE_DIGS - 1))
+
+/**
+ * Returns the equivalent rdx for the scale @a s.
+ * @param s The scale to convert.
+ * @return The rdx for @a s.
+ */
+#define BC_NUM_RDX(s) (BC_NUM_ROUND_POW(s) / BC_BASE_DIGS)
+
+/**
+ * Returns the actual rdx of @a n. (It removes the negative bit.)
+ * @param n The number.
+ * @return The real rdx of @a n.
+ */
+#define BC_NUM_RDX_VAL(n) ((n)->rdx >> 1)
+
+/**
+ * Returns the actual rdx of @a n, where @a n is not a pointer. (It removes the
+ * negative bit.)
+ * @param n The number.
+ * @return The real rdx of @a n.
+ */
+#define BC_NUM_RDX_VAL_NP(n) ((n).rdx >> 1)
+
+/**
+ * Sets the rdx of @a n to @a v.
+ * @param n The number.
+ * @param v The value to set the rdx to.
+ */
+#define BC_NUM_RDX_SET(n, v) \
+ ((n)->rdx = (((v) << 1) | ((n)->rdx & (BcBigDig) 1)))
+
+/**
+ * Sets the rdx of @a n to @a v, where @a n is not a pointer.
+ * @param n The number.
+ * @param v The value to set the rdx to.
+ */
+#define BC_NUM_RDX_SET_NP(n, v) \
+ ((n).rdx = (((v) << 1) | ((n).rdx & (BcBigDig) 1)))
+
+/**
+ * Sets the rdx of @a n to @a v and the negative bit to @a neg.
+ * @param n The number.
+ * @param v The value to set the rdx to.
+ * @param neg The value to set the negative bit to.
+ */
+#define BC_NUM_RDX_SET_NEG(n, v, neg) \
+ ((n)->rdx = (((v) << 1) | (neg)))
+
+/**
+ * Returns true if the rdx and scale for @a n match.
+ * @param n The number to test.
+ * @return True if the rdx and scale of @a n match, false otherwise.
+ */
+#define BC_NUM_RDX_VALID(n) \
+ (BC_NUM_ZERO(n) || BC_NUM_RDX_VAL(n) * BC_BASE_DIGS >= (n)->scale)
+
+/**
+ * Returns true if the rdx and scale for @a n match, where @a n is not a
+ * pointer.
+ * @param n The number to test.
+ * @return True if the rdx and scale of @a n match, false otherwise.
+ */
+#define BC_NUM_RDX_VALID_NP(n) \
+ ((!(n).len) || BC_NUM_RDX_VAL_NP(n) * BC_BASE_DIGS >= (n).scale)
+
+/**
+ * Returns true if @a n is negative, false otherwise.
+ * @param n The number to test.
+ * @return True if @a n is negative, false otherwise.
+ */
+#define BC_NUM_NEG(n) ((n)->rdx & ((BcBigDig) 1))
+
+/**
+ * Returns true if @a n is negative, false otherwise, where @a n is not a
+ * pointer.
+ * @param n The number to test.
+ * @return True if @a n is negative, false otherwise.
+ */
+#define BC_NUM_NEG_NP(n) ((n).rdx & ((BcBigDig) 1))
+
+/**
+ * Clears the negative bit on @a n.
+ * @param n The number.
+ */
+#define BC_NUM_NEG_CLR(n) ((n)->rdx &= ~((BcBigDig) 1))
+
+/**
+ * Clears the negative bit on @a n, where @a n is not a pointer.
+ * @param n The number.
+ */
+#define BC_NUM_NEG_CLR_NP(n) ((n).rdx &= ~((BcBigDig) 1))
+
+/**
+ * Sets the negative bit on @a n.
+ * @param n The number.
+ */
+#define BC_NUM_NEG_SET(n) ((n)->rdx |= ((BcBigDig) 1))
+
+/**
+ * Toggles the negative bit on @a n.
+ * @param n The number.
+ */
+#define BC_NUM_NEG_TGL(n) ((n)->rdx ^= ((BcBigDig) 1))
+
+/**
+ * Toggles the negative bit on @a n, where @a n is not a pointer.
+ * @param n The number.
+ */
+#define BC_NUM_NEG_TGL_NP(n) ((n).rdx ^= ((BcBigDig) 1))
+
+/**
+ * Returns the rdx val for @a n if the negative bit is set to @a v.
+ * @param n The number.
+ * @param v The value for the negative bit.
+ * @return The value of the rdx of @a n if the negative bit were set to @a v.
+ */
+#define BC_NUM_NEG_VAL(n, v) (((n)->rdx & ~((BcBigDig) 1)) | (v))
+
+/**
+ * Returns the rdx val for @a n if the negative bit is set to @a v, where @a n
+ * is not a pointer.
+ * @param n The number.
+ * @param v The value for the negative bit.
+ * @return The value of the rdx of @a n if the negative bit were set to @a v.
+ */
+#define BC_NUM_NEG_VAL_NP(n, v) (((n).rdx & ~((BcBigDig) 1)) | (v))
+
+/**
+ * Returns the size, in bytes, of limb array with @a n limbs.
+ * @param n The number.
+ * @return The size, in bytes, of a limb array with @a n limbs.
+ */
+#define BC_NUM_SIZE(n) ((n) * sizeof(BcDig))
+
+// These are for debugging only.
+#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
+
+/**
+ * A function type for binary operators.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+typedef void (*BcNumBinaryOp)(BcNum* a, BcNum* b, BcNum* c, size_t scale);
+
+/**
+ * A function type for binary operators *after* @a c has been properly
+ * allocated. At this point, *nothing* should be pointing to @a c (in any way
+ * that matters, anyway).
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ */
+typedef void (*BcNumBinOp)(BcNum* a, BcNum* b, BcNum* restrict c, size_t scale);
+
+/**
+ * A function type for getting the allocation size needed for a binary operator.
+ * Any function used for this *must* return enough space for *all* possible
+ * invocations of the operator.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param scale The current scale.
+ * @return The size of allocation needed for the result of the operator
+ * with @a a, @a b, and @a scale.
+ */
+typedef size_t (*BcNumBinaryOpReq)(const BcNum* a, const BcNum* b,
+ size_t scale);
+
+/**
+ * A function type for printing a "digit." Functions of this type will print one
+ * digit in a number. Digits are printed differently based on the base, which is
+ * why there is more than one implementation of this function type.
+ * @param n The "digit" to print.
+ * @param len The "length" of the digit, or number of characters that will
+ * need to be printed for the digit.
+ * @param rdx True if a decimal (radix) point should be printed.
+ * @param bslash True if a backslash+newline should be printed if the character
+ * limit for the line is reached, false otherwise.
+ */
+typedef void (*BcNumDigitOp)(size_t n, size_t len, bool rdx, bool bslash);
+
+/**
+ * A function type to run an operator on @a a and @a b and store the result in
+ * @a a. This is used in karatsuba for faster adds and subtracts at the end.
+ * @param a The first parameter and return value.
+ * @param b The second parameter.
+ * @param len The minimum length of both arrays.
+ */
+typedef void (*BcNumShiftAddOp)(BcDig* restrict a, const BcDig* restrict b,
+ size_t len);
+
+/**
+ * Initializes @a n with @a req limbs in its array.
+ * @param n The number to initialize.
+ * @param req The number of limbs @a n must have in its limb array.
+ */
+void bc_num_init(BcNum *restrict n, size_t req);
+
+/**
+ * Initializes (sets up) @a n with the preallocated limb array @a num that has
+ * size @a cap. This is called by @a bc_num_init(), but it is also used by parts
+ * of bc that use statically allocated limb arrays.
+ * @param n The number to initialize.
+ * @param num The preallocated limb array.
+ * @param cap The capacity of @a num.
+ */
+void bc_num_setup(BcNum *restrict n, BcDig *restrict num, size_t cap);
+
+/**
+ * Copies @a s into @a d. This does a deep copy and requires that @a d is
+ * already a valid and allocated BcNum.
+ * @param d The destination BcNum.
+ * @param s The source BcNum.
+ */
+void bc_num_copy(BcNum *d, const BcNum *s);
+
+/**
+ * Creates @a d and copies @a s into @a d. This does a deep copy and requires
+ * that @a d is *not* a valid or allocated BcNum.
+ * @param d The destination BcNum.
+ * @param s The source BcNum.
+ */
+void bc_num_createCopy(BcNum *d, const BcNum *s);
+
+/**
+ * Creates (initializes) @a n and sets its value to the equivalent of @a val.
+ * @a n must *not* be a valid or preallocated BcNum.
+ * @param n The number to initialize and set.
+ * @param val The value to set @a n's value to.
+ */
+void bc_num_createFromBigdig(BcNum *restrict n, BcBigDig val);
+
+/**
+ * Makes @a n valid for holding strings. @a n must *not* be allocated; this
+ * simply clears some fields, including setting the num field to NULL.
+ * @param n The number to clear.
+ */
+void bc_num_clear(BcNum *restrict n);
+
+/**
+ * Frees @a num, which is a BcNum as a void pointer. This is a destructor.
+ * @param num The BcNum to free as a void pointer.
+ */
+void bc_num_free(void *num);
+
+/**
+ * Returns the scale of @a n.
+ * @param n The number.
+ * @return The scale of @a n.
+ */
+size_t bc_num_scale(const BcNum *restrict n);
+
+/**
+ * Returns the length (in decimal digits) of @a n. This is complicated. First,
+ * if the number is zero, we always return at least one, but we also return the
+ * scale if it exists. Then, If it is not zero, it opens a whole other can of
+ * worms. Read the comments in the definition.
+ * @param n The number.
+ * @return The length of @a n.
+ */
+size_t bc_num_len(const BcNum *restrict n);
+
+/**
+ * Convert a number to a BcBigDig (hardware integer). This version does error
+ * checking, and if it finds an error, throws it. Otherwise, it calls
+ * bc_num_bigdig2().
+ * @param n The number to convert.
+ * @return The number as a hardware integer.
+ */
+BcBigDig bc_num_bigdig(const BcNum *restrict n);
+
+/**
+ * Convert a number to a BcBigDig (hardware integer). This version does no error
+ * checking.
+ * @param n The number to convert.
+ * @return The number as a hardware integer.
+ */
+BcBigDig bc_num_bigdig2(const BcNum *restrict n);
+
+/**
+ * Sets @a n to the value of @a val. @a n is expected to be a valid and
+ * allocated BcNum.
+ * @param n The number to set.
+ * @param val The value to set the number to.
+ */
+void bc_num_bigdig2num(BcNum *restrict n, BcBigDig val);
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * Generates a random arbitrary-size integer less than or equal to @a a and
+ * returns it in @a b. This implements irand().
+ * @param a The limit for the integer to generate.
+ * @param b The return value.
+ * @param rng The pseudo-random number generator.
+ */
+void bc_num_irand(BcNum *restrict a, BcNum *restrict b,
+ struct BcRNG *restrict rng);
+
+/**
+ * Sets the seed for the PRNG @a rng from @a n.
+ * @param n The new seed for the PRNG.
+ * @param rng The PRNG to set the seed for.
+ */
+void bc_num_rng(const BcNum *restrict n, struct BcRNG *rng);
+
+/**
+ * Sets @a n to the value produced by the PRNG. This implements rand().
+ * @param n The number to set.
+ * @param rng The pseudo-random number generator.
+ */
+void bc_num_createFromRNG(BcNum *restrict n, struct BcRNG *rng);
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * The add function. This is a BcNumBinaryOp function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+/**
+ * The subtract function. This is a BcNumBinaryOp function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+/**
+ * The multiply function.
+ * @param a The first parameter. This is a BcNumBinaryOp function.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_mul(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+/**
+ * The division function.
+ * @param a The first parameter. This is a BcNumBinaryOp function.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_div(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+/**
+ * The modulus function.
+ * @param a The first parameter. This is a BcNumBinaryOp function.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_mod(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+/**
+ * The power function.
+ * @param a The first parameter. This is a BcNumBinaryOp function.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_pow(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * The places function (@ operator). This is a BcNumBinaryOp function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_places(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+/**
+ * The left shift function (<< operator). This is a BcNumBinaryOp function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_lshift(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+/**
+ * The right shift function (>> operator). This is a BcNumBinaryOp function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The return value.
+ * @param scale The current scale.
+ */
+void bc_num_rshift(BcNum *a, BcNum *b, BcNum *c, size_t scale);
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * Square root.
+ * @param a The first parameter.
+ * @param b The return value.
+ * @param scale The current scale.
+ */
+void bc_num_sqrt(BcNum *restrict a, BcNum *restrict b, size_t scale);
+
+/**
+ * Divsion and modulus together. This is a dc extension.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The first return value (quotient).
+ * @param d The second return value (modulus).
+ * @param scale The current scale.
+ */
+void bc_num_divmod(BcNum *a, BcNum *b, BcNum *c, BcNum *d, size_t scale);
+
+/**
+ * A function returning the required allocation size for an addition or a
+ * subtraction. This is a BcNumBinaryOpReq function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param scale The current scale.
+ * @return The size of allocation needed for the result of add or subtract
+ * with @a a, @a b, and @a scale.
+ */
+size_t bc_num_addReq(const BcNum* a, const BcNum* b, size_t scale);
+
+/**
+ * A function returning the required allocation size for a multiplication. This
+ * is a BcNumBinaryOpReq function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param scale The current scale.
+ * @return The size of allocation needed for the result of multiplication
+ * with @a a, @a b, and @a scale.
+ */
+size_t bc_num_mulReq(const BcNum *a, const BcNum *b, size_t scale);
+
+/**
+ * A function returning the required allocation size for a division or modulus.
+ * This is a BcNumBinaryOpReq function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param scale The current scale.
+ * @return The size of allocation needed for the result of division or
+ * modulus with @a a, @a b, and @a scale.
+ */
+size_t bc_num_divReq(const BcNum *a, const BcNum *b, size_t scale);
+
+/**
+ * A function returning the required allocation size for an exponentiation. This
+ * is a BcNumBinaryOpReq function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param scale The current scale.
+ * @return The size of allocation needed for the result of exponentiation
+ * with @a a, @a b, and @a scale.
+ */
+size_t bc_num_powReq(const BcNum *a, const BcNum *b, size_t scale);
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * A function returning the required allocation size for a places, left shift,
+ * or right shift. This is a BcNumBinaryOpReq function.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param scale The current scale.
+ * @return The size of allocation needed for the result of places, left
+ * shift, or right shift with @a a, @a b, and @a scale.
+ */
+size_t bc_num_placesReq(const BcNum *a, const BcNum *b, size_t scale);
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * Truncate @a n *by* @a places decimal places. This only extends places *after*
+ * the decimal point.
+ * @param n The number to truncate.
+ * @param places The number of places to truncate @a n by.
+ */
+void bc_num_truncate(BcNum *restrict n, size_t places);
+
+/**
+ * Extend @a n *by* @a places decimal places. This only extends places *after*
+ * the decimal point.
+ * @param n The number to truncate.
+ * @param places The number of places to extend @a n by.
+ */
+void bc_num_extend(BcNum *restrict n, size_t places);
+
+/**
+ * Shifts @a n right by @a places decimal places. This is the workhorse of the
+ * right shift operator, and would be static to src/num.c, except that
+ * src/library.c uses it for efficiency when executing its frand.
+ * @param n The number to shift right.
+ * @param places The number of decimal places to shift @a n right by.
+ */
+void bc_num_shiftRight(BcNum *restrict n, size_t places);
+
+/**
+ * Compare a and b and return the result of their comparison as an ssize_t.
+ * Returns >0 if @a a is greater than @a b, <0 if @a a is less than @a b, and =0
+ * if a == b.
+ * @param a The first number.
+ * @param b The second number.
+ * @return The result of the comparison.
+ */
+ssize_t bc_num_cmp(const BcNum *a, const BcNum *b);
+
+/**
+ * Modular exponentiation.
+ * @param a The first parameter.
+ * @param b The second parameter.
+ * @param c The third parameter.
+ * @param d The return value.
+ */
+void bc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d);
+
+/**
+ * Sets @a n to zero with a scale of zero.
+ * @param n The number to zero.
+ */
+void bc_num_zero(BcNum *restrict n);
+
+/**
+ * Sets @a n to one with a scale of zero.
+ * @param n The number to set to one.
+ */
+void bc_num_one(BcNum *restrict n);
+
+/**
+ * An efficient function to compare @a n to zero.
+ * @param n The number to compare to zero.
+ * @return The result of the comparison.
+ */
+ssize_t bc_num_cmpZero(const BcNum *n);
+
+#if !defined(NDEBUG) || BC_ENABLE_LIBRARY
+
+/**
+ * Check a number string for validity and return true if it is, false otherwise.
+ * The library needs this to check user-supplied strings, but in bc and dc, this
+ * is only used for debug asserts because the parsers should get the numbers
+ * parsed right, which should ensure they are always valid.
+ * @param val The string to check.
+ * @return True if the string is a valid number, false otherwise.
+ */
+bool bc_num_strValid(const char *restrict val);
+
+#endif // !defined(NDEBUG) || BC_ENABLE_LIBRARY
+
+/**
+ * Parses a number string into the number @a n according to @a base.
+ * @param n The number to set to the parsed value.
+ * @param val The number string to parse.
+ * @param base The base to parse the number string by.
+ */
+void bc_num_parse(BcNum *restrict n, const char *restrict val, BcBigDig base);
+
+/**
+ * Prints the number @a n according to @a base.
+ * @param n The number to print.
+ * @param base The base to print the number by.
+ * @param newline True if a newline should be inserted at the end, false
+ * otherwise.
+ */
+void bc_num_print(BcNum *restrict n, BcBigDig base, bool newline);
+
+#if !BC_ENABLE_LIBRARY
+
+/**
+ * Prints a number as a character stream.
+ * @param n The number to print as a character stream.
+ */
+void bc_num_stream(BcNum *restrict n);
+
+#endif // !BC_ENABLE_LIBRARY
+
+#if BC_DEBUG_CODE
+
+/**
+ * Print a number with a label. This is a debug-only function.
+ * @param n The number to print.
+ * @param name The label to print the number with.
+ * @param emptyline True if there should be an empty line after the number.
+ */
+void bc_num_printDebug(const BcNum *n, const char *name, bool emptyline);
+
+/**
+ * Print the limbs of @a n. This is a debug-only function.
+ * @param n The number to print.
+ * @param len The length of the number.
+ * @param emptyline True if there should be an empty line after the number.
+ */
+void bc_num_printDigs(const BcDig* n, size_t len, bool emptyline);
+
+/**
+ * Print debug info about @a n along with its limbs.
+ * @param n The number to print.
+ * @param name The label to print the number with.
+ * @param emptyline True if there should be an empty line after the number.
+ */
+void bc_num_printWithDigs(const BcNum *n, const char *name, bool emptyline);
+
+/**
+ * Dump debug info about a BcNum variable.
+ * @param varname The variable name.
+ * @param n The number.
+ */
+void bc_num_dump(const char *varname, const BcNum *n);
+
+#endif // BC_DEBUG_CODE
+
+/// A reference to an array of hex digits for easy conversion for printing.
+extern const char bc_num_hex_digits[];
+
+/// An array of powers of 10 for easy conversion from number of digits to
+//powers.
+extern const BcBigDig bc_num_pow10[BC_BASE_DIGS + 1];
+
+/// A reference to a constant array that is the max of a BigDig.
+extern const BcDig bc_num_bigdigMax[];
+
+/// A reference to a constant size of the above array.
+extern const size_t bc_num_bigdigMax_size;
+
+/// A reference to a constant array that is 2 times the max of a BigDig.
+extern const BcDig bc_num_bigdigMax2[];
+
+/// A reference to a constant size of the above array.
+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..cffe63682236
--- /dev/null
+++ b/contrib/bc/include/opt.h
@@ -0,0 +1,140 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Adapted from https://github.com/skeeto/optparse
+ *
+ * *****************************************************************************
+ *
+ * Definitions for getopt_long() replacement.
+ *
+ */
+
+#ifndef BC_OPT_H
+#define BC_OPT_H
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+/// The data required to parse command-line arguments.
+typedef struct BcOpt {
+
+ /// The array of arguments.
+ char **argv;
+
+ /// The index of the current argument.
+ size_t optind;
+
+ /// The actual parse option character.
+ int optopt;
+
+ /// Where in the option we are for multi-character single-character options.
+ int subopt;
+
+ /// The option argument.
+ char *optarg;
+
+} BcOpt;
+
+/// The types of arguments. This is specially adapted for bc.
+typedef enum BcOptType {
+
+ /// No argument required.
+ BC_OPT_NONE,
+
+ /// An argument required.
+ BC_OPT_REQUIRED,
+
+ /// An option that is bc-only.
+ BC_OPT_BC_ONLY,
+
+ /// An option that is bc-only that requires an argument.
+ BC_OPT_REQUIRED_BC_ONLY,
+
+ /// An option that is dc-only.
+ BC_OPT_DC_ONLY,
+
+} BcOptType;
+
+/// A struct to hold const data for long options.
+typedef struct BcOptLong {
+
+ /// The name of the option.
+ const char *name;
+
+ /// The type of the option.
+ BcOptType type;
+
+ /// The character to return if the long option was parsed.
+ int val;
+
+} BcOptLong;
+
+/**
+ * Initialize data for parsing options.
+ * @param o The option data to initialize.
+ * @param argv The array of arguments.
+ */
+void bc_opt_init(BcOpt *o, char **argv);
+
+/**
+ * Parse an option. This returns a value the same way getopt() and getopt_long()
+ * do, so it returns a character for the parsed option or -1 if done.
+ * @param o The option data.
+ * @param longopts The long options.
+ * @return A character for the parsed option, or -1 if done.
+ */
+int bc_opt_parse(BcOpt *o, const BcOptLong *longopts);
+
+/**
+ * Returns true if the option is `--` and not a long option.
+ * @param a The argument to parse.
+ * @return True if @a a is the `--` option, false otherwise.
+ */
+#define BC_OPT_ISDASHDASH(a) \
+ ((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] == '\0')
+
+/**
+ * Returns true if the option is a short option.
+ * @param a The argument to parse.
+ * @return True if @a a is a short option, false otherwise.
+ */
+#define BC_OPT_ISSHORTOPT(a) \
+ ((a) != NULL && (a)[0] == '-' && (a)[1] != '-' && (a)[1] != '\0')
+
+/**
+ * Returns true if the option has `--` at the beginning, i.e., is a long option.
+ * @param a The argument to parse.
+ * @return True if @a a is a long option, false otherwise.
+ */
+#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..0088c1523ec6
--- /dev/null
+++ b/contrib/bc/include/parse.h
@@ -0,0 +1,275 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for 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>
+
+// The following are flags that can be passed to @a BcParseExpr functions. They
+// define the requirements that the parsed expression must meet to not have an
+// error thrown.
+
+/// A flag that requires that the expression is valid for conditionals in for
+/// loops, while loops, and if statements. This is because POSIX requires that
+/// certain operators are *only* used in those cases. It's whacked, but that's
+/// how it is.
+#define BC_PARSE_REL (UINTMAX_C(1)<<0)
+
+/// A flag that requires that the expression is valid for a print statement.
+#define BC_PARSE_PRINT (UINTMAX_C(1)<<1)
+
+/// A flag that requires that the expression does *not* have any function call.
+#define BC_PARSE_NOCALL (UINTMAX_C(1)<<2)
+
+/// A flag that requires that the expression does *not* have a read() expression.
+#define BC_PARSE_NOREAD (UINTMAX_C(1)<<3)
+
+/// A flag that *allows* (rather than requires) that an array appear in the
+/// expression. This is mostly used as parameters in bc.
+#define BC_PARSE_ARRAY (UINTMAX_C(1)<<4)
+
+/// A flag that requires that the expression is not empty and returns a value.
+#define BC_PARSE_NEEDVAL (UINTMAX_C(1)<<5)
+
+/**
+ * Returns true if the parser has been initialized.
+ * @param p The parser.
+ * @param prg The program.
+ * @return True if @a p has been initialized, false otherwise.
+ */
+#define BC_PARSE_IS_INITED(p, prg) ((p)->prog == (prg))
+
+#if BC_ENABLED
+
+/**
+ * Returns true if the current parser state allows parsing, false otherwise.
+ * @param p The parser.
+ * @return True if parsing can proceed, false otherwise.
+ */
+#define BC_PARSE_CAN_PARSE(p) \
+ ((p).l.t != BC_LEX_EOF && (p).l.t != BC_LEX_KW_DEFINE)
+
+#else // BC_ENABLED
+
+/**
+ * Returns true if the current parser state allows parsing, false otherwise.
+ * @param p The parser.
+ * @return True if parsing can proceed, false otherwise.
+ */
+#define BC_PARSE_CAN_PARSE(p) ((p).l.t != BC_LEX_EOF)
+
+#endif // BC_ENABLED
+
+/**
+ * Pushes the instruction @a i onto the bytecode vector for the current
+ * function.
+ * @param p The parser.
+ * @param i The instruction to push onto the bytecode vector.
+ */
+#define bc_parse_push(p, i) (bc_vec_pushByte(&(p)->func->code, (uchar) (i)))
+
+/**
+ * Pushes an index onto the bytecode vector. For more information, see
+ * @a bc_vec_pushIndex() in src/vector.c and @a bc_program_index() in
+ * src/program.c.
+ * @param p The parser.
+ * @param idx The index to push onto the bytecode vector.
+ */
+#define bc_parse_pushIndex(p, idx) (bc_vec_pushIndex(&(p)->func->code, (idx)))
+
+/**
+ * A convenience macro for throwing errors in parse code. They take care of
+ * plumbing like passing in the current line the lexer is on.
+ * @param p The parser.
+ * @param e The error.
+ */
+#define bc_parse_err(p, e) (bc_vm_handleError((e), (p)->l.line))
+
+/**
+ * A convenience macro for throwing errors in parse code. They take care of
+ * plumbing like passing in the current line the lexer is on.
+ * @param p The parser.
+ * @param e The error.
+ * @param ... The varags that are needed.
+ */
+#define bc_parse_verr(p, e, ...) \
+ (bc_vm_handleError((e), (p)->l.line, __VA_ARGS__))
+
+// Forward declarations.
+struct BcParse;
+struct BcProgram;
+
+/**
+ * A function pointer to call when more parsing is needed.
+ * @param p The parser.
+ */
+typedef void (*BcParseParse)(struct BcParse* p);
+
+/**
+ * A function pointer to call when an expression needs to be parsed. This can
+ * happen for read() expressions or dc strings.
+ * @param p The parser.
+ * @param flags The flags for what is allowed or required. (See flags above.)
+ */
+typedef void (*BcParseExpr)(struct BcParse* p, uint8_t flags);
+
+/// The parser struct.
+typedef struct BcParse {
+
+ /// The lexer.
+ BcLex l;
+
+#if BC_ENABLED
+ /// The stack of flags for bc. (See comments in include/bc.h.) This stack is
+ /// *required* to have one item at all times. Not maintaining that invariant
+ /// will cause problems.
+ BcVec flags;
+
+ /// The stack of exits. These are indices into the bytecode vector where
+ /// blocks for loops and if statements end. Basically, these are the places
+ /// to jump to when skipping code.
+ BcVec exits;
+
+ /// The stack of conditionals. Unlike exits, which are indices to jump
+ /// *forward* to, this is a vector of indices to jump *backward* to, usually
+ /// to the conditional of a loop, hence the name.
+ BcVec conds;
+
+ /// A stack of operators. When parsing expressions, the bc parser uses the
+ /// Shunting-Yard algorithm, which requires a stack of operators. This can
+ /// hold the stack for multiple expressions at once because the expressions
+ /// stack as well. For more information, see the Expression Parsing section
+ /// of the Development manual (manuals/development.md).
+ BcVec ops;
+
+ /// A buffer to temporarily store a string in. This is because the lexer
+ /// might generate a string as part of its work, and the parser needs that
+ /// string, but it also needs the lexer to continue lexing, which might
+ /// overwrite the string stored in the lexer. This buffer is for copying
+ /// that string from the lexer to keep it safe.
+ BcVec buf;
+#endif // BC_ENABLED
+
+ /// A reference to the program to grab the current function when necessary.
+ struct BcProgram *prog;
+
+ /// A reference to the current function. The function is what holds the
+ /// bytecode vector that the parser is filling.
+ BcFunc *func;
+
+ /// The index of the function.
+ size_t fidx;
+
+#if BC_ENABLED
+ /// True if the bc parser just entered a function and an auto statement
+ /// would be valid.
+ bool auto_part;
+#endif // BC_ENABLED
+
+} BcParse;
+
+/**
+ * Initializes a parser.
+ * @param p The parser to initialize.
+ * @param prog A referenc to the program.
+ * @param func The index of the current function.
+ */
+void bc_parse_init(BcParse *p, struct BcProgram *prog, size_t func);
+
+/**
+ * Frees a parser. This is not guarded by #ifndef NDEBUG because a separate
+ * parser is created at runtime to parse read() expressions and dc strings.
+ * @param p The parser to free.
+ */
+void bc_parse_free(BcParse *p);
+
+/**
+ * Resets the parser. Resetting means erasing all state to the point that the
+ * parser would think it was just initialized.
+ * @param p The parser to reset.
+ */
+void bc_parse_reset(BcParse *p);
+
+/**
+ * Adds a string. See @a BcProgram in include/program.h for more details.
+ * @param p The parser that parsed the string.
+ */
+void bc_parse_addString(BcParse *p);
+
+/**
+ * Adds a number. See @a BcProgram in include/program.h for more details.
+ * @param p The parser that parsed the number.
+ */
+void bc_parse_number(BcParse *p);
+
+/**
+ * Update the current function in the parser.
+ * @param p The parser.
+ * @param fidx The index of the new function.
+ */
+void bc_parse_updateFunc(BcParse *p, size_t fidx);
+
+/**
+ * Adds a new variable or array. See @a BcProgram in include/program.h for more
+ * details.
+ * @param p The parser that parsed the variable or array name.
+ * @param name The name of the variable or array to add.
+ * @param var True if the name is for a variable, false if it's for an array.
+ */
+void bc_parse_pushName(const BcParse* p, char *name, bool var);
+
+/**
+ * Sets the text that the parser will parse.
+ * @param p The parser.
+ * @param text The text to lex.
+ * @param is_stdin True if the text is from stdin, false otherwise.
+ */
+void bc_parse_text(BcParse *p, const char *text, bool is_stdin);
+
+// References to const 0 and 1 strings for special cases. bc and dc have
+// specific instructions for 0 and 1 because they pop up so often and (in the
+// case of 1), increment/decrement operators.
+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..3f90f2b9f552
--- /dev/null
+++ b/contrib/bc/include/program.h
@@ -0,0 +1,971 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for bc programs.
+ *
+ */
+
+#ifndef BC_PROGRAM_H
+#define BC_PROGRAM_H
+
+#include <assert.h>
+#include <stddef.h>
+
+#include <status.h>
+#include <parse.h>
+#include <lang.h>
+#include <num.h>
+#include <rand.h>
+
+/// The index of ibase in the globals array.
+#define BC_PROG_GLOBALS_IBASE (0)
+
+/// The index of obase in the globals array.
+#define BC_PROG_GLOBALS_OBASE (1)
+
+/// The index of scale in the globals array.
+#define BC_PROG_GLOBALS_SCALE (2)
+
+#if BC_ENABLE_EXTRA_MATH
+
+/// The index of the rand max in the maxes array.
+#define BC_PROG_MAX_RAND (3)
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+/// The length of the globals array.
+#define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)
+
+typedef struct BcProgram {
+
+ /// The array of globals values.
+ BcBigDig globals[BC_PROG_GLOBALS_LEN];
+
+ /// The array of globals stacks.
+ BcVec globals_v[BC_PROG_GLOBALS_LEN];
+
+#if BC_ENABLE_EXTRA_MATH
+
+ /// The pseudo-random number generator.
+ BcRNG rng;
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+ /// The results stack.
+ BcVec results;
+
+ /// The execution stack.
+ BcVec stack;
+
+ /// A pointer to the current function's constants.
+ BcVec *consts;
+
+ /// A pointer to the current function's strings.
+ BcVec *strs;
+
+ /// The array of functions.
+ BcVec fns;
+
+ /// The map of functions to go with fns.
+ BcVec fn_map;
+
+ /// The array of variables.
+ BcVec vars;
+
+ /// The map of variables to go with vars.
+ BcVec var_map;
+
+ /// The array of arrays.
+ BcVec arrs;
+
+ /// The map of arrays to go with arrs.
+ BcVec arr_map;
+
+#if DC_ENABLED
+
+ /// A vector of tail calls. These are just integers, which are the number of
+ /// tail calls that have been executed for each function (string) on the
+ /// stack for dc. This is to prevent dc from constantly growing memory use
+ /// because of pushing more and more string executions on the stack.
+ BcVec tail_calls;
+
+#endif // DC_ENABLED
+
+ /// A BcNum that has the proper base for asciify.
+ BcNum strmb;
+
+#if BC_ENABLED
+
+ /// The last printed value for bc.
+ BcNum last;
+
+#endif // BC_ENABLED
+
+ // The BcDig array for strmb. 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];
+
+} BcProgram;
+
+/**
+ * Returns true if the stack @a s has at least @a n items, false otherwise.
+ * @param s The stack to check.
+ * @param n The number of items the stack must have.
+ * @return True if @a s has at least @a n items, false otherwise.
+ */
+#define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
+
+/**
+ * Get a pointer to the top value in a global value stack.
+ * @param v The global value stack.
+ * @return A pointer to the top value in @a v.
+ */
+#define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
+
+/**
+ * Get the top value in a global value stack.
+ * @param v The global value stack.
+ * @return The top value in @a v.
+ */
+#define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
+
+/**
+ * Returns the current value of ibase.
+ * @param p The program.
+ * @return The current ibase.
+ */
+#define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
+
+/**
+ * Returns the current value of obase.
+ * @param p The program.
+ * @return The current obase.
+ */
+#define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
+
+/**
+ * Returns the current value of scale.
+ * @param p The program.
+ * @return The current scale.
+ */
+#define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
+
+/// The index for the main function in the functions array.//
+#define BC_PROG_MAIN (0)
+
+/// The index for the read function in the functions array.
+#define BC_PROG_READ (1)
+
+/**
+ * Retires (completes the execution of) an instruction. Some instructions
+ * require special retirement, but most can use this. This basically pops the
+ * operands while preserving the result (which we assumed was pushed before the
+ * actual operation).
+ * @param p The program.
+ * @param nres The number of results returned by the instruction.
+ * @param nops The number of operands used by the instruction.
+ */
+#define bc_program_retire(p, nres, nops) \
+ (bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops)))
+
+#if DC_ENABLED
+
+/// A constant that tells how many functions are required in dc.
+#define BC_PROG_REQ_FUNCS (2)
+
+#if !BC_ENABLED
+
+/// This define disappears the parameter last because 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
+
+/// This define disappears pop and copy because for bc, 'pop' and 'copy' are
+/// always false.
+#define bc_program_pushVar(p, code, bgn, pop, copy) \
+ bc_program_pushVar(p, code, bgn)
+
+// In debug mode, we want bc to check the stack, but otherwise, we don't because
+// the bc language implicitly mandates that the stack should always have enough
+// items.
+#ifdef NDEBUG
+#define BC_PROG_NO_STACK_CHECK
+#endif // NDEBUG
+
+#endif // DC_ENABLED
+
+/**
+ * Returns true if the BcNum @a n is acting as a string.
+ * @param n The BcNum to test.
+ * @return True if @a n is acting as a string, false otherwise.
+ */
+#define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
+
+#if BC_ENABLED
+
+/**
+ * Returns true if the result @a r and @a n is a number.
+ * @param r The result.
+ * @param n The number corresponding to the result.
+ * @return True if the result holds a number, false otherwise.
+ */
+#define BC_PROG_NUM(r, n) \
+ ((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
+
+#else // BC_ENABLED
+
+/**
+ * Returns true if the result @a r and @a n is a number.
+ * @param r The result.
+ * @param n The number corresponding to the result.
+ * @return True if the result holds a number, false otherwise.
+ */
+#define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
+
+#endif // BC_ENABLED
+
+/**
+ * This is a function type for unary operations. Currently, these include
+ * boolean not, negation, and truncation with extra math.
+ * @param r The BcResult to store the result into.
+ * @param n The parameter to the unary operation.
+ */
+typedef void (*BcProgramUnary)(BcResult *r, BcNum *n);
+
+/**
+ * Initializes the BcProgram.
+ * @param p The program to initialize.
+ */
+void bc_program_init(BcProgram *p);
+
+#ifndef NDEBUG
+
+/**
+ * Frees a BcProgram. This is only used in debug builds because a BcProgram is
+ * only freed on program exit, and we don't care about freeing resources on
+ * exit.
+ * @param p The program to initialize.
+ */
+void bc_program_free(BcProgram *p);
+
+#endif // NDEBUG
+
+#if BC_DEBUG_CODE
+#if BC_ENABLED && DC_ENABLED
+
+/**
+ * Prints the bytecode in a function. This is a debug-only function.
+ * @param p The program.
+ */
+void bc_program_code(const BcProgram *p);
+
+/**
+ * Prints an instruction. This is a debug-only function.
+ * @param p The program.
+ * @param code The bytecode array.
+ * @param bgn A pointer to the current index. It is also updated to the next
+ * index.
+ */
+void bc_program_printInst(const BcProgram *p, const char *code,
+ size_t *restrict bgn);
+
+/**
+ * Prints the stack. This is a debug-only function.
+ * @param p The program.
+ */
+void bc_program_printStackDebug(BcProgram* p);
+
+#endif // BC_ENABLED && DC_ENABLED
+#endif // BC_DEBUG_CODE
+
+/**
+ * Returns the index of the variable or array in their respective arrays.
+ * @param p The program.
+ * @param id The BcId of the variable or array.
+ * @param var True if the search should be for a variable, false for an array.
+ * @return The index of the variable or array in the correct array.
+ */
+size_t bc_program_search(BcProgram *p, const char* id, bool var);
+
+/**
+ * Adds a string to a function and returns the string's index in the function.
+ * @param p The program.
+ * @param str The string to add.
+ * @param fidx The index of the function to add to.
+ */
+size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx);
+
+/**
+ * Inserts a function into the program and returns the index of the function in
+ * the fns array.
+ * @param p The program.
+ * @param name The name of the function.
+ * @return The index of the function after insertion.
+ */
+size_t bc_program_insertFunc(BcProgram *p, const char *name);
+
+/**
+ * Resets a program, usually because of resetting after an error.
+ * @param p The program to reset.
+ */
+void bc_program_reset(BcProgram *p);
+
+/**
+ * Executes bc or dc code in the BcProgram.
+ * @param p The program.
+ */
+void bc_program_exec(BcProgram *p);
+
+/**
+ * Negates a copy of a BcNum. This is a BcProgramUnary function.
+ * @param r The BcResult to store the result into.
+ * @param n The parameter to the unary operation.
+ */
+void bc_program_negate(BcResult *r, BcNum *n);
+
+/**
+ * Returns a boolean not of a BcNum. This is a BcProgramUnary function.
+ * @param r The BcResult to store the result into.
+ * @param n The parameter to the unary operation.
+ */
+void bc_program_not(BcResult *r, BcNum *n);
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * Truncates a copy of a BcNum. This is a BcProgramUnary function.
+ * @param r The BcResult to store the result into.
+ * @param n The parameter to the unary operation.
+ */
+void bc_program_trunc(BcResult *r, BcNum *n);
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+/// A reference to an array of binary operator functions.
+extern const BcNumBinaryOp bc_program_ops[];
+
+/// A reference to an array of binary operator allocation request functions.
+extern const BcNumBinaryOpReq bc_program_opReqs[];
+
+/// A reference to an array of unary operator functions.
+extern const BcProgramUnary bc_program_unarys[];
+
+/// A reference to a filename for command-line expressions.
+extern const char bc_program_exprs_name[];
+
+/// A reference to a filename for stdin.
+extern const char bc_program_stdin_name[];
+
+/// A reference to the ready message printed on SIGINT.
+extern const char bc_program_ready_msg[];
+
+/// A reference to the length of the ready message.
+extern const size_t bc_program_ready_msg_len;
+
+/// A reference to an array of escape characters for the print statement.
+extern const char bc_program_esc_chars[];
+
+/// A reference to an array of the characters corresponding to the escape
+/// characters in bc_program_esc_chars.
+extern const char bc_program_esc_seqs[];
+
+#if BC_HAS_COMPUTED_GOTO
+
+#if BC_DEBUG_CODE
+
+#define BC_PROG_JUMP(inst, code, ip) \
+ do { \
+ inst = (uchar) (code)[(ip)->idx++]; \
+ bc_file_printf(&vm.ferr, "inst: %s\n", bc_inst_names[inst]); \
+ bc_file_flush(&vm.ferr, bc_flush_none); \
+ goto *bc_program_inst_lbls[inst]; \
+ } while (0)
+
+#else // BC_DEBUG_CODE
+
+#define BC_PROG_JUMP(inst, code, ip) \
+ do { \
+ inst = (uchar) (code)[(ip)->idx++]; \
+ goto *bc_program_inst_lbls[inst]; \
+ } while (0)
+
+#endif // BC_DEBUG_CODE
+
+#define BC_PROG_DIRECT_JUMP(l) goto lbl_ ## l;
+#define BC_PROG_LBL(l) lbl_ ## l
+#define BC_PROG_FALLTHROUGH
+
+#if BC_C11
+
+#define BC_PROG_LBLS_SIZE (sizeof(bc_program_inst_lbls) / sizeof(void*))
+#define BC_PROG_LBLS_ASSERT \
+ static_assert(BC_PROG_LBLS_SIZE == BC_INST_INVALID + 1,\
+ "bc_program_inst_lbls[] mismatches the instructions")
+
+#else // BC_C11
+
+#define BC_PROG_LBLS_ASSERT
+
+#endif // BC_C11
+
+#if BC_ENABLED
+
+#if DC_ENABLED
+
+#if BC_ENABLE_EXTRA_MATH
+
+#define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
+ &&lbl_BC_INST_INC, \
+ &&lbl_BC_INST_DEC, \
+ &&lbl_BC_INST_NEG, \
+ &&lbl_BC_INST_BOOL_NOT, \
+ &&lbl_BC_INST_TRUNC, \
+ &&lbl_BC_INST_POWER, \
+ &&lbl_BC_INST_MULTIPLY, \
+ &&lbl_BC_INST_DIVIDE, \
+ &&lbl_BC_INST_MODULUS, \
+ &&lbl_BC_INST_PLUS, \
+ &&lbl_BC_INST_MINUS, \
+ &&lbl_BC_INST_PLACES, \
+ &&lbl_BC_INST_LSHIFT, \
+ &&lbl_BC_INST_RSHIFT, \
+ &&lbl_BC_INST_REL_EQ, \
+ &&lbl_BC_INST_REL_LE, \
+ &&lbl_BC_INST_REL_GE, \
+ &&lbl_BC_INST_REL_NE, \
+ &&lbl_BC_INST_REL_LT, \
+ &&lbl_BC_INST_REL_GT, \
+ &&lbl_BC_INST_BOOL_OR, \
+ &&lbl_BC_INST_BOOL_AND, \
+ &&lbl_BC_INST_ASSIGN_POWER, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE, \
+ &&lbl_BC_INST_ASSIGN_MODULUS, \
+ &&lbl_BC_INST_ASSIGN_PLUS, \
+ &&lbl_BC_INST_ASSIGN_MINUS, \
+ &&lbl_BC_INST_ASSIGN_PLACES, \
+ &&lbl_BC_INST_ASSIGN_LSHIFT, \
+ &&lbl_BC_INST_ASSIGN_RSHIFT, \
+ &&lbl_BC_INST_ASSIGN, \
+ &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_NO_VAL, \
+ &&lbl_BC_INST_NUM, \
+ &&lbl_BC_INST_VAR, \
+ &&lbl_BC_INST_ARRAY_ELEM, \
+ &&lbl_BC_INST_ARRAY, \
+ &&lbl_BC_INST_ZERO, \
+ &&lbl_BC_INST_ONE, \
+ &&lbl_BC_INST_LAST, \
+ &&lbl_BC_INST_IBASE, \
+ &&lbl_BC_INST_OBASE, \
+ &&lbl_BC_INST_SCALE, \
+ &&lbl_BC_INST_SEED, \
+ &&lbl_BC_INST_LENGTH, \
+ &&lbl_BC_INST_SCALE_FUNC, \
+ &&lbl_BC_INST_SQRT, \
+ &&lbl_BC_INST_ABS, \
+ &&lbl_BC_INST_IRAND, \
+ &&lbl_BC_INST_ASCIIFY, \
+ &&lbl_BC_INST_READ, \
+ &&lbl_BC_INST_RAND, \
+ &&lbl_BC_INST_MAXIBASE, \
+ &&lbl_BC_INST_MAXOBASE, \
+ &&lbl_BC_INST_MAXSCALE, \
+ &&lbl_BC_INST_MAXRAND, \
+ &&lbl_BC_INST_LINE_LENGTH, \
+ &&lbl_BC_INST_GLOBAL_STACKS, \
+ &&lbl_BC_INST_LEADING_ZERO, \
+ &&lbl_BC_INST_PRINT, \
+ &&lbl_BC_INST_PRINT_POP, \
+ &&lbl_BC_INST_STR, \
+ &&lbl_BC_INST_PRINT_STR, \
+ &&lbl_BC_INST_JUMP, \
+ &&lbl_BC_INST_JUMP_ZERO, \
+ &&lbl_BC_INST_CALL, \
+ &&lbl_BC_INST_RET, \
+ &&lbl_BC_INST_RET0, \
+ &&lbl_BC_INST_RET_VOID, \
+ &&lbl_BC_INST_HALT, \
+ &&lbl_BC_INST_POP, \
+ &&lbl_BC_INST_SWAP, \
+ &&lbl_BC_INST_MODEXP, \
+ &&lbl_BC_INST_DIVMOD, \
+ &&lbl_BC_INST_PRINT_STREAM, \
+ &&lbl_BC_INST_POP_EXEC, \
+ &&lbl_BC_INST_EXECUTE, \
+ &&lbl_BC_INST_EXEC_COND, \
+ &&lbl_BC_INST_PRINT_STACK, \
+ &&lbl_BC_INST_CLEAR_STACK, \
+ &&lbl_BC_INST_REG_STACK_LEN, \
+ &&lbl_BC_INST_STACK_LEN, \
+ &&lbl_BC_INST_DUPLICATE, \
+ &&lbl_BC_INST_LOAD, \
+ &&lbl_BC_INST_PUSH_VAR, \
+ &&lbl_BC_INST_PUSH_TO_VAR, \
+ &&lbl_BC_INST_QUIT, \
+ &&lbl_BC_INST_NQUIT, \
+ &&lbl_BC_INST_EXEC_STACK_LEN, \
+ &&lbl_BC_INST_INVALID, \
+}
+
+#else // BC_ENABLE_EXTRA_MATH
+
+#define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
+ &&lbl_BC_INST_INC, \
+ &&lbl_BC_INST_DEC, \
+ &&lbl_BC_INST_NEG, \
+ &&lbl_BC_INST_BOOL_NOT, \
+ &&lbl_BC_INST_POWER, \
+ &&lbl_BC_INST_MULTIPLY, \
+ &&lbl_BC_INST_DIVIDE, \
+ &&lbl_BC_INST_MODULUS, \
+ &&lbl_BC_INST_PLUS, \
+ &&lbl_BC_INST_MINUS, \
+ &&lbl_BC_INST_REL_EQ, \
+ &&lbl_BC_INST_REL_LE, \
+ &&lbl_BC_INST_REL_GE, \
+ &&lbl_BC_INST_REL_NE, \
+ &&lbl_BC_INST_REL_LT, \
+ &&lbl_BC_INST_REL_GT, \
+ &&lbl_BC_INST_BOOL_OR, \
+ &&lbl_BC_INST_BOOL_AND, \
+ &&lbl_BC_INST_ASSIGN_POWER, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE, \
+ &&lbl_BC_INST_ASSIGN_MODULUS, \
+ &&lbl_BC_INST_ASSIGN_PLUS, \
+ &&lbl_BC_INST_ASSIGN_MINUS, \
+ &&lbl_BC_INST_ASSIGN, \
+ &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_NO_VAL, \
+ &&lbl_BC_INST_NUM, \
+ &&lbl_BC_INST_VAR, \
+ &&lbl_BC_INST_ARRAY_ELEM, \
+ &&lbl_BC_INST_ARRAY, \
+ &&lbl_BC_INST_ZERO, \
+ &&lbl_BC_INST_ONE, \
+ &&lbl_BC_INST_LAST, \
+ &&lbl_BC_INST_IBASE, \
+ &&lbl_BC_INST_OBASE, \
+ &&lbl_BC_INST_SCALE, \
+ &&lbl_BC_INST_LENGTH, \
+ &&lbl_BC_INST_SCALE_FUNC, \
+ &&lbl_BC_INST_SQRT, \
+ &&lbl_BC_INST_ABS, \
+ &&lbl_BC_INST_ASCIIFY, \
+ &&lbl_BC_INST_READ, \
+ &&lbl_BC_INST_MAXIBASE, \
+ &&lbl_BC_INST_MAXOBASE, \
+ &&lbl_BC_INST_MAXSCALE, \
+ &&lbl_BC_INST_LINE_LENGTH, \
+ &&lbl_BC_INST_GLOBAL_STACKS, \
+ &&lbl_BC_INST_LEADING_ZERO, \
+ &&lbl_BC_INST_PRINT, \
+ &&lbl_BC_INST_PRINT_POP, \
+ &&lbl_BC_INST_STR, \
+ &&lbl_BC_INST_PRINT_STR, \
+ &&lbl_BC_INST_JUMP, \
+ &&lbl_BC_INST_JUMP_ZERO, \
+ &&lbl_BC_INST_CALL, \
+ &&lbl_BC_INST_RET, \
+ &&lbl_BC_INST_RET0, \
+ &&lbl_BC_INST_RET_VOID, \
+ &&lbl_BC_INST_HALT, \
+ &&lbl_BC_INST_POP, \
+ &&lbl_BC_INST_SWAP, \
+ &&lbl_BC_INST_MODEXP, \
+ &&lbl_BC_INST_DIVMOD, \
+ &&lbl_BC_INST_PRINT_STREAM, \
+ &&lbl_BC_INST_POP_EXEC, \
+ &&lbl_BC_INST_EXECUTE, \
+ &&lbl_BC_INST_EXEC_COND, \
+ &&lbl_BC_INST_PRINT_STACK, \
+ &&lbl_BC_INST_CLEAR_STACK, \
+ &&lbl_BC_INST_REG_STACK_LEN, \
+ &&lbl_BC_INST_STACK_LEN, \
+ &&lbl_BC_INST_DUPLICATE, \
+ &&lbl_BC_INST_LOAD, \
+ &&lbl_BC_INST_PUSH_VAR, \
+ &&lbl_BC_INST_PUSH_TO_VAR, \
+ &&lbl_BC_INST_QUIT, \
+ &&lbl_BC_INST_NQUIT, \
+ &&lbl_BC_INST_EXEC_STACK_LEN, \
+ &&lbl_BC_INST_INVALID, \
+}
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+#else // DC_ENABLED
+
+#if BC_ENABLE_EXTRA_MATH
+
+#define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
+ &&lbl_BC_INST_INC, \
+ &&lbl_BC_INST_DEC, \
+ &&lbl_BC_INST_NEG, \
+ &&lbl_BC_INST_BOOL_NOT, \
+ &&lbl_BC_INST_TRUNC, \
+ &&lbl_BC_INST_POWER, \
+ &&lbl_BC_INST_MULTIPLY, \
+ &&lbl_BC_INST_DIVIDE, \
+ &&lbl_BC_INST_MODULUS, \
+ &&lbl_BC_INST_PLUS, \
+ &&lbl_BC_INST_MINUS, \
+ &&lbl_BC_INST_PLACES, \
+ &&lbl_BC_INST_LSHIFT, \
+ &&lbl_BC_INST_RSHIFT, \
+ &&lbl_BC_INST_REL_EQ, \
+ &&lbl_BC_INST_REL_LE, \
+ &&lbl_BC_INST_REL_GE, \
+ &&lbl_BC_INST_REL_NE, \
+ &&lbl_BC_INST_REL_LT, \
+ &&lbl_BC_INST_REL_GT, \
+ &&lbl_BC_INST_BOOL_OR, \
+ &&lbl_BC_INST_BOOL_AND, \
+ &&lbl_BC_INST_ASSIGN_POWER, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE, \
+ &&lbl_BC_INST_ASSIGN_MODULUS, \
+ &&lbl_BC_INST_ASSIGN_PLUS, \
+ &&lbl_BC_INST_ASSIGN_MINUS, \
+ &&lbl_BC_INST_ASSIGN_PLACES, \
+ &&lbl_BC_INST_ASSIGN_LSHIFT, \
+ &&lbl_BC_INST_ASSIGN_RSHIFT, \
+ &&lbl_BC_INST_ASSIGN, \
+ &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_PLACES_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_LSHIFT_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_RSHIFT_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_NO_VAL, \
+ &&lbl_BC_INST_NUM, \
+ &&lbl_BC_INST_VAR, \
+ &&lbl_BC_INST_ARRAY_ELEM, \
+ &&lbl_BC_INST_ARRAY, \
+ &&lbl_BC_INST_ZERO, \
+ &&lbl_BC_INST_ONE, \
+ &&lbl_BC_INST_LAST, \
+ &&lbl_BC_INST_IBASE, \
+ &&lbl_BC_INST_OBASE, \
+ &&lbl_BC_INST_SCALE, \
+ &&lbl_BC_INST_SEED, \
+ &&lbl_BC_INST_LENGTH, \
+ &&lbl_BC_INST_SCALE_FUNC, \
+ &&lbl_BC_INST_SQRT, \
+ &&lbl_BC_INST_ABS, \
+ &&lbl_BC_INST_IRAND, \
+ &&lbl_BC_INST_ASCIIFY, \
+ &&lbl_BC_INST_READ, \
+ &&lbl_BC_INST_RAND, \
+ &&lbl_BC_INST_MAXIBASE, \
+ &&lbl_BC_INST_MAXOBASE, \
+ &&lbl_BC_INST_MAXSCALE, \
+ &&lbl_BC_INST_MAXRAND, \
+ &&lbl_BC_INST_LINE_LENGTH, \
+ &&lbl_BC_INST_GLOBAL_STACKS, \
+ &&lbl_BC_INST_LEADING_ZERO, \
+ &&lbl_BC_INST_PRINT, \
+ &&lbl_BC_INST_PRINT_POP, \
+ &&lbl_BC_INST_STR, \
+ &&lbl_BC_INST_PRINT_STR, \
+ &&lbl_BC_INST_JUMP, \
+ &&lbl_BC_INST_JUMP_ZERO, \
+ &&lbl_BC_INST_CALL, \
+ &&lbl_BC_INST_RET, \
+ &&lbl_BC_INST_RET0, \
+ &&lbl_BC_INST_RET_VOID, \
+ &&lbl_BC_INST_HALT, \
+ &&lbl_BC_INST_POP, \
+ &&lbl_BC_INST_SWAP, \
+ &&lbl_BC_INST_MODEXP, \
+ &&lbl_BC_INST_DIVMOD, \
+ &&lbl_BC_INST_PRINT_STREAM, \
+ &&lbl_BC_INST_INVALID, \
+}
+
+#else // BC_ENABLE_EXTRA_MATH
+
+#define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
+ &&lbl_BC_INST_INC, \
+ &&lbl_BC_INST_DEC, \
+ &&lbl_BC_INST_NEG, \
+ &&lbl_BC_INST_BOOL_NOT, \
+ &&lbl_BC_INST_POWER, \
+ &&lbl_BC_INST_MULTIPLY, \
+ &&lbl_BC_INST_DIVIDE, \
+ &&lbl_BC_INST_MODULUS, \
+ &&lbl_BC_INST_PLUS, \
+ &&lbl_BC_INST_MINUS, \
+ &&lbl_BC_INST_REL_EQ, \
+ &&lbl_BC_INST_REL_LE, \
+ &&lbl_BC_INST_REL_GE, \
+ &&lbl_BC_INST_REL_NE, \
+ &&lbl_BC_INST_REL_LT, \
+ &&lbl_BC_INST_REL_GT, \
+ &&lbl_BC_INST_BOOL_OR, \
+ &&lbl_BC_INST_BOOL_AND, \
+ &&lbl_BC_INST_ASSIGN_POWER, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE, \
+ &&lbl_BC_INST_ASSIGN_MODULUS, \
+ &&lbl_BC_INST_ASSIGN_PLUS, \
+ &&lbl_BC_INST_ASSIGN_MINUS, \
+ &&lbl_BC_INST_ASSIGN, \
+ &&lbl_BC_INST_ASSIGN_POWER_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MULTIPLY_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_DIVIDE_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MODULUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_PLUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_MINUS_NO_VAL, \
+ &&lbl_BC_INST_ASSIGN_NO_VAL, \
+ &&lbl_BC_INST_NUM, \
+ &&lbl_BC_INST_VAR, \
+ &&lbl_BC_INST_ARRAY_ELEM, \
+ &&lbl_BC_INST_ARRAY, \
+ &&lbl_BC_INST_ZERO, \
+ &&lbl_BC_INST_ONE, \
+ &&lbl_BC_INST_LAST, \
+ &&lbl_BC_INST_IBASE, \
+ &&lbl_BC_INST_OBASE, \
+ &&lbl_BC_INST_SCALE, \
+ &&lbl_BC_INST_LENGTH, \
+ &&lbl_BC_INST_SCALE_FUNC, \
+ &&lbl_BC_INST_SQRT, \
+ &&lbl_BC_INST_ABS, \
+ &&lbl_BC_INST_ASCIIFY, \
+ &&lbl_BC_INST_READ, \
+ &&lbl_BC_INST_MAXIBASE, \
+ &&lbl_BC_INST_MAXOBASE, \
+ &&lbl_BC_INST_MAXSCALE, \
+ &&lbl_BC_INST_LINE_LENGTH, \
+ &&lbl_BC_INST_GLOBAL_STACKS, \
+ &&lbl_BC_INST_LEADING_ZERO, \
+ &&lbl_BC_INST_PRINT, \
+ &&lbl_BC_INST_PRINT_POP, \
+ &&lbl_BC_INST_STR, \
+ &&lbl_BC_INST_PRINT_STR, \
+ &&lbl_BC_INST_JUMP, \
+ &&lbl_BC_INST_JUMP_ZERO, \
+ &&lbl_BC_INST_CALL, \
+ &&lbl_BC_INST_RET, \
+ &&lbl_BC_INST_RET0, \
+ &&lbl_BC_INST_RET_VOID, \
+ &&lbl_BC_INST_HALT, \
+ &&lbl_BC_INST_POP, \
+ &&lbl_BC_INST_SWAP, \
+ &&lbl_BC_INST_MODEXP, \
+ &&lbl_BC_INST_DIVMOD, \
+ &&lbl_BC_INST_PRINT_STREAM, \
+ &&lbl_BC_INST_INVALID, \
+}
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+#endif // DC_ENABLED
+
+#else // BC_ENABLED
+
+#if BC_ENABLE_EXTRA_MATH
+
+#define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
+ &&lbl_BC_INST_NEG, \
+ &&lbl_BC_INST_BOOL_NOT, \
+ &&lbl_BC_INST_TRUNC, \
+ &&lbl_BC_INST_POWER, \
+ &&lbl_BC_INST_MULTIPLY, \
+ &&lbl_BC_INST_DIVIDE, \
+ &&lbl_BC_INST_MODULUS, \
+ &&lbl_BC_INST_PLUS, \
+ &&lbl_BC_INST_MINUS, \
+ &&lbl_BC_INST_PLACES, \
+ &&lbl_BC_INST_LSHIFT, \
+ &&lbl_BC_INST_RSHIFT, \
+ &&lbl_BC_INST_REL_EQ, \
+ &&lbl_BC_INST_REL_LE, \
+ &&lbl_BC_INST_REL_GE, \
+ &&lbl_BC_INST_REL_NE, \
+ &&lbl_BC_INST_REL_LT, \
+ &&lbl_BC_INST_REL_GT, \
+ &&lbl_BC_INST_BOOL_OR, \
+ &&lbl_BC_INST_BOOL_AND, \
+ &&lbl_BC_INST_ASSIGN_NO_VAL, \
+ &&lbl_BC_INST_NUM, \
+ &&lbl_BC_INST_VAR, \
+ &&lbl_BC_INST_ARRAY_ELEM, \
+ &&lbl_BC_INST_ARRAY, \
+ &&lbl_BC_INST_ZERO, \
+ &&lbl_BC_INST_ONE, \
+ &&lbl_BC_INST_IBASE, \
+ &&lbl_BC_INST_OBASE, \
+ &&lbl_BC_INST_SCALE, \
+ &&lbl_BC_INST_SEED, \
+ &&lbl_BC_INST_LENGTH, \
+ &&lbl_BC_INST_SCALE_FUNC, \
+ &&lbl_BC_INST_SQRT, \
+ &&lbl_BC_INST_ABS, \
+ &&lbl_BC_INST_IRAND, \
+ &&lbl_BC_INST_ASCIIFY, \
+ &&lbl_BC_INST_READ, \
+ &&lbl_BC_INST_RAND, \
+ &&lbl_BC_INST_MAXIBASE, \
+ &&lbl_BC_INST_MAXOBASE, \
+ &&lbl_BC_INST_MAXSCALE, \
+ &&lbl_BC_INST_MAXRAND, \
+ &&lbl_BC_INST_LINE_LENGTH, \
+ &&lbl_BC_INST_LEADING_ZERO, \
+ &&lbl_BC_INST_PRINT, \
+ &&lbl_BC_INST_PRINT_POP, \
+ &&lbl_BC_INST_STR, \
+ &&lbl_BC_INST_POP, \
+ &&lbl_BC_INST_SWAP, \
+ &&lbl_BC_INST_MODEXP, \
+ &&lbl_BC_INST_DIVMOD, \
+ &&lbl_BC_INST_PRINT_STREAM, \
+ &&lbl_BC_INST_POP_EXEC, \
+ &&lbl_BC_INST_EXECUTE, \
+ &&lbl_BC_INST_EXEC_COND, \
+ &&lbl_BC_INST_PRINT_STACK, \
+ &&lbl_BC_INST_CLEAR_STACK, \
+ &&lbl_BC_INST_REG_STACK_LEN, \
+ &&lbl_BC_INST_STACK_LEN, \
+ &&lbl_BC_INST_DUPLICATE, \
+ &&lbl_BC_INST_LOAD, \
+ &&lbl_BC_INST_PUSH_VAR, \
+ &&lbl_BC_INST_PUSH_TO_VAR, \
+ &&lbl_BC_INST_QUIT, \
+ &&lbl_BC_INST_NQUIT, \
+ &&lbl_BC_INST_EXEC_STACK_LEN, \
+ &&lbl_BC_INST_INVALID, \
+}
+
+#else // BC_ENABLE_EXTRA_MATH
+
+#define BC_PROG_LBLS static const void* const bc_program_inst_lbls[] = { \
+ &&lbl_BC_INST_NEG, \
+ &&lbl_BC_INST_BOOL_NOT, \
+ &&lbl_BC_INST_POWER, \
+ &&lbl_BC_INST_MULTIPLY, \
+ &&lbl_BC_INST_DIVIDE, \
+ &&lbl_BC_INST_MODULUS, \
+ &&lbl_BC_INST_PLUS, \
+ &&lbl_BC_INST_MINUS, \
+ &&lbl_BC_INST_REL_EQ, \
+ &&lbl_BC_INST_REL_LE, \
+ &&lbl_BC_INST_REL_GE, \
+ &&lbl_BC_INST_REL_NE, \
+ &&lbl_BC_INST_REL_LT, \
+ &&lbl_BC_INST_REL_GT, \
+ &&lbl_BC_INST_BOOL_OR, \
+ &&lbl_BC_INST_BOOL_AND, \
+ &&lbl_BC_INST_ASSIGN_NO_VAL, \
+ &&lbl_BC_INST_NUM, \
+ &&lbl_BC_INST_VAR, \
+ &&lbl_BC_INST_ARRAY_ELEM, \
+ &&lbl_BC_INST_ARRAY, \
+ &&lbl_BC_INST_ZERO, \
+ &&lbl_BC_INST_ONE, \
+ &&lbl_BC_INST_IBASE, \
+ &&lbl_BC_INST_OBASE, \
+ &&lbl_BC_INST_SCALE, \
+ &&lbl_BC_INST_LENGTH, \
+ &&lbl_BC_INST_SCALE_FUNC, \
+ &&lbl_BC_INST_SQRT, \
+ &&lbl_BC_INST_ABS, \
+ &&lbl_BC_INST_ASCIIFY, \
+ &&lbl_BC_INST_READ, \
+ &&lbl_BC_INST_MAXIBASE, \
+ &&lbl_BC_INST_MAXOBASE, \
+ &&lbl_BC_INST_MAXSCALE, \
+ &&lbl_BC_INST_LINE_LENGTH, \
+ &&lbl_BC_INST_LEADING_ZERO, \
+ &&lbl_BC_INST_PRINT, \
+ &&lbl_BC_INST_PRINT_POP, \
+ &&lbl_BC_INST_STR, \
+ &&lbl_BC_INST_POP, \
+ &&lbl_BC_INST_SWAP, \
+ &&lbl_BC_INST_MODEXP, \
+ &&lbl_BC_INST_DIVMOD, \
+ &&lbl_BC_INST_PRINT_STREAM, \
+ &&lbl_BC_INST_POP_EXEC, \
+ &&lbl_BC_INST_EXECUTE, \
+ &&lbl_BC_INST_EXEC_COND, \
+ &&lbl_BC_INST_PRINT_STACK, \
+ &&lbl_BC_INST_CLEAR_STACK, \
+ &&lbl_BC_INST_REG_STACK_LEN, \
+ &&lbl_BC_INST_STACK_LEN, \
+ &&lbl_BC_INST_DUPLICATE, \
+ &&lbl_BC_INST_LOAD, \
+ &&lbl_BC_INST_PUSH_VAR, \
+ &&lbl_BC_INST_PUSH_TO_VAR, \
+ &&lbl_BC_INST_QUIT, \
+ &&lbl_BC_INST_NQUIT, \
+ &&lbl_BC_INST_EXEC_STACK_LEN, \
+ &&lbl_BC_INST_INVALID, \
+}
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+#endif // BC_ENABLED
+
+#else // BC_HAS_COMPUTED_GOTO
+
+#define BC_PROG_JUMP(inst, code, ip) break
+#define BC_PROG_DIRECT_JUMP(l)
+#define BC_PROG_LBL(l) case l
+#define BC_PROG_FALLTHROUGH BC_FALLTHROUGH
+
+#define BC_PROG_LBLS
+
+#endif // BC_HAS_COMPUTED_GOTO
+
+#endif // BC_PROGRAM_H
diff --git a/contrib/bc/include/rand.h b/contrib/bc/include/rand.h
new file mode 100644
index 000000000000..58eb2cf0e320
--- /dev/null
+++ b/contrib/bc/include/rand.h
@@ -0,0 +1,519 @@
+/*
+ * *****************************************************************************
+ *
+ * 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
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * This code is under the following license:
+ *
+ * Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
+ * Copyright (c) 2018-2021 Gavin D. Howard and 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_LIBRARY
+#define BC_RAND_USE_FREE (1)
+#else // BC_ENABLE_LIBRARY
+#ifndef NDEBUG
+#define BC_RAND_USE_FREE (1)
+#else // NDEBUG
+#define BC_RAND_USE_FREE (0)
+#endif // NDEBUG
+#endif // BC_ENABLE_LIBRARY
+
+/**
+ * A function to return a random unsigned long.
+ * @param ptr A void ptr to some data that will help generate the random ulong.
+ * @return The random ulong.
+ */
+typedef ulong (*BcRandUlong)(void *ptr);
+
+#if BC_LONG_BIT >= 64
+
+// If longs are 64 bits, we have the option of 128-bit integers on some
+// compilers. These two sections test that.
+#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
+
+/// The type for random integers.
+typedef uint64_t BcRand;
+
+/// A constant defined by PCG.
+#define BC_RAND_ROTC (63)
+
+#if BC_RAND_BUILTIN
+
+/// A typedef for the PCG state.
+typedef __uint128_t BcRandState;
+
+/**
+ * Multiply two integers, worrying about overflow.
+ * @param a The first integer.
+ * @param b The second integer.
+ * @return The product of the PCG states.
+ */
+#define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+
+/**
+ * Add two integers, worrying about overflow.
+ * @param a The first integer.
+ * @param b The second integer.
+ * @return The sum of the PCG states.
+ */
+#define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+/**
+ * Multiply two PCG states.
+ * @param a The first PCG state.
+ * @param b The second PCG state.
+ * @return The product of the PCG states.
+ */
+#define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+
+/**
+ * Add two PCG states.
+ * @param a The first PCG state.
+ * @param b The second PCG state.
+ * @return The sum of the PCG states.
+ */
+#define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+/**
+ * Figure out if the PRNG has been modified. Since the increment of the PRNG has
+ * to be odd, we use the extra bit to store whether it has been modified or not.
+ * @param r The PRNG.
+ * @return True if the PRNG has *not* been modified, false otherwise.
+ */
+#define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
+
+/**
+ * Return true if the PRNG has not been seeded yet.
+ * @param r The PRNG.
+ * @return True if the PRNG has not been seeded yet, false otherwise.
+ */
+#define BC_RAND_ZERO(r) (!(r)->state)
+
+/**
+ * Returns a constant built from @a h and @a l.
+ * @param h The high 64 bits.
+ * @param l The low 64 bits.
+ * @return The constant built from @a h and @a l.
+ */
+#define BC_RAND_CONSTANT(h, l) ((((BcRandState) (h)) << 64) + (BcRandState) (l))
+
+/**
+ * Truncates a PCG state to the number of bits in a random integer.
+ * @param s The state to truncate.
+ * @return The truncated state.
+ */
+#define BC_RAND_TRUNC(s) ((uint64_t) (s))
+
+/**
+ * Chops a PCG state in half and returns the top bits.
+ * @param s The state to chop.
+ * @return The chopped state's top bits.
+ */
+#define BC_RAND_CHOP(s) ((uint64_t) ((s) >> 64UL))
+
+/**
+ * Rotates a PCG state.
+ * @param s The state to rotate.
+ * @return The rotated state.
+ */
+#define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 122UL))
+
+#else // BC_RAND_BUILTIN
+
+/// A typedef for the PCG state.
+typedef struct BcRandState {
+
+ /// The low bits.
+ uint_fast64_t lo;
+
+ /// The high bits.
+ uint_fast64_t hi;
+
+} BcRandState;
+
+/**
+ * Multiply two integers, worrying about overflow.
+ * @param a The first integer.
+ * @param b The second integer.
+ * @return The product of the PCG states.
+ */
+#define bc_rand_mul(a, b) (bc_rand_multiply((a), (b)))
+
+/**
+ * Add two integers, worrying about overflow.
+ * @param a The first integer.
+ * @param b The second integer.
+ * @return The sum of the PCG states.
+ */
+#define bc_rand_add(a, b) (bc_rand_addition((a), (b)))
+
+/**
+ * Multiply two PCG states.
+ * @param a The first PCG state.
+ * @param b The second PCG state.
+ * @return The product of the PCG states.
+ */
+#define bc_rand_mul2(a, b) (bc_rand_multiply2((a), (b)))
+
+/**
+ * Add two PCG states.
+ * @param a The first PCG state.
+ * @param b The second PCG state.
+ * @return The sum of the PCG states.
+ */
+#define bc_rand_add2(a, b) (bc_rand_addition2((a), (b)))
+
+/**
+ * Figure out if the PRNG has been modified. Since the increment of the PRNG has
+ * to be odd, we use the extra bit to store whether it has been modified or not.
+ * @param r The PRNG.
+ * @return True if the PRNG has *not* been modified, false otherwise.
+ */
+#define BC_RAND_NOTMODIFIED(r) (((r)->inc.lo & 1) == 0)
+
+/**
+ * Return true if the PRNG has not been seeded yet.
+ * @param r The PRNG.
+ * @return True if the PRNG has not been seeded yet, false otherwise.
+ */
+#define BC_RAND_ZERO(r) (!(r)->state.lo && !(r)->state.hi)
+
+/**
+ * Returns a constant built from @a h and @a l.
+ * @param h The high 64 bits.
+ * @param l The low 64 bits.
+ * @return The constant built from @a h and @a l.
+ */
+#define BC_RAND_CONSTANT(h, l) { .lo = (l), .hi = (h) }
+
+/**
+ * Truncates a PCG state to the number of bits in a random integer.
+ * @param s The state to truncate.
+ * @return The truncated state.
+ */
+#define BC_RAND_TRUNC(s) ((s).lo)
+
+/**
+ * Chops a PCG state in half and returns the top bits.
+ * @param s The state to chop.
+ * @return The chopped state's top bits.
+ */
+#define BC_RAND_CHOP(s) ((s).hi)
+
+/**
+ * Returns the rotate amount for a PCG state.
+ * @param s The state to rotate.
+ * @return The semi-rotated state.
+ */
+#define BC_RAND_ROTAMT(s) ((unsigned int) ((s).hi >> 58UL))
+
+/// A 64-bit integer with the bottom 32 bits set.
+#define BC_RAND_BOTTOM32 (((uint_fast64_t) 0xffffffffULL))
+
+/**
+ * Returns the 32-bit truncated value of @a n.
+ * @param n The integer to truncate.
+ * @return The bottom 32 bits of @a n.
+ */
+#define BC_RAND_TRUNC32(n) ((n) & BC_RAND_BOTTOM32)
+
+/**
+ * Returns the second 32 bits of @a n.
+ * @param n The integer to truncate.
+ * @return The second 32 bits of @a n.
+ */
+#define BC_RAND_CHOP32(n) ((n) >> 32)
+
+#endif // BC_RAND_BUILTIN
+
+/// A constant defined by PCG.
+#define BC_RAND_MULTIPLIER \
+ BC_RAND_CONSTANT(2549297995355413924ULL, 4865540595714422341ULL)
+
+/**
+ * Returns the result of a PCG fold.
+ * @param s The state to fold.
+ * @return The folded state.
+ */
+#define BC_RAND_FOLD(s) ((BcRand) (BC_RAND_CHOP(s) ^ BC_RAND_TRUNC(s)))
+
+#else // BC_LONG_BIT >= 64
+
+// If we are using 32-bit longs, we need to set these so.
+#undef BC_RAND_BUILTIN
+#define BC_RAND_BUILTIN (1)
+
+/// The type for random integers.
+typedef uint32_t BcRand;
+
+/// A constant defined by PCG.
+#define BC_RAND_ROTC (31)
+
+/// A typedef for the PCG state.
+typedef uint_fast64_t BcRandState;
+
+/**
+ * Multiply two integers, worrying about overflow.
+ * @param a The first integer.
+ * @param b The second integer.
+ * @return The product of the PCG states.
+ */
+#define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+
+/**
+ * Add two integers, worrying about overflow.
+ * @param a The first integer.
+ * @param b The second integer.
+ * @return The sum of the PCG states.
+ */
+#define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+/**
+ * Multiply two PCG states.
+ * @param a The first PCG state.
+ * @param b The second PCG state.
+ * @return The product of the PCG states.
+ */
+#define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
+
+/**
+ * Add two PCG states.
+ * @param a The first PCG state.
+ * @param b The second PCG state.
+ * @return The sum of the PCG states.
+ */
+#define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
+
+/**
+ * Figure out if the PRNG has been modified. Since the increment of the PRNG has
+ * to be odd, we use the extra bit to store whether it has been modified or not.
+ * @param r The PRNG.
+ * @return True if the PRNG has *not* been modified, false otherwise.
+ */
+#define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
+
+/**
+ * Return true if the PRNG has not been seeded yet.
+ * @param r The PRNG.
+ * @return True if the PRNG has not been seeded yet, false otherwise.
+ */
+#define BC_RAND_ZERO(r) (!(r)->state)
+
+/**
+ * Returns a constant built from a number.
+ * @param n The number.
+ * @return The constant built from @a n.
+ */
+#define BC_RAND_CONSTANT(n) UINT64_C(n)
+
+/// A constant defined by PCG.
+#define BC_RAND_MULTIPLIER BC_RAND_CONSTANT(6364136223846793005)
+
+/**
+ * Truncates a PCG state to the number of bits in a random integer.
+ * @param s The state to truncate.
+ * @return The truncated state.
+ */
+#define BC_RAND_TRUNC(s) ((uint32_t) (s))
+
+/**
+ * Chops a PCG state in half and returns the top bits.
+ * @param s The state to chop.
+ * @return The chopped state's top bits.
+ */
+#define BC_RAND_CHOP(s) ((uint32_t) ((s) >> 32UL))
+
+/**
+ * Returns the rotate amount for a PCG state.
+ * @param s The state to rotate.
+ * @return The semi-rotated state.
+ */
+#define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 59UL))
+
+/**
+ * Returns the result of a PCG fold.
+ * @param s The state to fold.
+ * @return The folded state.
+ */
+#define BC_RAND_FOLD(s) ((BcRand) ((((s) >> 18U) ^ (s)) >> 27U))
+
+#endif // BC_LONG_BIT >= 64
+
+/**
+ * Rotates @a v by @a r bits.
+ * @param v The value to rotate.
+ * @param r The amount to rotate by.
+ * @return The rotated value.
+ */
+#define BC_RAND_ROT(v, r) \
+ ((BcRand) (((v) >> (r)) | ((v) << ((0 - (r)) & BC_RAND_ROTC))))
+
+/// The number of bits in a random integer.
+#define BC_RAND_BITS (sizeof(BcRand) * CHAR_BIT)
+
+/// The number of bits in a PCG state.
+#define BC_RAND_STATE_BITS (sizeof(BcRandState) * CHAR_BIT)
+
+/// The size of a BcNum with the max random integer. This isn't exact; it's
+/// actually rather crude. But it's always enough.
+#define BC_RAND_NUM_SIZE (BC_NUM_BIGDIG_LOG10 * 2 + 2)
+
+/// The mask for how many bits bc_rand_srand() can set per iteration.
+#define BC_RAND_SRAND_BITS ((1 << CHAR_BIT) - 1)
+
+/// The actual RNG data. These are the actual PRNG's.
+typedef struct BcRNGData {
+
+ /// The state.
+ BcRandState state;
+
+ /// The increment and the modified bit.
+ BcRandState inc;
+
+} BcRNGData;
+
+/// The public PRNG. This is just a stack of PRNG's to maintain the globals
+/// stack illusion.
+typedef struct BcRNG {
+
+ /// The stack of PRNG's.
+ BcVec v;
+
+} BcRNG;
+
+/**
+ * Initializes a BcRNG.
+ * @param r The BcRNG to initialize.
+ */
+void bc_rand_init(BcRNG *r);
+
+#if BC_RAND_USE_FREE
+
+/**
+ * Frees a BcRNG. This is only in debug builds because it would only be freed on
+ * exit.
+ * @param r The BcRNG to free.
+ */
+void bc_rand_free(BcRNG *r);
+
+#endif // BC_RAND_USE_FREE
+
+/**
+ * Returns a random integer from the PRNG.
+ * @param r The PRNG.
+ * @return A random integer.
+ */
+BcRand bc_rand_int(BcRNG *r);
+
+/**
+ * Returns a random integer from the PRNG bounded by @a bound. Bias is
+ * eliminated.
+ * @param r The PRNG.
+ * @param bound The bound for the random integer.
+ * @return A bounded random integer.
+ */
+BcRand bc_rand_bounded(BcRNG *r, BcRand bound);
+
+/**
+ * Seed the PRNG with the state in two parts and the increment in two parts.
+ * @param r The PRNG.
+ * @param state1 The first part of the state.
+ * @param state2 The second part of the state.
+ * @param inc1 The first part of the increment.
+ * @param inc2 The second part of the increment.
+ */
+void bc_rand_seed(BcRNG *r, ulong state1, ulong state2, ulong inc1, ulong inc2);
+
+/**
+ * Pushes a new PRNG onto the PRNG stack.
+ * @param r The PRNG.
+ */
+void bc_rand_push(BcRNG *r);
+
+/**
+ * Pops one or all but one items off of the PRNG stack.
+ * @param r The PRNG.
+ * @param reset True if all but one PRNG should be popped off the stack, false
+ * if only one should be popped.
+ */
+void bc_rand_pop(BcRNG *r, bool reset);
+
+/**
+ * Returns, via pointers, the state of the PRNG in pieces.
+ * @param r The PRNG.
+ * @param s1 The return value for the first part of the state.
+ * @param s2 The return value for the second part of the state.
+ * @param i1 The return value for the first part of the increment.
+ * @param i2 The return value for the second part of the increment.
+ */
+void bc_rand_getRands(BcRNG *r, BcRand *s1, BcRand *s2, BcRand *i1, BcRand *i2);
+
+/**
+ * Seed the PRNG with random data.
+ * @param rng The PRNG.
+ */
+void bc_rand_srand(BcRNGData *rng);
+
+/// A reference to a constant multiplier.
+extern const BcRandState bc_rand_multiplier;
+
+#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..2ebb456e83fe
--- /dev/null
+++ b/contrib/bc/include/read.h
@@ -0,0 +1,82 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+/**
+ * Returns true if @a c is a non-ASCII (invalid) char.
+ * @param c The character to test.
+ * @return True if @a c is an invalid char.
+ */
+#define BC_READ_BIN_CHAR(c) (!(c))
+
+/**
+ * Reads a line from stdin after printing prompt, if desired.
+ * @param vec The vector to put the stdin data into.
+ * @param prompt The prompt to print, if desired.
+ */
+BcStatus bc_read_line(BcVec *vec, const char *prompt);
+
+/**
+ * Read a file and return a buffer with the data. The buffer must be freed by
+ * the caller.
+ * @param path The path to the file to read.
+ */
+char* bc_read_file(const char *path);
+
+/**
+ * Helper function for reading characters from stdin. This takes care of a bunch
+ * of complex error handling. Thus, it returns a status instead of throwing an
+ * error, except for fatal errors.
+ * @param vec The vec to put the stdin into.
+ * @param prompt The prompt to print, if desired.
+ */
+BcStatus bc_read_chars(BcVec *vec, const char *prompt);
+
+/**
+ * Read a line from buf into vec.
+ * @param vec The vector to read data into.
+ * @param buf The buffer to read from.
+ * @param buf_len The length of the buffer.
+ */
+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..662f2b89c04d
--- /dev/null
+++ b/contrib/bc/include/status.h
@@ -0,0 +1,793 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * All bc status codes and cross-platform portability.
+ *
+ */
+
+#ifndef BC_STATUS_H
+#define BC_STATUS_H
+
+#include <stdint.h>
+
+// This is used by configure.sh to test for OpenBSD.
+#ifdef BC_TEST_OPENBSD
+#ifdef __OpenBSD__
+#error On OpenBSD without _BSD_SOURCE
+#endif // __OpenBSD__
+#endif // BC_TEST_OPENBSD
+
+#ifndef BC_ENABLED
+#define BC_ENABLED (1)
+#endif // BC_ENABLED
+
+#ifndef DC_ENABLED
+#define DC_ENABLED (1)
+#endif // DC_ENABLED
+
+#ifndef BC_ENABLE_LIBRARY
+#define BC_ENABLE_LIBRARY (0)
+#endif // BC_ENABLE_LIBRARY
+
+// This is error checking for fuzz builds.
+#if BC_ENABLE_AFL
+#ifndef __AFL_HAVE_MANUAL_CONTROL
+#error Must compile with afl-clang-fast or afl-clang-lto for fuzzing
+#endif // __AFL_HAVE_MANUAL_CONTROL
+#endif // BC_ENABLE_AFL
+
+#ifndef BC_ENABLE_MEMCHECK
+#define BC_ENABLE_MEMCHECK (0)
+#endif // BC_ENABLE_MEMCHECK
+
+/**
+ * Mark a variable as unused.
+ * @param e The variable to mark as unused.
+ */
+#define BC_UNUSED(e) ((void) (e))
+
+// If users want, they can define this to something like __builtin_expect(e, 1).
+// It might give a performance improvement.
+#ifndef BC_LIKELY
+
+/**
+ * Mark a branch expression as likely.
+ * @param e The expression to mark as likely.
+ */
+#define BC_LIKELY(e) (e)
+
+#endif // BC_LIKELY
+
+// If users want, they can define this to something like __builtin_expect(e, 0).
+// It might give a performance improvement.
+#ifndef BC_UNLIKELY
+
+/**
+ * Mark a branch expression as unlikely.
+ * @param e The expression to mark as unlikely.
+ */
+#define BC_UNLIKELY(e) (e)
+
+#endif // BC_UNLIKELY
+
+/**
+ * Mark a branch expression as an error, if true.
+ * @param e The expression to mark as an error, if true.
+ */
+#define BC_ERR(e) BC_UNLIKELY(e)
+
+/**
+ * Mark a branch expression as not an error, if true.
+ * @param e The expression to mark as not an error, if true.
+ */
+#define BC_NO_ERR(s) BC_LIKELY(s)
+
+// Disable extra debug code by default.
+#ifndef BC_DEBUG_CODE
+#define BC_DEBUG_CODE (0)
+#endif // BC_DEBUG_CODE
+
+// We want to be able to use _Noreturn on C11 compilers.
+#if __STDC_VERSION__ >= 201100L
+
+#include <stdnoreturn.h>
+#define BC_NORETURN _Noreturn
+#define BC_C11 (1)
+
+#else // __STDC_VERSION__
+
+#define BC_NORETURN
+#define BC_MUST_RETURN
+#define BC_C11 (0)
+
+#endif // __STDC_VERSION__
+
+#define BC_HAS_UNREACHABLE (0)
+#define BC_HAS_COMPUTED_GOTO (0)
+
+// GCC and Clang complain if fallthroughs are not marked with their special
+// attribute. Jerks. This creates a define for marking the fallthroughs that is
+// nothing on other compilers.
+#if defined(__clang__) || defined(__GNUC__)
+
+#if defined(__has_attribute)
+
+#if __has_attribute(fallthrough)
+#define BC_FALLTHROUGH __attribute__((fallthrough));
+#else // __has_attribute(fallthrough)
+#define BC_FALLTHROUGH
+#endif // __has_attribute(fallthrough)
+
+#ifdef __GNUC__
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#undef BC_HAS_UNREACHABLE
+#define BC_HAS_UNREACHABLE (1)
+#endif // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+
+#else // __GNUC__
+
+#if __clang_major__ >= 4
+#undef BC_HAS_UNREACHABLE
+#define BC_HAS_UNREACHABLE (1)
+#endif // __clang_major__ >= 4
+
+#endif // __GNUC__
+
+#else // defined(__has_attribute)
+#define BC_FALLTHROUGH
+#endif // defined(__has_attribute)
+#else // defined(__clang__) || defined(__GNUC__)
+#define BC_FALLTHROUGH
+#endif // defined(__clang__) || defined(__GNUC__)
+
+#if BC_HAS_UNREACHABLE
+
+#define BC_UNREACHABLE __builtin_unreachable();
+
+#else // BC_HAS_UNREACHABLE
+
+#ifdef _WIN32
+
+#define BC_UNREACHABLE __assume(0);
+
+#else // _WIN32
+
+#define BC_UNREACHABLE
+
+#endif // _WIN32
+
+#endif // BC_HAS_UNREACHABLE
+
+#ifdef __GNUC__
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+
+#undef BC_HAS_COMPUTED_GOTO
+#define BC_HAS_COMPUTED_GOTO (1)
+
+#endif // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+
+#endif // __GNUC__
+
+#ifdef __clang__
+
+#if __clang_major__ >= 4
+
+#undef BC_HAS_COMPUTED_GOTO
+#define BC_HAS_COMPUTED_GOTO (1)
+
+#endif // __clang_major__ >= 4
+
+#endif // __GNUC__
+
+#ifdef BC_NO_COMPUTED_GOTO
+
+#undef BC_HAS_COMPUTED_GOTO
+#define BC_HAS_COMPUTED_GOTO (0)
+
+#endif // BC_NO_COMPUTED_GOTO
+
+#ifdef __GNUC__
+#ifdef __OpenBSD__
+// The OpenBSD GCC doesn't like inline.
+#define inline
+#endif // __OpenBSD__
+#endif // __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
+
+// Yes, this has to be here.
+#include <bcl.h>
+
+// All of these set defaults for settings.
+
+#if BC_ENABLED
+
+#ifndef BC_DEFAULT_BANNER
+#define BC_DEFAULT_BANNER (0)
+#endif // BC_DEFAULT_BANNER
+
+#endif // BC_ENABLED
+
+#ifndef BC_DEFAULT_SIGINT_RESET
+#define BC_DEFAULT_SIGINT_RESET (1)
+#endif // BC_DEFAULT_SIGINT_RESET
+
+#ifndef BC_DEFAULT_TTY_MODE
+#define BC_DEFAULT_TTY_MODE (1)
+#endif // BC_DEFAULT_TTY_MODE
+
+#ifndef BC_DEFAULT_PROMPT
+#define BC_DEFAULT_PROMPT BC_DEFAULT_TTY_MODE
+#endif // BC_DEFAULT_PROMPT
+
+// All of these set defaults for settings.
+#ifndef DC_DEFAULT_SIGINT_RESET
+#define DC_DEFAULT_SIGINT_RESET (1)
+#endif // DC_DEFAULT_SIGINT_RESET
+
+#ifndef DC_DEFAULT_TTY_MODE
+#define DC_DEFAULT_TTY_MODE (0)
+#endif // DC_DEFAULT_TTY_MODE
+
+#ifndef DC_DEFAULT_HISTORY
+#define DC_DEFAULT_HISTORY DC_DEFAULT_TTY_MODE
+#endif // DC_DEFAULT_HISTORY
+
+#ifndef DC_DEFAULT_PROMPT
+#define DC_DEFAULT_PROMPT DC_DEFAULT_TTY_MODE
+#endif // DC_DEFAULT_PROMPT
+
+/// Statuses, which mark either which category of error happened, or some other
+/// status that matters.
+typedef enum BcStatus {
+
+ /// Normal status.
+ BC_STATUS_SUCCESS = 0,
+
+ /// Math error.
+ BC_STATUS_ERROR_MATH,
+
+ /// Parse (and lex) error.
+ BC_STATUS_ERROR_PARSE,
+
+ /// Runtime error.
+ BC_STATUS_ERROR_EXEC,
+
+ /// Fatal error.
+ BC_STATUS_ERROR_FATAL,
+
+ /// EOF status.
+ BC_STATUS_EOF,
+
+ /// Quit status. This means that bc/dc is in the process of quitting.
+ BC_STATUS_QUIT,
+
+} BcStatus;
+
+/// Errors, which are more specific errors.
+typedef enum BcErr {
+
+ // Math errors.
+
+ /// Negative number used when not allowed.
+ BC_ERR_MATH_NEGATIVE,
+
+ /// Non-integer used when not allowed.
+ BC_ERR_MATH_NON_INTEGER,
+
+ /// Conversion to a hardware integer would overflow.
+ BC_ERR_MATH_OVERFLOW,
+
+ /// Divide by zero.
+ BC_ERR_MATH_DIVIDE_BY_ZERO,
+
+ // Fatal errors.
+
+ /// An allocation or reallocation failed.
+ BC_ERR_FATAL_ALLOC_ERR,
+
+ /// I/O failure.
+ BC_ERR_FATAL_IO_ERR,
+
+ /// File error, such as permissions or file does not exist.
+ BC_ERR_FATAL_FILE_ERR,
+
+ /// File is binary, not text, error.
+ BC_ERR_FATAL_BIN_FILE,
+
+ /// Attempted to read a directory as a file error.
+ BC_ERR_FATAL_PATH_DIR,
+
+ /// Invalid option error.
+ BC_ERR_FATAL_OPTION,
+
+ /// Option with required argument not given an argument.
+ BC_ERR_FATAL_OPTION_NO_ARG,
+
+ /// Option with no argument given an argument.
+ BC_ERR_FATAL_OPTION_ARG,
+
+ /// Option argument is invalid.
+ BC_ERR_FATAL_ARG,
+
+ // Runtime errors.
+
+ /// Invalid ibase value.
+ BC_ERR_EXEC_IBASE,
+
+ /// Invalid obase value.
+ BC_ERR_EXEC_OBASE,
+
+ /// Invalid scale value.
+ BC_ERR_EXEC_SCALE,
+
+ /// Invalid expression parsed by read().
+ BC_ERR_EXEC_READ_EXPR,
+
+ /// read() used within an expression given to a read() call.
+ BC_ERR_EXEC_REC_READ,
+
+ /// Type error.
+ BC_ERR_EXEC_TYPE,
+
+ /// Stack has too few elements error.
+ BC_ERR_EXEC_STACK,
+
+ /// Register stack has too few elements error.
+ BC_ERR_EXEC_STACK_REGISTER,
+
+ /// Wrong number of arguments error.
+ BC_ERR_EXEC_PARAMS,
+
+ /// Undefined function error.
+ BC_ERR_EXEC_UNDEF_FUNC,
+
+ /// Void value used in an expression error.
+ BC_ERR_EXEC_VOID_VAL,
+
+ // Parse (and lex errors).
+
+ /// EOF encountered when not expected error.
+ BC_ERR_PARSE_EOF,
+
+ /// Invalid character error.
+ BC_ERR_PARSE_CHAR,
+
+ /// Invalid string (no ending quote) error.
+ BC_ERR_PARSE_STRING,
+
+ /// Invalid comment (no end found) error.
+ BC_ERR_PARSE_COMMENT,
+
+ /// Invalid token encountered error.
+ BC_ERR_PARSE_TOKEN,
+
+#if BC_ENABLED
+
+ /// Invalid expression error.
+ BC_ERR_PARSE_EXPR,
+
+ /// Expression is empty error.
+ BC_ERR_PARSE_EMPTY_EXPR,
+
+ /// Print statement is invalid error.
+ BC_ERR_PARSE_PRINT,
+
+ /// Function definition is invalid error.
+ BC_ERR_PARSE_FUNC,
+
+ /// Assignment is invalid error.
+ BC_ERR_PARSE_ASSIGN,
+
+ /// No auto identifiers given for an auto statement error.
+ BC_ERR_PARSE_NO_AUTO,
+
+ /// Duplicate local (parameter or auto) error.
+ BC_ERR_PARSE_DUP_LOCAL,
+
+ /// Invalid block (within braces) error.
+ BC_ERR_PARSE_BLOCK,
+
+ /// Invalid return statement for void functions.
+ BC_ERR_PARSE_RET_VOID,
+
+ /// Reference attached to a variable, not an array, error.
+ BC_ERR_PARSE_REF_VAR,
+
+ // POSIX-only errors.
+
+ /// Name length greater than 1 error.
+ BC_ERR_POSIX_NAME_LEN,
+
+ /// Non-POSIX comment used error.
+ BC_ERR_POSIX_COMMENT,
+
+ /// Non-POSIX keyword error.
+ BC_ERR_POSIX_KW,
+
+ /// Non-POSIX . (last) error.
+ BC_ERR_POSIX_DOT,
+
+ /// Non-POSIX return error.
+ BC_ERR_POSIX_RET,
+
+ /// Non-POSIX boolean operator used error.
+ BC_ERR_POSIX_BOOL,
+
+ /// POSIX relation operator used outside if, while, or for statements error.
+ BC_ERR_POSIX_REL_POS,
+
+ /// Multiple POSIX relation operators used in an if, while, or for statement
+ /// error.
+ BC_ERR_POSIX_MULTIREL,
+
+ /// Empty statements in POSIX for loop error.
+ BC_ERR_POSIX_FOR,
+
+ /// Non-POSIX exponential (scientific or engineering) number used error.
+ BC_ERR_POSIX_EXP_NUM,
+
+ /// Non-POSIX array reference error.
+ BC_ERR_POSIX_REF,
+
+ /// Non-POSIX void error.
+ BC_ERR_POSIX_VOID,
+
+ /// Non-POSIX brace position used error.
+ BC_ERR_POSIX_BRACE,
+
+ /// String used in expression.
+ BC_ERR_POSIX_EXPR_STRING,
+
+#endif // BC_ENABLED
+
+ // Number of elements.
+ BC_ERR_NELEMS,
+
+#if BC_ENABLED
+
+ /// A marker for the start of POSIX errors.
+ BC_ERR_POSIX_START = BC_ERR_POSIX_NAME_LEN,
+
+ /// A marker for the end of POSIX errors.
+ BC_ERR_POSIX_END = BC_ERR_POSIX_EXPR_STRING,
+
+#endif // BC_ENABLED
+
+} BcErr;
+
+// The indices of each category of error in bc_errs[], and used in bc_err_ids[]
+// to associate actual errors with their categories.
+
+/// Math error category.
+#define BC_ERR_IDX_MATH (0)
+
+/// Parse (and lex) error category.
+#define BC_ERR_IDX_PARSE (1)
+
+/// Runtime error category.
+#define BC_ERR_IDX_EXEC (2)
+
+/// Fatal error category.
+#define BC_ERR_IDX_FATAL (3)
+
+/// Number of categories.
+#define BC_ERR_IDX_NELEMS (4)
+
+// If bc is enabled, we add an extra category for POSIX warnings.
+#if BC_ENABLED
+
+/// POSIX warning category.
+#define BC_ERR_IDX_WARN (BC_ERR_IDX_NELEMS)
+
+#endif // BC_ENABLED
+
+/// Do a longjmp(). This is what to use when activating an "exception", i.e., a
+/// longjmp(). With debug code, it will print the name of the function it jumped
+/// from.
+#if BC_DEBUG_CODE
+#define BC_JMP bc_vm_jmp(__func__)
+#else // BC_DEBUG_CODE
+#define BC_JMP bc_vm_jmp()
+#endif // BC_DEBUG_CODE
+
+/// Returns true if an exception is in flight, false otherwise.
+#define BC_SIG_EXC \
+ BC_UNLIKELY(vm.status != (sig_atomic_t) BC_STATUS_SUCCESS || vm.sig)
+
+/// Returns true if there is *no* exception in flight, false otherwise.
+#define BC_NO_SIG_EXC \
+ BC_LIKELY(vm.status == (sig_atomic_t) BC_STATUS_SUCCESS && !vm.sig)
+
+#ifndef NDEBUG
+
+/// Assert that signals are locked. There are non-async-signal-safe functions in
+/// bc, and they *must* have signals locked. Other functions are expected to
+/// *not* have signals locked, for reasons. So this is a pre-built assert
+/// (no-op in non-debug mode) that check that signals are locked.
+#define BC_SIG_ASSERT_LOCKED do { assert(vm.sig_lock); } while (0)
+
+/// Assert that signals are unlocked. There are non-async-signal-safe functions
+/// in bc, and they *must* have signals locked. Other functions are expected to
+/// *not* have signals locked, for reasons. So this is a pre-built assert
+/// (no-op in non-debug mode) that check that signals are unlocked.
+#define BC_SIG_ASSERT_NOT_LOCKED do { assert(vm.sig_lock == 0); } while (0)
+
+#else // NDEBUG
+
+/// Assert that signals are locked. There are non-async-signal-safe functions in
+/// bc, and they *must* have signals locked. Other functions are expected to
+/// *not* have signals locked, for reasons. So this is a pre-built assert
+/// (no-op in non-debug mode) that check that signals are locked.
+#define BC_SIG_ASSERT_LOCKED
+
+/// Assert that signals are unlocked. There are non-async-signal-safe functions
+/// in bc, and they *must* have signals locked. Other functions are expected to
+/// *not* have signals locked, for reasons. So this is a pre-built assert
+/// (no-op in non-debug mode) that check that signals are unlocked.
+#define BC_SIG_ASSERT_NOT_LOCKED
+
+#endif // NDEBUG
+
+/// Locks signals.
+#define BC_SIG_LOCK \
+ do { \
+ BC_SIG_ASSERT_NOT_LOCKED; \
+ vm.sig_lock = 1; \
+ } while (0)
+
+/// Unlocks signals. If a signal happened, then this will cause a jump.
+#define BC_SIG_UNLOCK \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ vm.sig_lock = 0; \
+ if (vm.sig) BC_JMP; \
+ } while (0)
+
+/// Locks signals, regardless of if they are already locked. This is really only
+/// used after labels that longjmp() goes to after the jump because the cleanup
+/// code must have signals locked, and BC_LONGJMP_CONT will unlock signals if it
+/// doesn't jump.
+#define BC_SIG_MAYLOCK \
+ do { \
+ vm.sig_lock = 1; \
+ } while (0)
+
+/// Unlocks signals, regardless of if they were already unlocked. If a signal
+/// happened, then this will cause a jump.
+#define BC_SIG_MAYUNLOCK \
+ do { \
+ vm.sig_lock = 0; \
+ if (vm.sig) BC_JMP; \
+ } while (0)
+
+/*
+ * Locks signals, but stores the old lock state, to be restored later by
+ * BC_SIG_TRYUNLOCK.
+ * @param v The variable to store the old lock state to.
+ */
+#define BC_SIG_TRYLOCK(v) \
+ do { \
+ v = vm.sig_lock; \
+ vm.sig_lock = 1; \
+ } while (0)
+
+/* Restores the previous state of a signal lock, and if it is now unlocked,
+ * initiates an exception/jump.
+ * @param v The old lock state.
+ */
+#define BC_SIG_TRYUNLOCK(v) \
+ do { \
+ vm.sig_lock = (v); \
+ if (!(v) && vm.sig) BC_JMP; \
+ } while (0)
+
+/**
+ * Sets a jump, and sets it up as well so that if a longjmp() happens, bc will
+ * immediately goto a label where some cleanup code is. This one assumes that
+ * signals are not locked and will lock them, set the jump, and unlock them.
+ * Setting the jump also includes pushing the jmp_buf onto the jmp_buf stack.
+ * This grows the jmp_bufs vector first to prevent a fatal error from happening
+ * after the setjmp(). This is done because BC_SETJMP(l) is assumed to be used
+ * *before* the actual initialization calls that need the setjmp().
+ * param l The label to jump to on a longjmp().
+ */
+#define BC_SETJMP(l) \
+ do { \
+ sigjmp_buf sjb; \
+ BC_SIG_LOCK; \
+ bc_vec_grow(&vm.jmp_bufs, 1); \
+ if (sigsetjmp(sjb, 0)) { \
+ assert(BC_SIG_EXC); \
+ goto l; \
+ } \
+ bc_vec_push(&vm.jmp_bufs, &sjb); \
+ BC_SIG_UNLOCK; \
+ } while (0)
+
+/**
+ * Sets a jump like BC_SETJMP, but unlike BC_SETJMP, it assumes signals are
+ * locked and will just set the jump. This does *not* have a call to
+ * bc_vec_grow() because it is assumed that BC_SETJMP_LOCKED(l) is used *after*
+ * the initializations that need the setjmp().
+ * param l The label to jump to on a longjmp().
+ */
+#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)
+
+/// Used after cleanup labels set by BC_SETJMP and BC_SETJMP_LOCKED to jump to
+/// the next place. This is what continues the stack unwinding. This basically
+/// copies BC_SIG_UNLOCK into itself, but that is because its condition for
+/// jumping is BC_SIG_EXC, not just that a signal happened.
+#define BC_LONGJMP_CONT \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ if (!vm.sig_pop) bc_vec_pop(&vm.jmp_bufs); \
+ vm.sig_lock = 0; \
+ if (BC_SIG_EXC) BC_JMP; \
+ } while (0)
+
+/// Unsets a jump. It always assumes signals are locked. This basically just
+/// pops a jmp_buf off of the stack of jmp_bufs, and since the jump mechanism
+/// always jumps to the location at the top of the stack, this effectively
+/// undoes a setjmp().
+#define BC_UNSETJMP \
+ do { \
+ BC_SIG_ASSERT_LOCKED; \
+ bc_vec_pop(&vm.jmp_bufs); \
+ } while (0)
+
+/// Stops a stack unwinding. Technically, a stack unwinding needs to be done
+/// manually, but it will always be done unless certain flags are cleared. This
+/// clears the flags.
+#define BC_LONGJMP_STOP \
+ do { \
+ vm.sig_pop = 0; \
+ vm.sig = 0; \
+ } while (0)
+
+// Various convenience macros for calling the bc's error handling routine.
+#if BC_ENABLE_LIBRARY
+
+/**
+ * Call bc's error handling routine.
+ * @param e The error.
+ * @param l The line of the script that the error happened.
+ * @param ... Extra arguments for error messages as necessary.
+ */
+#define bc_error(e, l, ...) (bc_vm_handleError((e)))
+
+/**
+ * Call bc's error handling routine.
+ * @param e The error.
+ */
+#define bc_err(e) (bc_vm_handleError((e)))
+
+/**
+ * Call bc's error handling routine.
+ * @param e The error.
+ */
+#define bc_verr(e, ...) (bc_vm_handleError((e)))
+
+#else // BC_ENABLE_LIBRARY
+
+/**
+ * Call bc's error handling routine.
+ * @param e The error.
+ * @param l The line of the script that the error happened.
+ * @param ... Extra arguments for error messages as necessary.
+ */
+#define bc_error(e, l, ...) (bc_vm_handleError((e), (l), __VA_ARGS__))
+
+/**
+ * Call bc's error handling routine.
+ * @param e The error.
+ */
+#define bc_err(e) (bc_vm_handleError((e), 0))
+
+/**
+ * Call bc's error handling routine.
+ * @param e The error.
+ */
+#define bc_verr(e, ...) (bc_vm_handleError((e), 0, __VA_ARGS__))
+
+#endif // BC_ENABLE_LIBRARY
+
+/**
+ * Returns true if status @a s is an error, false otherwise.
+ * @param s The status to test.
+ * @return True if @a s is an error, false otherwise.
+ */
+#define BC_STATUS_IS_ERROR(s) \
+ ((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL)
+
+// Convenience macros that can be placed at the beginning and exits of functions
+// for easy marking of where functions are entered and exited.
+#if BC_DEBUG_CODE
+#define BC_FUNC_ENTER \
+ do { \
+ size_t bc_func_enter_i; \
+ for (bc_func_enter_i = 0; bc_func_enter_i < vm.func_depth; \
+ ++bc_func_enter_i) \
+ { \
+ bc_file_puts(&vm.ferr, bc_flush_none, " "); \
+ } \
+ vm.func_depth += 1; \
+ bc_file_printf(&vm.ferr, "Entering %s\n", __func__); \
+ bc_file_flush(&vm.ferr, bc_flush_none); \
+ } while (0);
+
+#define BC_FUNC_EXIT \
+ do { \
+ size_t bc_func_enter_i; \
+ vm.func_depth -= 1; \
+ for (bc_func_enter_i = 0; bc_func_enter_i < vm.func_depth; \
+ ++bc_func_enter_i) \
+ { \
+ bc_file_puts(&vm.ferr, bc_flush_none, " "); \
+ } \
+ bc_file_printf(&vm.ferr, "Leaving %s\n", __func__); \
+ bc_file_flush(&vm.ferr, bc_flush_none); \
+ } while (0);
+#else // BC_DEBUG_CODE
+#define BC_FUNC_ENTER
+#define BC_FUNC_EXIT
+#endif // BC_DEBUG_CODE
+
+#endif // BC_STATUS_H
diff --git a/contrib/bc/include/vector.h b/contrib/bc/include/vector.h
new file mode 100644
index 000000000000..c35d22c9eff7
--- /dev/null
+++ b/contrib/bc/include/vector.h
@@ -0,0 +1,461 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for bc vectors (resizable arrays).
+ *
+ */
+
+#ifndef BC_VECTOR_H
+#define BC_VECTOR_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <status.h>
+
+/// An invalid index for a map to mark when an item does not exist.
+#define BC_VEC_INVALID_IDX (SIZE_MAX)
+
+/// The starting capacity for vectors. This is based on the minimum allocation
+/// for 64-bit systems.
+#define BC_VEC_START_CAP (UINTMAX_C(1)<<5)
+
+/// An alias.
+typedef unsigned char uchar;
+
+/**
+ * A destructor. Frees the object that @a ptr points to. This is used by vectors
+ * to free the memory they own.
+ * @param ptr Pointer to the data to free.
+ */
+typedef void (*BcVecFree)(void *ptr);
+
+// Forward declaration.
+struct BcId;
+
+#if BC_LONG_BIT >= 64
+
+/// An integer to shrink the size of a vector by using these instead of size_t.
+typedef uint32_t BcSize;
+
+#else // BC_LONG_BIT >= 64
+
+/// An integer to shrink the size of a vector by using these instead of size_t.
+typedef uint16_t BcSize;
+
+#endif // BC_LONG_BIT >= 64
+
+/// An enum of all of the destructors. We use an enum to save space.
+typedef enum BcDtorType {
+
+ /// No destructor needed.
+ BC_DTOR_NONE,
+
+ /// Vector destructor.
+ BC_DTOR_VEC,
+
+ /// BcNum destructor.
+ BC_DTOR_NUM,
+
+#if !BC_ENABLE_LIBRARY
+
+#ifndef NDEBUG
+
+ /// BcFunc destructor.
+ BC_DTOR_FUNC,
+
+#endif // NDEBUG
+
+ /// BcSlab destructor.
+ BC_DTOR_SLAB,
+
+ /// BcConst destructor.
+ BC_DTOR_CONST,
+
+ /// BcResult destructor.
+ BC_DTOR_RESULT,
+
+#if BC_ENABLE_HISTORY
+
+ /// String destructor for history, which is *special*.
+ BC_DTOR_HISTORY_STRING,
+
+#endif // BC_ENABLE_HISTORY
+#else // !BC_ENABLE_LIBRARY
+
+ /// Destructor for bcl numbers.
+ BC_DTOR_BCL_NUM,
+
+#endif // !BC_ENABLE_LIBRARY
+
+} BcDtorType;
+
+/// The actual vector struct.
+typedef struct BcVec {
+
+ /// The vector array itself. This uses a char* because it is compatible with
+ /// pointers of all other types, and I can do pointer arithmetic on it.
+ char *restrict v;
+
+ /// The length of the vector, which is how many items actually exist.
+ size_t len;
+
+ /// The capacity of the vector, which is how many items can fit in the
+ /// current allocation.
+ size_t cap;
+
+ /// The size of the items in the vector, as returned by sizeof().
+ BcSize size;
+
+ /// The destructor as a BcDtorType enum.
+ BcSize dtor;
+
+} BcVec;
+
+/**
+ * Initializes a vector.
+ * @param v The vector to initialize.
+ * @param esize The size of the elements, as returned by sizeof().
+ * @param dtor The destructor of the elements, as a BcDtorType enum.
+ */
+void bc_vec_init(BcVec *restrict v, size_t esize, BcDtorType dtor);
+
+/**
+ * Expands the vector to have a capacity of @a req items, if it doesn't have
+ * enough already.
+ * @param v The vector to expand.
+ * @param req The requested capacity.
+ */
+void bc_vec_expand(BcVec *restrict v, size_t req);
+
+/**
+ * Grow a vector by at least @a n elements.
+ * @param v The vector to grow.
+ * @param n The number of elements to grow the vector by.
+ */
+void bc_vec_grow(BcVec *restrict v, size_t n);
+
+/**
+ * Pops @a n items off the back of the vector. The vector must have at least
+ * @a n elements.
+ * @param v The vector to pop off of.
+ * @param n The number of elements to pop off.
+ */
+void bc_vec_npop(BcVec *restrict v, size_t n);
+
+/**
+ * Pops @a n items, starting at index @a idx, off the vector. The vector must
+ * have at least @a n elements after the @a idx index. Any remaining elements at
+ * the end are moved up to fill the hole.
+ * @param v The vector to pop off of.
+ * @param n The number of elements to pop off.
+ * @param idx The index to start popping at.
+ */
+void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx);
+
+/**
+ * Pushes one item on the back of the vector. It does a memcpy(), but it assumes
+ * that the vector takes ownership of the data.
+ * @param v The vector to push onto.
+ * @param data A pointer to the data to push.
+ */
+void bc_vec_push(BcVec *restrict v, const void *data);
+
+/**
+ * Pushes @a n items on the back of the vector. It does a memcpy(), but it
+ * assumes that the vector takes ownership of the data.
+ * @param v The vector to push onto.
+ * @param data A pointer to the elements of data to push.
+ */
+void bc_vec_npush(BcVec *restrict v, size_t n, const void *data);
+
+/**
+ * Push an empty element and return a pointer to it. This is done as an
+ * optimization where initializing an item needs a pointer anyway. It removes an
+ * extra memcpy().
+ * @param v The vector to push onto.
+ * @return A pointer to the newly-pushed element.
+ */
+void* bc_vec_pushEmpty(BcVec *restrict v);
+
+/**
+ * Pushes a byte onto a bytecode vector. This is a convenience function for the
+ * parsers pushing instructions. The vector must be a bytecode vector.
+ * @param v The vector to push onto.
+ * @param data The byte to push.
+ */
+void bc_vec_pushByte(BcVec *restrict v, uchar data);
+
+/**
+ * Pushes and index onto a bytecode vector. The vector must be a bytecode
+ * vector. For more info about why and how this is done, see the development
+ * manual (manuals/development#bytecode-indices).
+ * @param v The vector to push onto.
+ * @param idx The index to push.
+ */
+void bc_vec_pushIndex(BcVec *restrict v, size_t idx);
+
+/**
+ * Push an item onto the vector at a certain index. The index must be valid
+ * (either exists or is equal to the length of the vector). The elements at that
+ * index and after are moved back one element and kept in the same order. This
+ * is how the map vectors are kept sorted.
+ * @param v The vector to push onto.
+ * @param data A pointer to the data to push.
+ * @param idx The index to push at.
+ */
+void bc_vec_pushAt(BcVec *restrict v, const void *data, size_t idx);
+
+/**
+ * Empties the vector and sets it to the string. The vector must be a valid
+ * vector and must have chars as its elements.
+ * @param v The vector to set to the string.
+ * @param len The length of the string. This can be less than the actual length
+ * of the string, but must never be more.
+ * @param str The string to push.
+ */
+void bc_vec_string(BcVec *restrict v, size_t len, const char *restrict str);
+
+/**
+ * Appends the string to the end of the vector, which must be holding a string
+ * (nul byte-terminated) already.
+ * @param v The vector to append to.
+ * @param str The string to append (by copying).
+ */
+void bc_vec_concat(BcVec *restrict v, const char *restrict str);
+
+/**
+ * Empties a vector and pushes a nul-byte at the first index. The vector must be
+ * a char vector.
+ */
+void bc_vec_empty(BcVec *restrict v);
+
+#if BC_ENABLE_HISTORY
+
+/**
+ * Replaces an item at a particular index. No elements are moved. The index must
+ * exist.
+ * @param v The vector to replace an item on.
+ * @param idx The index of the item to replace.
+ * @param data The data to replace the item with.
+ */
+void bc_vec_replaceAt(BcVec *restrict v, size_t idx, const void *data);
+
+#endif // BC_ENABLE_HISTORY
+
+/**
+ * Returns a pointer to the item in the vector at the index. This is the key
+ * function for vectors. The index must exist.
+ * @param v The vector.
+ * @param idx The index to the item to get a pointer to.
+ * @return A pointer to the item at @a idx.
+ */
+void* bc_vec_item(const BcVec *restrict v, size_t idx);
+
+/**
+ * Returns a pointer to the item in the vector at the index, reversed. This is
+ * another key function for vectors. The index must exist.
+ * @param v The vector.
+ * @param idx The index to the item to get a pointer to.
+ * @return A pointer to the item at len - @a idx - 1.
+ */
+void* bc_vec_item_rev(const BcVec *restrict v, size_t idx);
+
+/**
+ * Zeros a vector. The vector must not be allocated.
+ * @param v The vector to clear.
+ */
+void bc_vec_clear(BcVec *restrict v);
+
+/**
+ * Frees a vector and its elements. This is a destructor.
+ * @param vec A vector as a void pointer.
+ */
+void bc_vec_free(void *vec);
+
+/**
+ * Attempts to insert an item into a map and returns true if it succeeded, false
+ * if the item already exists.
+ * @param v The map vector to insert into.
+ * @param name The name of the item to insert. This name is assumed to be owned
+ * by another entity.
+ * @param idx The index of the partner array where the actual item is.
+ * @param i A pointer to an index that will be set to the index of the item
+ * in the map.
+ * @return True if the item was inserted, false if the item already exists.
+ */
+bool bc_map_insert(BcVec *restrict v, const char *name,
+ size_t idx, size_t *restrict i);
+
+/**
+ * Returns the index of the item with @a name in the map, or BC_VEC_INVALID_IDX
+ * if it doesn't exist.
+ * @param v The map vector.
+ * @param name The name of the item to find.
+ * @return The index in the map of the item with @a name, or
+ * BC_VEC_INVALID_IDX if the item does not exist.
+ */
+size_t bc_map_index(const BcVec *restrict v, const char *name);
+
+#if DC_ENABLED
+
+/**
+ * Returns the name of the item at index @a idx in the map.
+ * @param v The map vector.
+ * @param idx The index.
+ * @return The name of the item at @a idx.
+ */
+const char* bc_map_name(const BcVec *restrict v, size_t idx);
+
+#endif // DC_ENABLED
+
+/**
+ * Pops one item off of the vector.
+ * @param v The vector to pop one item off of.
+ */
+#define bc_vec_pop(v) (bc_vec_npop((v), 1))
+
+/**
+ * Pops all items off of the vector.
+ * @param v The vector to pop all items off of.
+ */
+#define bc_vec_popAll(v) (bc_vec_npop((v), (v)->len))
+
+/**
+ * Return a pointer to the last item in the vector, or first if it's being
+ * treated as a stack.
+ * @param v The vector to get the top of stack of.
+ */
+#define bc_vec_top(v) (bc_vec_item_rev((v), 0))
+
+/**
+ * Initializes a vector to serve as a map.
+ * @param v The vector to initialize.
+ */
+#define bc_map_init(v) (bc_vec_init((v), sizeof(BcId), BC_DTOR_NONE))
+
+/// A reference to the array of destructors.
+extern const BcVecFree bc_vec_dtors[];
+
+#if !BC_ENABLE_LIBRARY
+
+/// The allocated size of slabs.
+#define BC_SLAB_SIZE (4096)
+
+/// A slab for allocating strings.
+typedef struct BcSlab {
+
+ /// The actual allocation.
+ char *s;
+
+ /// How many bytes of the slab are taken.
+ size_t len;
+
+} BcSlab;
+
+/**
+ * Frees a slab. This is a destructor.
+ * @param slab The slab as a void pointer.
+ */
+void bc_slab_free(void *slab);
+
+/**
+ * Initializes a slab vector.
+ * @param v The vector to initialize.
+ */
+void bc_slabvec_init(BcVec *restrict v);
+
+/**
+ * Duplicates the string using slabs in the slab vector.
+ * @param v The slab vector.
+ * @param str The string to duplicate.
+ * @return A pointer to the duplicated string, owned by the slab vector.
+ */
+char* bc_slabvec_strdup(BcVec *restrict v, const char *str);
+
+#if BC_ENABLED
+
+/**
+ * Undoes the last allocation on the slab vector. This allows bc to have a
+ * heap-based stacks for strings. This is used by the bc parser.
+ */
+void bc_slabvec_undo(BcVec *restrict v, size_t len);
+
+#endif // BC_ENABLED
+
+/**
+ * Clears a slab vector. This deallocates all but the first slab and clears the
+ * first slab.
+ * @param v The slab vector to clear.
+ */
+void bc_slabvec_clear(BcVec *restrict v);
+
+#if BC_DEBUG_CODE
+
+/**
+ * Prints all of the items in a slab vector, in order.
+ * @param v The vector whose items will be printed.
+ */
+void bc_slabvec_print(BcVec *v, const char *func);
+
+#endif // BC_DEBUG_CODE
+
+/// A convenience macro for freeing a vector of slabs.
+#define bc_slabvec_free bc_vec_free
+
+#ifndef _WIN32
+
+/**
+ * A macro to get rid of a warning on Windows.
+ * @param d The destination string.
+ * @param l The length of the destination string. This has to be big enough to
+ * contain @a s.
+ * @param s The source string.
+ */
+#define bc_strcpy(d, l, s) strcpy(d, s)
+
+#else // _WIN32
+
+/**
+ * A macro to get rid of a warning on Windows.
+ * @param d The destination string.
+ * @param l The length of the destination string. This has to be big enough to
+ * contain @a s.
+ * @param s The source string.
+ */
+#define bc_strcpy(d, l, s) strcpy_s(d, l, s)
+
+#endif // _WIN32
+
+#endif // !BC_ENABLE_LIBRARY
+
+#endif // BC_VECTOR_H
diff --git a/contrib/bc/include/version.h b/contrib/bc/include/version.h
new file mode 100644
index 000000000000..3be823189b8f
--- /dev/null
+++ b/contrib/bc/include/version.h
@@ -0,0 +1,42 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The version of bc.
+ *
+ */
+
+#ifndef BC_VERSION_H
+#define BC_VERSION_H
+
+/// The current version.
+#define VERSION 5.1.0
+
+#endif // BC_VERSION_H
diff --git a/contrib/bc/include/vm.h b/contrib/bc/include/vm.h
new file mode 100644
index 000000000000..bbc5e57e2ac8
--- /dev/null
+++ b/contrib/bc/include/vm.h
@@ -0,0 +1,876 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Definitions for 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 <version.h>
+#include <status.h>
+#include <num.h>
+#include <lex.h>
+#include <parse.h>
+#include <program.h>
+#include <history.h>
+#include <bc.h>
+
+// We don't want to include this file for the library because it's unused.
+#if !BC_ENABLE_LIBRARY
+#include <file.h>
+#endif // !BC_ENABLE_LIBRARY
+
+// This should be obvious. If neither calculator is enabled, barf.
+#if !BC_ENABLED && !DC_ENABLED
+#error Must define BC_ENABLED, DC_ENABLED, or both
+#endif
+
+// CHAR_BIT must be at least 6, for various reasons. I might want to bump this
+// to 8 in the future.
+#if CHAR_BIT < 6
+#error CHAR_BIT must be at least 6.
+#endif
+
+// Set defaults.
+//
+#ifndef BC_ENABLE_NLS
+#define BC_ENABLE_NLS (0)
+#endif // BC_ENABLE_NLS
+
+#ifndef MAINEXEC
+#define MAINEXEC bc
+#endif // MAINEXEC
+
+#ifndef _WIN32
+#ifndef EXECPREFIX
+#define EXECPREFIX
+#endif // EXECPREFIX
+#else // _WIN32
+#undef EXECPREFIX
+#endif // _WIN32
+
+/**
+ * Generate a string from text.
+ * @parm V The text to generate a string for.
+ */
+#define GEN_STR(V) #V
+
+/**
+ * Help generate a string from text. The preprocessor requires this two-step
+ * process. Trust me.
+ * @parm V The text to generate a string for.
+ */
+#define GEN_STR2(V) GEN_STR(V)
+
+/// The version as a string. VERSION must be defined previously, usually by the
+/// build system.
+#define BC_VERSION GEN_STR2(VERSION)
+
+/// The main executable name as a string. MAINEXEC must be defined previously,
+/// usually by the build system.
+#define BC_MAINEXEC GEN_STR2(MAINEXEC)
+
+/// The build type as a string. BUILD_TYPE must be defined previously, usually
+/// by the build system.
+#define BC_BUILD_TYPE GEN_STR2(BUILD_TYPE)
+
+// We only allow an empty executable prefix on Windows.
+#ifndef _WIN32
+#define BC_EXECPREFIX GEN_STR2(EXECPREFIX)
+#else // _WIN32
+#define BC_EXECPREFIX ""
+#endif // _WIN32
+
+#if !BC_ENABLE_LIBRARY
+
+#if DC_ENABLED
+
+/// The flag for the extended register option.
+#define DC_FLAG_X (UINTMAX_C(1)<<0)
+
+#endif // DC_ENABLED
+
+#if BC_ENABLED
+
+/// The flag for the POSIX warning option.
+#define BC_FLAG_W (UINTMAX_C(1)<<1)
+
+/// The flag for the POSIX error option.
+#define BC_FLAG_S (UINTMAX_C(1)<<2)
+
+/// The flag for the math library option.
+#define BC_FLAG_L (UINTMAX_C(1)<<3)
+
+/// The flag for the global stacks option.
+#define BC_FLAG_G (UINTMAX_C(1)<<4)
+
+#endif // BC_ENABLED
+
+/// The flag for quiet, though this one is reversed; the option clears the flag.
+#define BC_FLAG_Q (UINTMAX_C(1)<<5)
+
+/// The flag for interactive.
+#define BC_FLAG_I (UINTMAX_C(1)<<6)
+
+/// The flag for prompt. This is also reversed; the option clears the flag.
+#define BC_FLAG_P (UINTMAX_C(1)<<7)
+
+/// The flag for read prompt. This is also reversed; the option clears the flag.
+#define BC_FLAG_R (UINTMAX_C(1)<<8)
+
+/// The flag for a leading zero.
+#define BC_FLAG_Z (UINTMAX_C(1)<<9)
+
+/// The flag for stdin being a TTY.
+#define BC_FLAG_TTYIN (UINTMAX_C(1)<<10)
+
+/// The flag for TTY mode.
+#define BC_FLAG_TTY (UINTMAX_C(1)<<11)
+
+/// The flag for reset on SIGINT.
+#define BC_FLAG_SIGINT (UINTMAX_C(1)<<12)
+
+/// A convenience macro for getting the TTYIN flag.
+#define BC_TTYIN (vm.flags & BC_FLAG_TTYIN)
+
+/// A convenience macro for getting the TTY flag.
+#define BC_TTY (vm.flags & BC_FLAG_TTY)
+
+/// A convenience macro for getting the SIGINT flag.
+#define BC_SIGINT (vm.flags & BC_FLAG_SIGINT)
+
+#if BC_ENABLED
+
+/// A convenience macro for getting the POSIX error flag.
+#define BC_S (vm.flags & BC_FLAG_S)
+
+/// A convenience macro for getting the POSIX warning flag.
+#define BC_W (vm.flags & BC_FLAG_W)
+
+/// A convenience macro for getting the math library flag.
+#define BC_L (vm.flags & BC_FLAG_L)
+
+/// A convenience macro for getting the global stacks flag.
+#define BC_G (vm.flags & BC_FLAG_G)
+
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+
+/// A convenience macro for getting the extended register flag.
+#define DC_X (vm.flags & DC_FLAG_X)
+
+#endif // DC_ENABLED
+
+/// A convenience macro for getting the interactive flag.
+#define BC_I (vm.flags & BC_FLAG_I)
+
+/// A convenience macro for getting the prompt flag.
+#define BC_P (vm.flags & BC_FLAG_P)
+
+/// A convenience macro for getting the read prompt flag.
+#define BC_R (vm.flags & BC_FLAG_R)
+
+/// A convenience macro for getting the leading zero flag.
+#define BC_Z (vm.flags & BC_FLAG_Z)
+
+#if BC_ENABLED
+
+/// A convenience macro for checking if bc is in POSIX mode.
+#define BC_IS_POSIX (BC_S || BC_W)
+
+#if DC_ENABLED
+
+/// Returns true if bc is running.
+#define BC_IS_BC (vm.name[0] != 'd')
+
+/// Returns true if dc is running.
+#define BC_IS_DC (vm.name[0] == 'd')
+
+#else // DC_ENABLED
+
+/// Returns true if bc is running.
+#define BC_IS_BC (1)
+
+/// Returns true if dc is running.
+#define BC_IS_DC (0)
+
+#endif // DC_ENABLED
+
+#else // BC_ENABLED
+
+/// A convenience macro for checking if bc is in POSIX mode.
+#define BC_IS_POSIX (0)
+
+/// Returns true if bc is running.
+#define BC_IS_BC (0)
+
+/// Returns true if dc is running.
+#define BC_IS_DC (1)
+
+#endif // BC_ENABLED
+
+/// A convenience macro for checking if the prompt is enabled.
+#define BC_PROMPT (BC_P)
+
+#else // !BC_ENABLE_LIBRARY
+
+#define BC_Z (vm.leading_zeroes)
+
+#endif // !BC_ENABLE_LIBRARY
+
+/**
+ * Returns the max of its two arguments. This evaluates arguments twice, so be
+ * careful what args you give it.
+ * @param a The first argument.
+ * @param b The second argument.
+ * @return The max of the two arguments.
+ */
+#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+/**
+ * Returns the min of its two arguments. This evaluates arguments twice, so be
+ * careful what args you give it.
+ * @param a The first argument.
+ * @param b The second argument.
+ * @return The min of the two arguments.
+ */
+#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/// Returns the max obase that is allowed.
+#define BC_MAX_OBASE ((BcBigDig) (BC_BASE_POW))
+
+/// Returns the max array size that is allowed.
+#define BC_MAX_DIM ((BcBigDig) (SIZE_MAX - 1))
+
+/// Returns the max scale that is allowed.
+#define BC_MAX_SCALE ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
+
+/// Returns the max string length that is allowed.
+#define BC_MAX_STRING ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
+
+/// Returns the max identifier length that is allowed.
+#define BC_MAX_NAME BC_MAX_STRING
+
+/// Returns the max number size that is allowed.
+#define BC_MAX_NUM BC_MAX_SCALE
+
+#if BC_ENABLE_EXTRA_MATH
+
+/// Returns the max random integer that can be returned.
+#define BC_MAX_RAND ((BcBigDig) (((BcRand) 0) - 1))
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+/// Returns the max exponent that is allowed.
+#define BC_MAX_EXP ((ulong) (BC_NUM_BIGDIG_MAX))
+
+/// Returns the max number of variables that is allowed.
+#define BC_MAX_VARS ((ulong) (SIZE_MAX - 1))
+
+/// The size of the global buffer.
+#define BC_VM_BUF_SIZE (1<<12)
+
+/// The amount of the global buffer allocated to stdout.
+#define BC_VM_STDOUT_BUF_SIZE (1<<11)
+
+/// The amount of the global buffer allocated to stderr.
+#define BC_VM_STDERR_BUF_SIZE (1<<10)
+
+/// The amount of the global buffer allocated to stdin.
+#define BC_VM_STDIN_BUF_SIZE (BC_VM_STDERR_BUF_SIZE - 1)
+
+/// The max number of temporary BcNums that can be kept.
+#define BC_VM_MAX_TEMPS (1 << 9)
+
+/// The capacity of the one BcNum, which is a constant.
+#define BC_VM_ONE_CAP (1)
+
+/**
+ * Returns true if a BcResult is safe for garbage collection.
+ * @param r The BcResult to test.
+ * @return True if @a r is safe to garbage collect.
+ */
+#define BC_VM_SAFE_RESULT(r) ((r)->t >= BC_RESULT_TEMP)
+
+/// The invalid locale catalog return value.
+#define BC_VM_INVALID_CATALOG ((nl_catd) -1)
+
+/**
+ * Returns true if the *unsigned* multiplication overflows.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param r The product.
+ * @return True if the multiplication of @a a and @a b overflows.
+ */
+#define BC_VM_MUL_OVERFLOW(a, b, r) \
+ ((r) >= SIZE_MAX || ((a) != 0 && (r) / (a) != (b)))
+
+/// The global vm struct. This holds all of the global data besides the file
+/// buffers.
+typedef struct BcVm {
+
+ /// The current status. This is volatile sig_atomic_t because it is also
+ /// used in the signal handler. See the development manual
+ /// (manuals/development.md#async-signal-safe-signal-handling) for more
+ /// information.
+ volatile sig_atomic_t status;
+
+ /// Non-zero if a jump series is in progress and items should be popped off
+ /// the jmp_bufs vector. This is volatile sig_atomic_t because it is also
+ /// used in the signal handler. See the development manual
+ /// (manuals/development.md#async-signal-safe-signal-handling) for more
+ /// information.
+ volatile sig_atomic_t sig_pop;
+
+#if !BC_ENABLE_LIBRARY
+
+ /// The parser.
+ BcParse prs;
+
+ /// The program.
+ BcProgram prog;
+
+ /// A buffer for lines for stdin.
+ BcVec line_buf;
+
+ /// A buffer to hold a series of lines from stdin. Sometimes, multiple lines
+ /// are necessary for parsing, such as a comment that spans multiple lines.
+ BcVec buffer;
+
+ /// A parser to parse read expressions.
+ BcParse read_prs;
+
+ /// A buffer for read expressions.
+ BcVec read_buf;
+
+#endif // !BC_ENABLE_LIBRARY
+
+ /// A vector of jmp_bufs for doing a jump series. This allows exception-type
+ /// error handling, while allowing me to do cleanup on the way.
+ BcVec jmp_bufs;
+
+ /// The number of temps in the temps array.
+ size_t temps_len;
+
+#if BC_ENABLE_LIBRARY
+
+ /// The vector of contexts for the library.
+ BcVec ctxts;
+
+ /// The vector for creating strings to pass to the client.
+ BcVec out;
+
+ /// The PRNG.
+ BcRNG rng;
+
+ /// The current error.
+ BclError err;
+
+ /// Whether or not bcl should abort on fatal errors.
+ bool abrt;
+
+ /// Whether or not to print leading zeros.
+ bool leading_zeroes;
+
+ /// The number of "references," or times that the library was initialized.
+ unsigned int refs;
+
+ /// Non-zero if bcl is running. This is volatile sig_atomic_t because it is
+ /// also used in the signal handler. See the development manual
+ /// (manuals/development.md#async-signal-safe-signal-handling) for more
+ /// information.
+ volatile sig_atomic_t running;
+
+#endif // BC_ENABLE_LIBRARY
+
+#if !BC_ENABLE_LIBRARY
+
+ /// A pointer to the filename of the current file. This is not owned by the
+ /// BcVm struct.
+ const char* file;
+
+ /// The message printed when SIGINT happens.
+ const char *sigmsg;
+
+#endif // !BC_ENABLE_LIBRARY
+
+ /// Non-zero when signals are "locked." This is volatile sig_atomic_t
+ /// because it is also used in the signal handler. See the development
+ /// manual (manuals/development.md#async-signal-safe-signal-handling) for
+ /// more information.
+ volatile sig_atomic_t sig_lock;
+
+ /// Non-zero when a signal has been received, but not acted on. This is
+ /// volatile sig_atomic_t because it is also used in the signal handler. See
+ /// the development manual
+ /// (manuals/development.md#async-signal-safe-signal-handling) for more
+ /// information.
+ volatile sig_atomic_t sig;
+
+#if !BC_ENABLE_LIBRARY
+
+ /// The length of sigmsg.
+ uchar siglen;
+
+ /// The instruction used for returning from a read() call.
+ uchar read_ret;
+
+ /// The flags field used by most macros above.
+ uint16_t flags;
+
+ /// The number of characters printed in the current line. This is used
+ /// because bc has a limit of the number of characters it can print per
+ /// line.
+ uint16_t nchars;
+
+ /// The length of the line we can print. The user can set this if they wish.
+ uint16_t line_len;
+
+ /// True if bc should error if expressions are encountered during option
+ /// parsing, false otherwise.
+ bool no_exprs;
+
+ /// True if bc should exit if expresions are encountered.
+ bool exit_exprs;
+
+ /// True if EOF was encountered.
+ bool eof;
+
+ /// True if bc is currently reading from stdin.
+ bool is_stdin;
+
+#if BC_ENABLED
+
+ /// True if keywords should not be redefined. This is only true for the
+ /// builtin math libraries for bc.
+ bool no_redefine;
+
+#endif // BC_ENABLED
+
+#endif // !BC_ENABLE_LIBRARY
+
+ /// An array of maxes for the globals.
+ BcBigDig maxes[BC_PROG_GLOBALS_LEN + BC_ENABLE_EXTRA_MATH];
+
+#if !BC_ENABLE_LIBRARY
+
+ /// A vector of filenames to process.
+ BcVec files;
+
+ /// A vector of expressions to process.
+ BcVec exprs;
+
+ /// The name of the calculator under use. This is used by BC_IS_BC and
+ /// BC_IS_DC.
+ const char *name;
+
+ /// The help text for the calculator.
+ const char *help;
+
+#if BC_ENABLE_HISTORY
+
+ /// The history data.
+ BcHistory history;
+
+#endif // BC_ENABLE_HISTORY
+
+ /// The function to call to get the next lex token.
+ BcLexNext next;
+
+ /// The function to call to parse.
+ BcParseParse parse;
+
+ /// The function to call to parse expressions.
+ BcParseExpr expr;
+
+ /// The text to display to label functions in error messages.
+ const char *func_header;
+
+ /// The names of the categories of errors.
+ const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED];
+
+ /// The messages for each error.
+ const char *err_msgs[BC_ERR_NELEMS];
+
+ /// The locale.
+ const char *locale;
+
+#endif // !BC_ENABLE_LIBRARY
+
+ /// The last base used to parse.
+ BcBigDig last_base;
+
+ /// The last power of last_base used to parse.
+ BcBigDig last_pow;
+
+ /// The last exponent of base that equals last_pow.
+ BcBigDig last_exp;
+
+ /// BC_BASE_POW - last_pow.
+ BcBigDig last_rem;
+
+#if !BC_ENABLE_LIBRARY
+
+ /// A buffer of environment arguments. This is the actual value of the
+ /// environment variable.
+ char *env_args_buffer;
+
+ /// A vector for environment arguments after parsing.
+ BcVec env_args;
+
+ /// A BcNum set to constant 0.
+ BcNum zero;
+
+#endif // !BC_ENABLE_LIBRARY
+
+ /// A BcNum set to constant 1.
+ BcNum one;
+
+ /// A BcNum holding the max number held by a BcBigDig plus 1.
+ BcNum max;
+
+ /// A BcNum holding the max number held by a BcBigDig times 2 plus 1.
+ BcNum max2;
+
+ /// The BcDig array for max.
+ BcDig max_num[BC_NUM_BIGDIG_LOG10];
+
+ /// The BcDig array for max2.
+ BcDig max2_num[BC_NUM_BIGDIG_LOG10];
+
+ // The BcDig array for the one BcNum.
+ BcDig one_num[BC_VM_ONE_CAP];
+
+#if !BC_ENABLE_LIBRARY
+
+ // The BcDig array for the zero BcNum.
+ BcDig zero_num[BC_VM_ONE_CAP];
+
+ /// The stdout file.
+ BcFile fout;
+
+ /// The stderr file.
+ BcFile ferr;
+
+#if BC_ENABLE_NLS
+
+ /// The locale catalog.
+ nl_catd catalog;
+
+#endif // BC_ENABLE_NLS
+
+ /// A pointer to the stdin buffer.
+ char *buf;
+
+ /// The number of items in the input buffer.
+ size_t buf_len;
+
+ /// The slab for constants in the main function. This is separate for
+ /// garbage collection reasons.
+ BcVec main_const_slab;
+
+ //// The slab for all other strings for the main function.
+ BcVec main_slabs;
+
+ /// The slab for function names, strings in other functions, and constants
+ /// in other functions.
+ BcVec other_slabs;
+
+#if BC_ENABLED
+
+ /// An array of booleans for which bc keywords have been redefined if
+ /// BC_REDEFINE_KEYWORDS is non-zero.
+ bool redefined_kws[BC_LEX_NKWS];
+
+#endif // BC_ENABLED
+#endif // !BC_ENABLE_LIBRARY
+
+#if BC_DEBUG_CODE
+
+ /// The depth for BC_FUNC_ENTER and BC_FUNC_EXIT.
+ size_t func_depth;
+
+#endif // BC_DEBUG_CODE
+
+} BcVm;
+
+/**
+ * Print the copyright banner and help if it's non-NULL.
+ * @param help The help message to print if it's non-NULL.
+ */
+void bc_vm_info(const char* const help);
+
+/**
+ * The entrance point for bc/dc together.
+ * @param argc The count of arguments.
+ * @param argv The argument array.
+ */
+void bc_vm_boot(int argc, char *argv[]);
+
+/**
+ * Initializes some of the BcVm global. This is separate to make things easier
+ * on the library code.
+ */
+void bc_vm_init(void);
+
+/**
+ * Frees the BcVm global.
+ */
+void bc_vm_shutdown(void);
+
+/**
+ * Add a temp to the temp array.
+ * @param num The BcDig array to add to the temp array.
+ */
+void bc_vm_addTemp(BcDig *num);
+
+/**
+ * Dish out a temp, or NULL if there are none.
+ * @return A temp, or NULL if none exist.
+ */
+BcDig* bc_vm_takeTemp(void);
+
+/**
+ * Frees all temporaries.
+ */
+void bc_vm_freeTemps(void);
+
+#if !BC_ENABLE_HISTORY
+
+/**
+ * Erases the flush argument if history does not exist because it does not
+ * matter if history does not exist.
+ */
+#define bc_vm_putchar(c, t) bc_vm_putchar(c)
+
+#endif // !BC_ENABLE_HISTORY
+
+/**
+ * Print to stdout with limited formating.
+ * @param fmt The format string.
+ */
+void bc_vm_printf(const char *fmt, ...);
+
+/**
+ * Puts a char into the stdout buffer.
+ * @param c The character to put on the stdout buffer.
+ * @param type The flush type.
+ */
+void bc_vm_putchar(int c, BcFlushType type);
+
+/**
+ * Multiplies @a n and @a size and throws an allocation error if overflow
+ * occurs.
+ * @param n The number of elements.
+ * @param size The size of each element.
+ * @return The product of @a n and @a size.
+ */
+size_t bc_vm_arraySize(size_t n, size_t size);
+
+/**
+ * Adds @a a and @a b and throws an error if overflow occurs.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @return The sum of @a a and @a b.
+ */
+size_t bc_vm_growSize(size_t a, size_t b);
+
+/**
+ * Allocate @a n bytes and throw an allocation error if allocation fails.
+ * @param n The bytes to allocate.
+ * @return A pointer to the allocated memory.
+ */
+void* bc_vm_malloc(size_t n);
+
+/**
+ * Reallocate @a ptr to be @a n bytes and throw an allocation error if
+ * reallocation fails.
+ * @param ptr The pointer to a memory allocation to reallocate.
+ * @param n The bytes to allocate.
+ * @return A pointer to the reallocated memory.
+ */
+void* bc_vm_realloc(void *ptr, size_t n);
+
+/**
+ * Allocates space for, and duplicates, @a str.
+ * @param str The string to allocate.
+ * @return The allocated string.
+ */
+char* bc_vm_strdup(const char *str);
+
+/**
+ * Reads a line into BcVm's buffer field.
+ * @param clear True if the buffer should be cleared first, false otherwise.
+ * @return True if a line was read, false otherwise.
+ */
+bool bc_vm_readLine(bool clear);
+
+/**
+ * A convenience and portability function for OpenBSD's pledge().
+ * @param promises The promises to pledge().
+ * @param execpromises The exec promises to pledge().
+ */
+void bc_pledge(const char *promises, const char *execpromises);
+
+/**
+ * Returns the value of an environment variable.
+ * @param var The environment variable.
+ * @return The value of the environment variable.
+ */
+char* bc_vm_getenv(const char* var);
+
+/**
+ * Frees an environment variable value.
+ * @param val The value to free.
+ */
+void bc_vm_getenvFree(char* val);
+
+#if BC_DEBUG_CODE
+
+/**
+ * Start executing a jump series.
+ * @param f The name of the function that started the jump series.
+ */
+void bc_vm_jmp(const char *f);
+#else // BC_DEBUG_CODE
+
+/**
+ * Start executing a jump series.
+ */
+void bc_vm_jmp(void);
+
+#endif // BC_DEBUG_CODE
+
+#if BC_ENABLE_LIBRARY
+
+/**
+ * Handle an error. This is the true error handler. It will start a jump series
+ * if an error occurred. POSIX errors will not cause jumps when warnings are on
+ * or no POSIX errors are enabled.
+ * @param e The error.
+ */
+void bc_vm_handleError(BcErr e);
+
+/**
+ * Handle a fatal error.
+ * @param e The error.
+ */
+void bc_vm_fatalError(BcErr e);
+
+/**
+ * A function to call at exit.
+ */
+void bc_vm_atexit(void);
+
+#else // BC_ENABLE_LIBRARY
+
+/**
+ * Handle an error. This is the true error handler. It will start a jump series
+ * if an error occurred. POSIX errors will not cause jumps when warnings are on
+ * or no POSIX errors are enabled.
+ * @param e The error.
+ * @param line The source line where the error occurred.
+ */
+void bc_vm_handleError(BcErr e, size_t line, ...);
+
+/**
+ * Handle a fatal error.
+ * @param e The error.
+ */
+#if !BC_ENABLE_MEMCHECK
+BC_NORETURN
+#endif // !BC_ENABLE_MEMCHECK
+void bc_vm_fatalError(BcErr e);
+
+/**
+ * A function to call at exit.
+ * @param status The exit status.
+ */
+int bc_vm_atexit(int status);
+#endif // BC_ENABLE_LIBRARY
+
+/// A reference to the copyright header.
+extern const char bc_copyright[];
+
+/// A reference to the format string for source code line printing.
+extern const char* const bc_err_line;
+
+/// A reference to the format string for source code function printing.
+extern const char* const bc_err_func_header;
+
+/// A reference to the array of default error category names.
+extern const char *bc_errs[];
+
+/// A reference to the array of error category indices for each error.
+extern const uchar bc_err_ids[];
+
+/// A reference to the array of default error messages.
+extern const char* const bc_err_msgs[];
+
+/// A reference to the pledge() promises at start.
+extern const char bc_pledge_start[];
+
+#if BC_ENABLE_HISTORY
+
+/// A reference to the end pledge() promises when using history.
+extern const char bc_pledge_end_history[];
+
+#endif // BC_ENABLE_HISTORY
+
+/// A reference to the end pledge() promises when *not* using history.
+extern const char bc_pledge_end[];
+
+/// A reference to the global data.
+extern BcVm vm;
+
+/// A reference to the global output buffers.
+extern char output_bufs[BC_VM_BUF_SIZE];
+
+#endif // BC_VM_H
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..76f2ac4190f6
--- /dev/null
+++ b/contrib/bc/locales/de_DE.ISO8859-1.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 "ungltiges Zeichen: '%c'"
+3 "Zeichenketten-Ende konnte nicht gefunden werden"
+4 "Kommentar-Ende konnte nicht gefunden werden"
+5 "ungltiges Token"
+6 "ungltiger Ausdruck"
+7 "leerer Ausdruck"
+8 "Ungltige Druck- oder Stream-Anweisung"
+9 "Ungltige Funktionsdefinition"
+10 "Ungltige 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 zurckgeben: %s()"
+15 "Variable kann keine Referenz sein: %s"
+16 "POSIX erlaubt keine Namen mit mehr als 1 Zeichen Lnge: %s"
+17 "POSIX erlaubt keine '#'-Skriptkommentare"
+18 "POSIX erlaubt das Schlsselwort \"%s\" nicht"
+19 "POSIX erlaubt keinen Punkt ('.') als Abkrzung fr das letzte Ergebnis"
+20 "POSIX bentigt Klammern um Rckgabeausdrcke"
+21 "POSIX erlaubt den Operator \"%s\" nicht"
+22 "POSIX erlaubt keine Vergleichsoperatoren auerhalb von if-Anweisungen oder Schleifen"
+23 "POSIX bentigt 0 oder 1 Vergleichsoperatoren pro Bedingung"
+24 "POSIX erlaubt keinen leeren Ausdruck in einer for-Schleife"
+25 "POSIX erlaubt keine exponentielle Notation"
+26 "POSIX erlaubt keine Feld-Referenzen als Funktionsparameter"
+27 "POSIX erfordert, dass die linke Klammer auf der gleichen Linie wie der Funktionskopf steht"
+28 "POSIX erlaubt keine Zuweisung von Strings an Variablen oder Arrays"
+
+$ Runtime errors.
+$set 5
+
+1 "ungltige \"ibase\": muss im Intervall [%lu, %lu] liegen"
+2 "ungltige \"obase\": muss im Intervall [%lu, %lu] liegen"
+3 "ungltige \"scale\": muss im Intervall [%lu, %lu] liegen"
+4 "ungltiger read()-Ausdruck"
+5 "rekursiver read()-Aufruf"
+6 "Variable oder Feld-Element hat den falschen Typ"
+7 "Stapel hat zu wenig Elemente"
+8 "Stapel fr Register \"%s\" hat zu wenig Elemente"
+9 "falsche Anzahl der Parameter: bentigt %zu, hat %zu"
+10 "undefinierte Funktion: %s()"
+11 "kann keinen ungltigen 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 Text: %s"
+5 "Pfad ist ein Verzeichnis: %s"
+6 "ungltige Befehlszeilenoption: \"%s\""
+7 "Option erfordert ein Argument: '%c' (\"%s\")"
+8 "Option benutzt keine Argumente: '%c' (\"%s\")"
+9 "ungltiges Argument der Befehlszeilenoption: \"%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..c4dad4cd3a60
--- /dev/null
+++ b/contrib/bc/locales/de_DE.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 Druck- oder Stream-Anweisung"
+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"
+28 "POSIX erlaubt keine Zuweisung von Strings an Variablen oder Arrays"
+
+$ 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 "Stapel für Register \"%s\" hat zu wenig Elemente"
+9 "falsche Anzahl der Parameter: benötigt %zu, hat %zu"
+10 "undefinierte Funktion: %s()"
+11 "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 Text: %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\")"
+9 "ungültiges Argument der Befehlszeilenoption: \"%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..707950a5767d
--- /dev/null
+++ b/contrib/bc/locales/en_US.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 or stream 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"
+28 "POSIX does not allow strings to be assigned to variables or arrays"
+
+$ 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 "stack for register \"%s\" has too few elements"
+9 "wrong number of parameters; need %zu, have %zu"
+10 "undefined function: %s()"
+11 "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 text: %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\")"
+9 "invalid command-line option argument: \"%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..8d74f884f811
--- /dev/null
+++ b/contrib/bc/locales/es_ES.ISO8859-1.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Funcin:"
+
+$ Error types.
+$set 2
+
+1 "Error de matemtica:"
+2 "Error de syntaxis:"
+3 "Error de ejecucin:"
+4 "Error fatal:"
+5 "Advertencia:"
+
+$ Math errors.
+$set 3
+
+1 "nmero negativo"
+2 "nmero no es entero"
+3 "desbordamiento de enteros: no se puede encajar el el hardware"
+4 "divisin por cero"
+
+$ Parse errors.
+$set 4
+
+1 "fin de archivo"
+2 "no vlido '%c'"
+3 "no puede encontrar el fine de la cadena"
+4 "no puede encontrar el fine del comentario"
+5 "el token no es vlido"
+6 "la expresin no es vlida"
+7 "la expresin es vaca"
+8 "la expresin de print o de stream no es vlida"
+9 "la definicin de funcin no es vlida"
+10 "la asignacin no es valida: en la izquierda debe ser scale, ibase, obase, last, var, o un elemento de matriz"
+11 "no se encontr ninguna variable automtica"
+12 "ya hay un parmetro de funcin o variable automatica que se llama \"%s%s\""
+13 "no se puede encontrar el final de del bloque de cdigo"
+14 "no puede haber un valor de retorno de una funcin \"void\": %s()"
+15 "var no puede ser una referencia: %s"
+16 "POSIX no permite nombres de ms de 1 carcter: %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 parntesis en el expresin del \"return\""
+21 "POSIX no permite este operador: %s"
+22 "POSIX no permite operadores de comparacin aparte de \"if\" expresin o bucles"
+23 "POSIX requiere 0 o 1 operadores de comparisn para cada condicin"
+24 "POSIX requiere todos 3 partes de una bucla que no esta vaco"
+25 "POSIX no permite una notacin exponencial"
+26 "POSIX no permite una referencia a una matriz como un parmetro de funcin"
+27 "POSIX requiere el llave de la izquierda que sea en la misma lnea que los parmetros de la funcin"
+28 "POSIX no permite asignar cadenas a variables o matrices"
+
+$ Runtime errors.
+$set 5
+
+1 "\"ibase\" no es vlido: debe ser [%lu, %lu]"
+2 "\"obase\" no es vlido: debe ser [%lu, %lu]"
+3 "\"scale\" no es vlido: debe ser [%lu, %lu]"
+4 "read() expresin no es vlido"
+5 "recursion en la invocacin de read()"
+6 "variable o elemento del matriz de tipo equivocado"
+7 "la pila no ha demaciado elementos"
+8 "la pila del registro \"%s\" no ha demaciado elementos"
+9 "la funcin no tiene un nmero de argumentos correcto; necessita %zu, tiene %zu"
+10 "la funcin no esta definida: %s()"
+11 "no puede utilizar un valor vaco en una expresin"
+
+$ Fatal errors.
+$set 6
+
+1 "error en la asignacin de memoria"
+2 "error de I/O"
+3 "no puede abrir el archivo: %s"
+4 "el archivo no es texto: %s"
+5 "el ruta es un directorio: %s"
+6 "una opcin de lnea de comandos no es vlida: \"%s\""
+7 "una opcin requiere un argumento: '%c' (\"%s\")"
+8 "una opcin no tiene argumento: '%c' (\"%s\")"
+9 "uno argumento de opcin de lnea de comandos no es vlido: \"%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..26559e6e9b88
--- /dev/null
+++ b/contrib/bc/locales/es_ES.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 o de stream 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"
+28 "POSIX no permite asignar cadenas a variables o matrices"
+
+$ 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 pila del registro \"%s\" no ha demaciado elementos"
+9 "la función no tiene un número de argumentos correcto; necessita %zu, tiene %zu"
+10 "la función no esta definida: %s()"
+11 "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 texto: %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\")"
+9 "uno argumento de opción de línea de comandos no es válido: \"%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..8e894e043bbc
--- /dev/null
+++ b/contrib/bc/locales/fr_FR.ISO8859-1.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 ou de flux 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"
+28 "POSIX interdit pas d'assigner des chaînes de caractères à des variables ou à des tableaux"
+
+$ 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 "pile pour le registre \"%s\" sous-remplie"
+9 "nombre incorrect de paramètres - attendus : %zu, obtenus : %zu"
+10 "fonction non définie : %s()"
+11 "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 texte: %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"
+9 "argument d'option de ligne de commande invalide : \"%s\""
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..8e894e043bbc
--- /dev/null
+++ b/contrib/bc/locales/fr_FR.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 ou de flux 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"
+28 "POSIX interdit pas d'assigner des chaînes de caractères à des variables ou à des tableaux"
+
+$ 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 "pile pour le registre \"%s\" sous-remplie"
+9 "nombre incorrect de paramètres - attendus : %zu, obtenus : %zu"
+10 "fonction non définie : %s()"
+11 "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 texte: %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"
+9 "argument d'option de ligne de commande invalide : \"%s\""
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..4477f2bc548b
--- /dev/null
+++ b/contrib/bc/locales/ja_JP.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 "無効なprintまたはstream文"
+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では、関数ヘッダと同じ行に左中括弧があることが必要です。"
+28 "POSIXでは、変数や配列に文字列を割り当てることはできません。"
+
+$ ランタイムエラー。
+$set 5
+
+1 "無効なibase:は[%lu、%lu]でなければなりません"
+2 "無効なobase:は[%lu、%lu]でなければなりません"
+3 "無効なscale:は[%lu、%lu]でなければなりません"
+4 "式が無効read()"
+5 "再帰的読み込み()呼び出し"
+6 "変数または配列要素の型が間違っている"
+7 "スタックの要素が少なすぎる"
+8 "レジスタ\"%s\"のスタックの要素が少なすぎる"
+9 "パラメータの数が間違っています。"
+10 "定義されていない関数:%s()"
+11 "式では void 値を使用できません"
+
+$ 致命的なエラーが発生しました。
+$set 6
+
+1 "メモリの割り当てに失敗しました"
+2 "I/Oエラー"
+3 "ファイルを開けませんでした。%s"
+4 "ファイルがテキストではない:%s"
+5 "パスはディレクトリです:%s"
+6 "無効なコマンドラインオプション:\"%s\""
+7 "オプションには引数が必要です:'%c' (\"%s\")"
+8 "オプションは引数を取りません:'%c' (\"%s\")"
+9 "無効なコマンドラインオプション引数: \"%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..a907cd7cf0e3
--- /dev/null
+++ b/contrib/bc/locales/ja_JP.eucJP.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$quote "
+
+$ ¾Υå
+$set 1
+
+1 "ؿ"
+
+$ 顼μࡣ
+$set 2
+
+1 "ؤΥ顼"
+2 "ѡ顼"
+3 "󥿥२顼"
+4 "̿Ūʥ顼"
+5 "ٹ"
+
+$ ؤΥ顼Ǥ
+$set 3
+
+1 "ο"
+2 ""
+3 "Сեϡɥֹ˼ޤʤ"
+4 "0dz"
+
+$ ʸϤΥ顼
+$set 4
+
+1 "եνλ"
+2 "̵ʸ '%c'"
+3 "ʸνüĤޤǤ"
+4 "ȥɤĤޤǤ"
+5 "̵ʥȡ"
+6 "̵ʼ"
+7 "μ"
+8 "̵printޤstreamʸ"
+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 "POSIXfor롼פ3Ĥʬ٤ƶǤʤȤ׵ᤷޤ"
+25 "POSIXϻؿɽĤޤ"
+26 "POSIX ϴؿѥ᡼Ȥ󻲾ȤĤޤ"
+27 "POSIXǤϡؿإåƱԤ˺̤뤳ȤɬפǤ"
+28 "POSIXǤϡѿʸƤ뤳ȤϤǤޤ"
+
+$ 󥿥२顼
+$set 5
+
+1 "̵ibase[%lu%lu]ǤʤФʤޤ"
+2 "̵obase[%lu%lu]ǤʤФʤޤ"
+3 "̵scale[%lu%lu]ǤʤФʤޤ"
+4 "̵read()"
+5 "ƵŪɤ߹()ƤӽФ"
+6 "ѿޤǤηְäƤ"
+7 "åǤʤ"
+8 "쥸\"%s\"ΥåǤʤ"
+9 "ѥ᡼οְäƤޤ"
+10 "Ƥʤؿ%s()"
+11 "Ǥ void ͤѤǤޤ"
+
+$ ̿Ūʥ顼ȯޤ
+$set 6
+
+1 "γƤ˼Ԥޤ"
+2 "I/O顼"
+3 "ե򳫤ޤǤ%s"
+4 "ե뤬ƥȤǤϤʤ%s"
+5 "ѥϥǥ쥯ȥǤ%s"
+6 "̵ʥޥɥ饤󥪥ץ\"%s\""
+7 "ץˤϰɬפǤ'%c' (\"%s\")"
+8 "ץϰޤ'%c' (\"%s\")"
+9 "̵ʥޥɥ饤󥪥ץ \"%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..76b8577108e8
--- /dev/null
+++ b/contrib/bc/locales/nl_NL.ISO8859-1.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 print- of stream-instructie"
+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 exponentile notatie toe"
+26 "POSIX staat geen arrayreferenties toe als functieparameters"
+27 "POSIX vereist dat de linkse beugel op dezelfde regel staat als de functiehoofding"
+28 "POSIX staat niet toe dat strings worden toegewezen aan variabelen of arrays"
+
+$ 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 "Stapel voor register %s heeft te weinig elementen"
+9 "Verkeerd aantal parameters; hebben %zu nodig, hebben %zu"
+10 "ongedefinieerde functie: %s()"
+11 "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 geen tekst: %s"
+5 "pad is een directory: %s"
+6 "ongeldige opdrachtregeloptie: %s"
+7 "optie vereist een argument: '%c' (\"%s\")"
+8 "optie neemt geen argumenten aan: '%c' (\"%s\")"
+9 "ongeldige opdrachtregeloptie argument: %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..51acb9867e22
--- /dev/null
+++ b/contrib/bc/locales/nl_NL.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 print- of stream-instructie"
+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"
+28 "POSIX staat niet toe dat strings worden toegewezen aan variabelen of arrays"
+
+$ 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 "Stapel voor register %s heeft te weinig elementen"
+9 "Verkeerd aantal parameters; hebben %zu nodig, hebben %zu"
+10 "ongedefinieerde functie: %s()"
+11 "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 geen tekst: %s"
+5 "pad is een directory: %s"
+6 "ongeldige opdrachtregeloptie: %s"
+7 "optie vereist een argument: '%c' (\"%s\")"
+8 "optie neemt geen argumenten aan: '%c' (\"%s\")"
+9 "ongeldige opdrachtregeloptie argument: %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..d1d77d7e0b57
--- /dev/null
+++ b/contrib/bc/locales/pl_PL.ISO8859-2.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$quote "
+
+$ Rne wiadomoci.
+$set 1
+
+1 "Funkcja:"
+
+$ Typy bdw.
+$set 2
+
+1 "Bd matematyczny:"
+2 "Bd parse'a:"
+3 "Bd biegu:"
+4 "Bd miertelny:"
+5 "Ostrzeenie:"
+
+$ Bdy matematyczne.
+$set 3
+
+1 "liczba ujemna"
+2 "numer nieintegracyjny"
+3 "przelewanie: liczba nie mieci si w numerze sprztowym"
+4 "dzielenie przez 0"
+
+$ Bdy Parse'a.
+$set 4
+
+1 "koniec akt"
+2 "niewany znak '%c'"
+3 "koniec sznurka nie mg by znaleziony"
+4 "koniec komentarza nie mg by znaleziony"
+5 "niewany token"
+6 "niewane wyraenie"
+7 "puste wyraenie"
+8 "nieprawidowe polecenie drukowania lub przesyania strumienia"
+9 "nieprawidowa definicja funkcji"
+10 "nieprawidowe przyporzdkowanie: 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 "koca bloku nie mona byo znale"
+14 "nie moe zwrci wartoci z funkcji void: %s()"
+15 "var nie moe by odniesieniem: %s"
+16 "POSIX nie zezwala na nazwy dusze ni 1 znak: %s"
+17 "POSIX nie pozwala na komentarze skryptu '#'"
+18 "POSIX nie pozwala na uycie nastpujcego sowa kluczowego: %s"
+19 "POSIX nie dopuszcza kropki ('.') jako skrtu do ostatniego wyniku"
+20 "POSIX wymaga nawiasw wok wyrae zwrotnych"
+21 "POSIX nie pozwala nastpujcemu operatorowi: %s"
+22 "POSIX nie pozwala na porwnywanie operatorw na zewntrz, jeli deklaracje lub ptle"
+23 "POSIX wymaga 0 lub 1 operatora porwnawczego na jeden warunek"
+24 "POSIX wymaga, aby wszystkie 3 czci ptli nie byy puste"
+25 "POSIX nie pozwala na notacj wykadnicz"
+26 "POSIX nie zezwala na odniesienia do tablicy jako parametrw funkcji"
+27 "POSIX wymaga, aby lewe usztywnienie znajdowao si na tej samej linii co nagwek funkcji"
+28 "POSIX nie pozwala na przypisywanie cigw znakw do zmiennych lub tablic"
+
+$ Bdy Runtime'u.
+$set 5
+
+1 "nieprawidowa ibase: musi by [%lu, %lu]"
+2 "nieprawidowa obase: musi by [%lu, %lu]"
+3 "nieprawidowa scale: musi by [%lu, %lu]"
+4 "nieprawidowe wyraenie read()"
+5 "powtarzalne wywoanie read()"
+6 "element zmienny lub tablicowy jest niewaciwym typem"
+7 "stos ma zbyt mao elementw"
+8 "stos dla rejestru \"%s\" ma zbyt mao elementw"
+9 "niewaciwa liczba parametrw; potrzeba %zu, maj %zu"
+10 "niezdefiniowana funkcja: %s()"
+11 "nie moe uy wartoci pustej w wyraeniu"
+
+$ Fatalne bdy.
+$set 6
+
+1 "Alokacja pamici nie powioda si"
+2 "Bd we/wy"
+3 "nie mg otworzy pliku: %s"
+4 "plik nie jest tekstem: %s"
+5 "cieka to katalog: %s"
+6 "nieprawidowa opcja wiersza polece: \"%s\""
+7 "opcja wymaga argumentu: '%c' (\"%s\")"
+8 "opcja nie wymaga adnych argumentw: '%c' (\"%s\")"
+9 "nieprawidowa argument opcja wiersza polece: \"%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..a23a98edd1d2
--- /dev/null
+++ b/contrib/bc/locales/pl_PL.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 "nieprawidłowe polecenie drukowania lub przesyłania strumienia"
+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"
+28 "POSIX nie pozwala na przypisywanie ciągów znaków do zmiennych lub tablic"
+
+$ 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 "stos dla rejestru \"%s\" ma zbyt mało elementów"
+9 "niewłaściwa liczba parametrów; potrzeba %zu, mają %zu"
+10 "niezdefiniowana funkcja: %s()"
+11 "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 tekstem: %s"
+5 "ścieżka to katalog: %s"
+6 "nieprawidłowa opcja wiersza poleceń: \"%s\""
+7 "opcja wymaga argumentu: '%c' (\"%s\")"
+8 "opcja nie wymaga żadnych argumentów: '%c' (\"%s\")"
+9 "nieprawidłowa argument opcja wiersza poleceń: \"%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..7a17f0642cc9
--- /dev/null
+++ b/contrib/bc/locales/pt_PT.ISO8859-1.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$quote "
+
+$ Miscellaneous messages.
+$set 1
+
+1 "Funo:"
+
+$ Error types.
+$set 2
+
+1 "Erro de clculo:"
+2 "Erro de anlise de sintaxe:"
+3 "Erro de execuo:"
+4 "Erro fatal:"
+5 "Aviso:"
+
+$ Math errors.
+$set 3
+
+1 "nmero negativo"
+2 "nmero no inteiro"
+3 "Estouro: nmero no cabe no registro"
+4 "dividir por 0"
+
+$ Parse errors.
+$set 4
+
+1 "fim do arquivo"
+2 "caractere invlido '%c'"
+3 "No foi possvel encontrar o final da string"
+4 "No foi possvel encontrar o final do comentrio"
+5 "token invlido"
+6 "expresso invlida"
+7 "expresso vazia"
+8 "instruo de gravao ou de fluxo invlida"
+9 "definio de funo invlida"
+10 "atribuio invlida: a parte esquerda deve ser 'scale', 'ibase', 'obase', 'last', uma varivel ou um elemento da matriz"
+11 "nenhuma varivel automtica encontrada"
+12 "parmetro de funo ou varivel automtica \"%s%s\" j existe"
+13 "fim do bloco no encontrado"
+14 "uma funo 'void' no pode retornar um valor: %s()"
+15 "Uma varivel no pode ser uma referncia: %s"
+16 "POSIX no permite nomes com mais de 1 caractere: %s"
+17 "POSIX no permite comentrios de script '#'"
+18 "POSIX no permite a seguinte palavra-chave: %s"
+19 "POSIX no permite um ponto ('.') como um atalho para o ltimo resultado"
+20 "POSIX requer parnteses em torno de expresses de retorno"
+21 "POSIX no permite o seguinte operador: %s"
+22 "POSIX no permite operadores de comparao fora das expresses 'if' ou loops"
+23 "POSIX requer operadores 0 ou 1 de comparao por condio"
+24 "POSIX no permite uma expresso vazia em um loop 'for'"
+25 "POSIX no permite notao exponencial"
+26 "POSIX no permite referncias de matriz como parmetros de funo"
+27 "POSIX requer que o cabealho da funo '{' estejam na mesma linha"
+28 "POSIX no permite a atribuio de cadeias de caracteres a variveis ou matrizes"
+
+$ Runtime errors.
+$set 5
+
+1 "ibase invlido: deve ser [%lu, %lu]"
+2 "obase invlido: deve ser [%lu, %lu]"
+3 "scale invlida: deve ser [%lu, %lu]"
+4 "expresso read() invlida"
+5 "chamada read() recursiva"
+6 "tipo errado de varivel ou elemento de matriz"
+7 "pilha tem poucos elementos"
+8 "pilha para registo \"%s\" tem poucos elementos"
+9 "nmero incorreto de parmetros - esperado: %zu, obtido: %zu"
+10 "funo indefinida: %s()"
+11 "um valor 'void' no pode ser usado em uma expresso"
+
+$ Fatal errors.
+$set 6
+
+1 "falha na alocao de memria"
+2 "erro de entrada-sada"
+3 "impossvel abrir o arquivo: %s"
+4 "arquivo no texto: %s"
+5 "caminho um diretrio: %s"
+6 "opo de linha de comando invlida: \"%s\""
+7 "opo requer um argumento: '%c' (\"%s\")"
+8 "a opo no aceita argumentos: '%c' (\"%s\")"
+9 "argumento de opo de linha de comando invlido: \"%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..2f6a4683a376
--- /dev/null
+++ b/contrib/bc/locales/pt_PT.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 ou de fluxo 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"
+28 "POSIX não permite a atribuição de cadeias de caracteres a variáveis ou matrizes"
+
+$ 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 "pilha para registo \"%s\" tem poucos elementos"
+9 "número incorreto de parâmetros - esperado: %zu, obtido: %zu"
+10 "função indefinida: %s()"
+11 "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 é texto: %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\")"
+9 "argumento de opção de linha de comando inválido: \"%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..6b1d93aa2110
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.CP1251.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 , , "
+28 "POSIX "
+
+$ .
+$set 5
+
+1 " ibase: [%lu, %lu]"
+2 " obase: [%lu, %lu]"
+3 " scale: [%lu, %lu]"
+4 " read()"
+5 " read()"
+6 " "
+7 " "
+8 " \"%s\" "
+9 " ; %zu, %zu"
+10 " : %s()"
+11 " "
+
+$ .
+$set 6
+
+1 " "
+2 " /"
+3 " : %s"
+4 " : %s"
+5 " - : %s"
+6 " : \"%s\""
+7 " : '%c' (\"%s\")"
+8 " : '%c' (\"%s\")"
+9 " : \"%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..b693428b9a3c
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.CP866.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 ॡ, ⮡ ᪮ 뫠 ⮩ , 㭪樨"
+28 "POSIX ᢠ ப ६ ᨢ"
+
+$ 訡 믮.
+$set 5
+
+1 "⢨⥫ ibase: [%lu, %lu]"
+2 "⢨⥫ obase: [%lu, %lu]"
+3 "⢨⥫쭠 scale: [%lu, %lu]"
+4 "⢨⥫쭮 ࠦ read()"
+5 "४ᨢ 맮 read()"
+6 "६ ᨢ  ࠢ ⨯"
+7 "⮯ ᫨誮 ⮢"
+8 "⮯ ॣ \"%s\" ᫨誮 ⮢"
+9 "ࠢ쭮 ⢮ ࠬ஢; 㦭 %zu, 㦭 %zu"
+10 "। 㭪: %s()"
+11 " ᯮ짮 ⮥ 祭 ࠦ"
+
+$ ⠫ 訡.
+$set 6
+
+1 " 㤠 뤥 "
+2 "訡 /뢮"
+3 " ᬮ 䠩: %s"
+4 "䠩  ⥪⮢: %s"
+5 " - ⠫: %s"
+6 "ୠ ப: \"%s\""
+7 " ॡ 㬥: '%c' (\"%s\")"
+8 " ਭ 㬥⮢: '%c' (\"%s\")"
+9 " 㬥 樨 ப: \"%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..35af400c5831
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.ISO8859-5.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 , , "
+28 "POSIX "
+
+$ .
+$set 5
+
+1 " ibase: [%lu, %lu]"
+2 " obase: [%lu, %lu]"
+3 " scale: [%lu, %lu]"
+4 " read()"
+5 " read()"
+6 " "
+7 " "
+8 " \"%s\" "
+9 " ; %zu, %zu"
+10 " : %s()"
+11 " "
+
+$ .
+$set 6
+
+1 " "
+2 " /"
+3 " : %s"
+4 " : %s"
+5 " - : %s"
+6 " : \"%s\""
+7 " : '%c' (\"%s\")"
+8 " : '%c' (\"%s\")"
+9 " : \"%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..98c667095852
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.KOI8-R.msg
@@ -0,0 +1,110 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 , , "
+28 "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 " : %s"
+5 " - : %s"
+6 " : \"%s\""
+7 " : '%c' (\"%s\")"
+8 " : '%c' (\"%s\")"
+9 " : \"%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..f7c1dc58c4db
--- /dev/null
+++ b/contrib/bc/locales/ru_RU.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 требует, чтобы левая скобка была на той же линии, что и заголовок функции"
+28 "POSIX не позволяет присваивать строки переменным или массивам"
+
+$ Ошибки выполнения.
+$set 5
+
+1 "Недействительный ibase: должен быть [%lu, %lu]"
+2 "Недействительный obase: должен быть [%lu, %lu]"
+3 "недействительная scale: должна быть [%lu, %lu]"
+4 "недействительное выражение read()"
+5 "рекурсивный вызов read()"
+6 "переменная или элемент массива является неправильным типом"
+7 "стопка имеет слишком мало элементов"
+8 "стопка имеет для регистра \"%s\" слишком мало элементов"
+9 "неправильное количество параметров; нужно %zu, нужно %zu"
+10 "неопределенная функция: %s()"
+11 "не может использовать пустое значение в выражении"
+
+$ Фатальные ошибки.
+$set 6
+
+1 "Не удалось выделить память"
+2 "Ошибка ввода/вывода"
+3 "не смог открыть файл: %s"
+4 "файл не является текстовым: %s"
+5 "путь - это каталог: %s"
+6 "неверная опция командной строки: \"%s\""
+7 "опция требует аргумента: '%c' (\"%s\")"
+8 "опция не принимает аргументов: '%c' (\"%s\")"
+9 "неверный аргумент опции командной строки: \"%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..fb80db7de55d
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.GB18030.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 "Ч䣺scaleibaseobaselastvarԪ"
+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 "POSIXifѭ֮ıȽ"
+23 "POSIXҪÿıȽΪ01"
+24 "POSIXҪforѭ3ֱǷǿյ"
+25 "POSIXʹָ"
+26 "POSIXΪ"
+27 "POSIXҪߵźͺͷͬһ"
+28 "POSIXַ"
+
+$ ʱ
+$set 5
+
+1 "Чibase: [%lu, %lu]"
+2 "Чobase[%lu%lu]"
+3 "Чscale[%lu%lu]"
+4 "Чread()ʽ"
+5 "ݹȡ()"
+6 "ԪǴ"
+7 "ջԪ̫"
+8 "Ĵ \"%s\" ĶջԪ̫"
+9 "Ҫ%zu%zu"
+10 "δĺ%s()"
+11 ڱʽʹÿֵ
+
+$
+$set 6
+
+1 "ڴʧ"
+2 "I/O"
+3 "޷ļ%s"
+4 "ļı%s"
+5 "·һĿ¼%s"
+6 "Чѡ\"%s\""
+7 "ѡҪһ'%c'(\"%s\")"
+8 "ѡҪ'%c'(\"%s\")"
+9 "Чѡ\"%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..fb80db7de55d
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.GB2312.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 "Ч䣺scaleibaseobaselastvarԪ"
+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 "POSIXifѭ֮ıȽ"
+23 "POSIXҪÿıȽΪ01"
+24 "POSIXҪforѭ3ֱǷǿյ"
+25 "POSIXʹָ"
+26 "POSIXΪ"
+27 "POSIXҪߵźͺͷͬһ"
+28 "POSIXַ"
+
+$ ʱ
+$set 5
+
+1 "Чibase: [%lu, %lu]"
+2 "Чobase[%lu%lu]"
+3 "Чscale[%lu%lu]"
+4 "Чread()ʽ"
+5 "ݹȡ()"
+6 "ԪǴ"
+7 "ջԪ̫"
+8 "Ĵ \"%s\" ĶջԪ̫"
+9 "Ҫ%zu%zu"
+10 "δĺ%s()"
+11 ڱʽʹÿֵ
+
+$
+$set 6
+
+1 "ڴʧ"
+2 "I/O"
+3 "޷ļ%s"
+4 "ļı%s"
+5 "·һĿ¼%s"
+6 "Чѡ\"%s\""
+7 "ѡҪһ'%c'(\"%s\")"
+8 "ѡҪ'%c'(\"%s\")"
+9 "Чѡ\"%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..fb80db7de55d
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.GBK.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 "Ч䣺scaleibaseobaselastvarԪ"
+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 "POSIXifѭ֮ıȽ"
+23 "POSIXҪÿıȽΪ01"
+24 "POSIXҪforѭ3ֱǷǿյ"
+25 "POSIXʹָ"
+26 "POSIXΪ"
+27 "POSIXҪߵźͺͷͬһ"
+28 "POSIXַ"
+
+$ ʱ
+$set 5
+
+1 "Чibase: [%lu, %lu]"
+2 "Чobase[%lu%lu]"
+3 "Чscale[%lu%lu]"
+4 "Чread()ʽ"
+5 "ݹȡ()"
+6 "ԪǴ"
+7 "ջԪ̫"
+8 "Ĵ \"%s\" ĶջԪ̫"
+9 "Ҫ%zu%zu"
+10 "δĺ%s()"
+11 ڱʽʹÿֵ
+
+$
+$set 6
+
+1 "ڴʧ"
+2 "I/O"
+3 "޷ļ%s"
+4 "ļı%s"
+5 "·һĿ¼%s"
+6 "Чѡ\"%s\""
+7 "ѡҪһ'%c'(\"%s\")"
+8 "ѡҪ'%c'(\"%s\")"
+9 "Чѡ\"%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..c327c0b1b98c
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.UTF-8.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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要求左边的括号和函数头在同一行上"
+28 "POSIX不允许将字符串分配给变量或数组"
+
+$ 运行时错误。
+$set 5
+
+1 "无效的ibase: 必须是[%lu, %lu]"
+2 "无效的obase:必须是[%lu,%lu]"
+3 "无效的scale:必须是[%lu,%lu]"
+4 "无效的read()表达式"
+5 "递归读取()调用"
+6 "变量或数组元素是错误的类型"
+7 "堆栈的元素太少"
+8 "寄存器 \"%s\" 的堆栈的元素太少"
+9 "参数数量错误:需要%zu,有%zu"
+10 "未定义的函数:%s()"
+11 “不能在表达式中使用空值”
+
+$ 致命错误。
+$set 6
+
+1 "内存分配失败"
+2 "I/O错误"
+3 "无法打开文件:%s"
+4 "文件不是文本:%s"
+5 "路径是一个目录:%s"
+6 "无效的命令行选项:\"%s\""
+7 "选项需要一个参数:'%c'(\"%s\")"
+8 "选项不需要参数:'%c'(\"%s\")"
+9 "无效的命令行选项参数:\"%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..fb80db7de55d
--- /dev/null
+++ b/contrib/bc/locales/zh_CN.eucCN.msg
@@ -0,0 +1,111 @@
+$ $
+$ SPDX-License-Identifier: BSD-2-Clause
+$ $
+$ Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+$ $
+$ Redistribution and use in source and binary forms, with or without
+$ modification, are permitted provided that the following conditions are met:
+$ $
+$ * Redistributions of source code must retain the above copyright notice, this
+$ list of conditions and the following disclaimer.
+$ $
+$ * Redistributions in binary form must reproduce the above copyright notice,
+$ this list of conditions and the following disclaimer in the documentation
+$ and/or other materials provided with the distribution.
+$ $
+$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+$ POSSIBILITY OF SUCH DAMAGE.
+$ $
+
+$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 "Ч䣺scaleibaseobaselastvarԪ"
+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 "POSIXifѭ֮ıȽ"
+23 "POSIXҪÿıȽΪ01"
+24 "POSIXҪforѭ3ֱǷǿյ"
+25 "POSIXʹָ"
+26 "POSIXΪ"
+27 "POSIXҪߵźͺͷͬһ"
+28 "POSIXַ"
+
+$ ʱ
+$set 5
+
+1 "Чibase: [%lu, %lu]"
+2 "Чobase[%lu%lu]"
+3 "Чscale[%lu%lu]"
+4 "Чread()ʽ"
+5 "ݹȡ()"
+6 "ԪǴ"
+7 "ջԪ̫"
+8 "Ĵ \"%s\" ĶջԪ̫"
+9 "Ҫ%zu%zu"
+10 "δĺ%s()"
+11 ڱʽʹÿֵ
+
+$
+$set 6
+
+1 "ڴʧ"
+2 "I/O"
+3 "޷ļ%s"
+4 "ļı%s"
+5 "·һĿ¼%s"
+6 "Чѡ\"%s\""
+7 "ѡҪһ'%c'(\"%s\")"
+8 "ѡҪ'%c'(\"%s\")"
+9 "Чѡ\"%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/manuals/algorithms.md b/contrib/bc/manuals/algorithms.md
new file mode 100644
index 000000000000..ef6b6d99a657
--- /dev/null
+++ b/contrib/bc/manuals/algorithms.md
@@ -0,0 +1,329 @@
+# 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/scripts/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, and
+it doubles the amount of correct digits per iteration.
+
+### Sine and Cosine (`bc` Math Library 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` Math Library 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` Math Library 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` Math Library 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` Math Library 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.
+
+### Non-Integer Exponentiation (`bc` Math Library 2 Only)
+
+This is implemented in the function `p(x,y)`.
+
+The algorithm used is to use the formula `e(y*l(x))`.
+
+It has a complexity of `O(n^3)` because both `e()` and `l()` do.
+
+### Rounding (`bc` Math Library 2 Only)
+
+This is implemented in the function `r(x,p)`.
+
+The algorithm is a simple method to check if rounding away from zero is
+necessary, and if so, adds `1e10^p`.
+
+It has a complexity of `O(n)` because of add.
+
+### Ceiling (`bc` Math Library 2 Only)
+
+This is implemented in the function `ceil(x,p)`.
+
+The algorithm is a simple add of one less decimal place than `p`.
+
+It has a complexity of `O(n)` because of add.
+
+### Factorial (`bc` Math Library 2 Only)
+
+This is implemented in the function `f(n)`.
+
+The algorithm is a simple multiplication loop.
+
+It has a complexity of `O(n^3)` because of linear amount of `O(n^2)`
+multiplications.
+
+### Permutations (`bc` Math Library 2 Only)
+
+This is implemented in the function `perm(n,k)`.
+
+The algorithm is to use the formula `n!/(n-k)!`.
+
+It has a complexity of `O(n^3)` because of the division and factorials.
+
+### Combinations (`bc` Math Library 2 Only)
+
+This is implemented in the function `comb(n,r)`.
+
+The algorithm is to use the formula `n!/r!*(n-r)!`.
+
+It has a complexity of `O(n^3)` because of the division and factorials.
+
+### Logarithm of Any Base (`bc` Math Library 2 Only)
+
+This is implemented in the function `log(x,b)`.
+
+The algorithm is to use the formula `l(x)/l(b)` with double the `scale` because
+there is no good way of knowing how many digits of precision are needed when
+switching bases.
+
+It has a complexity of `O(n^3)` because of the division and `l()`.
+
+### Logarithm of Base 2 (`bc` Math Library 2 Only)
+
+This is implemented in the function `l2(x)`.
+
+This is a convenience wrapper around `log(x,2)`.
+
+### Logarithm of Base 10 (`bc` Math Library 2 Only)
+
+This is implemented in the function `l10(x)`.
+
+This is a convenience wrapper around `log(x,10)`.
+
+### Root (`bc` Math Library 2 Only)
+
+This is implemented in the function `root(x,n)`.
+
+The algorithm is [Newton's method][9]. The initial guess is calculated as
+`10^ceil(length(x)/n)`.
+
+Like square root, its complexity is `O(log(n)*n^2)` as it requires one division
+per iteration, and it doubles the amount of correct digits per iteration.
+
+### Cube Root (`bc` Math Library 2 Only)
+
+This is implemented in the function `cbrt(x)`.
+
+This is a convenience wrapper around `root(x,3)`.
+
+### Greatest Common Divisor (`bc` Math Library 2 Only)
+
+This is implemented in the function `gcd(a,b)`.
+
+The algorithm is an iterative version of the [Euclidean Algorithm][10].
+
+It has a complexity of `O(n^4)` because it has a linear number of divisions.
+
+This function ensures that `a` is always bigger than `b` before starting the
+algorithm.
+
+### Least Common Multiple (`bc` Math Library 2 Only)
+
+This is implemented in the function `lcm(a,b)`.
+
+The algorithm uses the formula `a*b/gcd(a,b)`.
+
+It has a complexity of `O(n^4)` because of `gcd()`.
+
+### Pi (`bc` Math Library 2 Only)
+
+This is implemented in the function `pi(s)`.
+
+The algorithm uses the formula `4*a(1)`.
+
+It has a complexity of `O(n^3)` because of arctangent.
+
+### Tangent (`bc` Math Library 2 Only)
+
+This is implemented in the function `t(x)`.
+
+The algorithm uses the formula `s(x)/c(x)`.
+
+It has a complexity of `O(n^3)` because of sine, cosine, and division.
+
+### Atan2 (`bc` Math Library 2 Only)
+
+This is implemented in the function `a2(y,x)`.
+
+The algorithm uses the [standard formulas][11].
+
+It has a complexity of `O(n^3)` because of arctangent.
+
+[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
+[9]: https://en.wikipedia.org/wiki/Root-finding_algorithms#Newton's_method_(and_similar_derivative-based_methods)
+[10]: https://en.wikipedia.org/wiki/Euclidean_algorithm
+[11]: https://en.wikipedia.org/wiki/Atan2#Definition_and_computation
diff --git a/contrib/bc/manuals/bc/A.1 b/contrib/bc/manuals/bc/A.1
new file mode 100644
index 000000000000..bf6c9108456b
--- /dev/null
+++ b/contrib/bc/manuals/bc/A.1
@@ -0,0 +1,2784 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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.
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and
+\f[B]seed\f[R] into stacks.
+.RS
+.PP
+This has the effect that a copy of the current value of all four are
+pushed onto a stack for every function call, as well as popped when
+every function returns.
+This means that functions can assign to any and all of those globals
+without worrying that the change will affect other functions.
+Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply
+printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this:
+.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]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library and the extended math library before
+running any code, including any expressions or files specified on the
+command line.
+.RS
+.PP
+To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]irand\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxrand\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]rand\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]seed\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "20." 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 "21." 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 "22." 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.
+This means that the pseudo-random values from bc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]--standard\f[R] or \f[B]-w\f[R]/\f[B]--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]gcd(a, b)\f[R]
+Returns the greatest common divisor (factor) of the truncated absolute
+value of \f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.TP
+\f[B]lcm(a, b)\f[R]
+Returns the least common multiple of the truncated absolute value of
+\f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.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]band(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]and\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]or\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bxor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]xor\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshl(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of \f[B]a\f[R] bit-shifted left by
+\f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshr(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the truncated result of \f[B]a\f[R]
+bit-shifted right by \f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnotn(x, n)\f[R]
+Takes the truncated absolute value of \f[B]x\f[R] and does a bitwise not
+as though it has the same number of bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot8(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]8\f[R] binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot16(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]16\f[R] binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot32(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]32\f[R] binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot64(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]64\f[R] binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brevn(x, n)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the same number of 8-bit bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev8(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 8 binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev16(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 16 binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev32(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 32 binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev64(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 64 binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]broln(x, p, n)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol8(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol16(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol32(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol64(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brorn(x, p, n)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror8(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror16(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror32(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror64(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmodn(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of the multiplication of the truncated absolute
+value of \f[B]n\f[R] and \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod8(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod16(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod32(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod64(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bunrev(t)\f[R]
+Assumes \f[B]t\f[R] is a bitwise-reversed number with an extra set bit
+one place more significant than the real most significant bit (which was
+the least significant bit in the original number).
+This number is reversed and returned without the extra set bit.
+.RS
+.PP
+This function is used to implement other bitwise functions; it is not
+meant to be used by users, but it can be.
+.RE
+.TP
+\f[B]plz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]plznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.TP
+\f[B]pnlz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]pnlznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.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]s2u(x)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer and returns the non-negative
+integer that would have the same representation in binary.
+.TP
+\f[B]s2un(x,n)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer with \f[B]n\f[R] bytes and
+returns the non-negative integer that would have the same representation
+in binary.
+If \f[B]x\f[R] cannot fit into \f[B]n\f[R] 2\[cq]s-complement signed
+bytes, it is truncated to fit.
+.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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]BC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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, and only when bc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If bc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]BC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If 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..e773d967284c
--- /dev/null
+++ b/contrib/bc/manuals/bc/A.1.md
@@ -0,0 +1,2347 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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.
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **irand**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxrand**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **rand**
+ * **read**
+ * **seed**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+20. **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**.
+21. **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**.
+22. **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. This
+means that the pseudo-random values from bc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+## 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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**.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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.
+
+**gcd(a, b)**
+
+: Returns the greatest common divisor (factor) of the truncated absolute value
+ of **a** and the truncated absolute value of **b**.
+
+**lcm(a, b)**
+
+: Returns the least common multiple of the truncated absolute value of **a**
+ and the truncated absolute value of **b**.
+
+**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**).
+
+**band(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **and** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **or** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bxor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **xor** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshl(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of **a** bit-shifted left by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshr(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the truncated result of **a** bit-shifted right by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bnotn(x, n)**
+
+: Takes the truncated absolute value of **x** and does a bitwise not as though
+ it has the same number of bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot8(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **8** binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot16(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **16** binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot32(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **32** binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot64(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **64** binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brevn(x, n)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the same number of 8-bit bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev8(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 8 binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev16(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 16 binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev32(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 32 binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev64(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 64 binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**broln(x, p, n)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol8(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol16(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol32(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol64(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brorn(x, p, n)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror8(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror16(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror32(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror64(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmodn(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of the multiplication of the truncated absolute value of **n** and
+ **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod8(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod16(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod32(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod64(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bunrev(t)**
+
+: Assumes **t** is a bitwise-reversed number with an extra set bit one place
+ more significant than the real most significant bit (which was the least
+ significant bit in the original number). This number is reversed and
+ returned without the extra set bit.
+
+ This function is used to implement other bitwise functions; it is not meant
+ to be used by users, but it can be.
+
+**plz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**plznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**pnlz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**pnlznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**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**.
+
+**s2u(x)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer and returns the
+ non-negative integer that would have the same representation in binary.
+
+**s2un(x,n)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer with **n** bytes and
+ returns the non-negative integer that would have the same representation in
+ binary. If **x** cannot fit into **n** 2's-complement signed bytes, it is
+ truncated to fit.
+
+**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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **BC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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, and only when bc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause bc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing.
+
+If bc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**BC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+If 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..bb563f5c96fc
--- /dev/null
+++ b/contrib/bc/manuals/bc/E.1
@@ -0,0 +1,1630 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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).
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]
+into stacks.
+.RS
+.PP
+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 \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
+However, since using this flag means that functions cannot set
+\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\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], or \f[B]scale\f[R] 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.
+.PP
+If the behavior of this option is desired for every run of bc(1), then
+users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this
+option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more
+details).
+.PP
+If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option
+is ignored.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library before running any code, including
+any expressions or files specified on the command line.
+.RS
+.PP
+To learn what is in the library, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]BC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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, and only when bc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If bc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]BC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If 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..63367e436cc8
--- /dev/null
+++ b/contrib/bc/manuals/bc/E.1.md
@@ -0,0 +1,1365 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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).
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **read**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **BC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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, and only when bc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause bc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing.
+
+If bc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**BC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+If 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..0bdfaa9fe14b
--- /dev/null
+++ b/contrib/bc/manuals/bc/EH.1
@@ -0,0 +1,1601 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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).
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]
+into stacks.
+.RS
+.PP
+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 \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
+However, since using this flag means that functions cannot set
+\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\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], or \f[B]scale\f[R] 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.
+.PP
+If the behavior of this option is desired for every run of bc(1), then
+users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this
+option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more
+details).
+.PP
+If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option
+is ignored.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library before running any code, including
+any expressions or files specified on the command line.
+.RS
+.PP
+To learn what is in the library, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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..044330b7fe0a
--- /dev/null
+++ b/contrib/bc/manuals/bc/EH.1.md
@@ -0,0 +1,1339 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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).
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **read**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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..f0519898ad7e
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHN.1
@@ -0,0 +1,1594 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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).
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]
+into stacks.
+.RS
+.PP
+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 \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
+However, since using this flag means that functions cannot set
+\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\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], or \f[B]scale\f[R] 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.
+.PP
+If the behavior of this option is desired for every run of bc(1), then
+users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this
+option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more
+details).
+.PP
+If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option
+is ignored.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library before running any code, including
+any expressions or files specified on the command line.
+.RS
+.PP
+To learn what is in the library, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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..25543500eea7
--- /dev/null
+++ b/contrib/bc/manuals/bc/EHN.1.md
@@ -0,0 +1,1331 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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).
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **read**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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/EN.1 b/contrib/bc/manuals/bc/EN.1
new file mode 100644
index 000000000000..192dccfea2fc
--- /dev/null
+++ b/contrib/bc/manuals/bc/EN.1
@@ -0,0 +1,1623 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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).
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]
+into stacks.
+.RS
+.PP
+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 \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
+However, since using this flag means that functions cannot set
+\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\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], or \f[B]scale\f[R] 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.
+.PP
+If the behavior of this option is desired for every run of bc(1), then
+users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this
+option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more
+details).
+.PP
+If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option
+is ignored.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library before running any code, including
+any expressions or files specified on the command line.
+.RS
+.PP
+To learn what is in the library, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]BC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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, and only when bc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If bc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]BC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If 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..e77d64cd7a56
--- /dev/null
+++ b/contrib/bc/manuals/bc/EN.1.md
@@ -0,0 +1,1357 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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).
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **read**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **BC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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, and only when bc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause bc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing.
+
+If bc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**BC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+If 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/H.1 b/contrib/bc/manuals/bc/H.1
new file mode 100644
index 000000000000..5f290f12ae32
--- /dev/null
+++ b/contrib/bc/manuals/bc/H.1
@@ -0,0 +1,2755 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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.
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and
+\f[B]seed\f[R] into stacks.
+.RS
+.PP
+This has the effect that a copy of the current value of all four are
+pushed onto a stack for every function call, as well as popped when
+every function returns.
+This means that functions can assign to any and all of those globals
+without worrying that the change will affect other functions.
+Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply
+printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this:
+.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]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library and the extended math library before
+running any code, including any expressions or files specified on the
+command line.
+.RS
+.PP
+To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]irand\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxrand\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]rand\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]seed\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "20." 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 "21." 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 "22." 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.
+This means that the pseudo-random values from bc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]--standard\f[R] or \f[B]-w\f[R]/\f[B]--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]gcd(a, b)\f[R]
+Returns the greatest common divisor (factor) of the truncated absolute
+value of \f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.TP
+\f[B]lcm(a, b)\f[R]
+Returns the least common multiple of the truncated absolute value of
+\f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.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]band(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]and\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]or\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bxor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]xor\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshl(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of \f[B]a\f[R] bit-shifted left by
+\f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshr(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the truncated result of \f[B]a\f[R]
+bit-shifted right by \f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnotn(x, n)\f[R]
+Takes the truncated absolute value of \f[B]x\f[R] and does a bitwise not
+as though it has the same number of bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot8(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]8\f[R] binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot16(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]16\f[R] binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot32(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]32\f[R] binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot64(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]64\f[R] binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brevn(x, n)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the same number of 8-bit bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev8(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 8 binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev16(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 16 binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev32(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 32 binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev64(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 64 binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]broln(x, p, n)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol8(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol16(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol32(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol64(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brorn(x, p, n)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror8(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror16(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror32(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror64(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmodn(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of the multiplication of the truncated absolute
+value of \f[B]n\f[R] and \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod8(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod16(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod32(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod64(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bunrev(t)\f[R]
+Assumes \f[B]t\f[R] is a bitwise-reversed number with an extra set bit
+one place more significant than the real most significant bit (which was
+the least significant bit in the original number).
+This number is reversed and returned without the extra set bit.
+.RS
+.PP
+This function is used to implement other bitwise functions; it is not
+meant to be used by users, but it can be.
+.RE
+.TP
+\f[B]plz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]plznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.TP
+\f[B]pnlz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]pnlznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.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]s2u(x)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer and returns the non-negative
+integer that would have the same representation in binary.
+.TP
+\f[B]s2un(x,n)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer with \f[B]n\f[R] bytes and
+returns the non-negative integer that would have the same representation
+in binary.
+If \f[B]x\f[R] cannot fit into \f[B]n\f[R] 2\[cq]s-complement signed
+bytes, it is truncated to fit.
+.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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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..99c88db93230
--- /dev/null
+++ b/contrib/bc/manuals/bc/H.1.md
@@ -0,0 +1,2321 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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.
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **irand**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxrand**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **rand**
+ * **read**
+ * **seed**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+20. **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**.
+21. **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**.
+22. **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. This
+means that the pseudo-random values from bc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+## 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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**.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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.
+
+**gcd(a, b)**
+
+: Returns the greatest common divisor (factor) of the truncated absolute value
+ of **a** and the truncated absolute value of **b**.
+
+**lcm(a, b)**
+
+: Returns the least common multiple of the truncated absolute value of **a**
+ and the truncated absolute value of **b**.
+
+**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**).
+
+**band(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **and** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **or** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bxor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **xor** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshl(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of **a** bit-shifted left by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshr(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the truncated result of **a** bit-shifted right by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bnotn(x, n)**
+
+: Takes the truncated absolute value of **x** and does a bitwise not as though
+ it has the same number of bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot8(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **8** binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot16(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **16** binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot32(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **32** binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot64(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **64** binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brevn(x, n)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the same number of 8-bit bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev8(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 8 binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev16(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 16 binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev32(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 32 binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev64(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 64 binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**broln(x, p, n)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol8(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol16(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol32(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol64(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brorn(x, p, n)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror8(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror16(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror32(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror64(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmodn(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of the multiplication of the truncated absolute value of **n** and
+ **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod8(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod16(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod32(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod64(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bunrev(t)**
+
+: Assumes **t** is a bitwise-reversed number with an extra set bit one place
+ more significant than the real most significant bit (which was the least
+ significant bit in the original number). This number is reversed and
+ returned without the extra set bit.
+
+ This function is used to implement other bitwise functions; it is not meant
+ to be used by users, but it can be.
+
+**plz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**plznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**pnlz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**pnlznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**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**.
+
+**s2u(x)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer and returns the
+ non-negative integer that would have the same representation in binary.
+
+**s2un(x,n)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer with **n** bytes and
+ returns the non-negative integer that would have the same representation in
+ binary. If **x** cannot fit into **n** 2's-complement signed bytes, it is
+ truncated to fit.
+
+**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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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..4773ff77efea
--- /dev/null
+++ b/contrib/bc/manuals/bc/HN.1
@@ -0,0 +1,2748 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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.
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and
+\f[B]seed\f[R] into stacks.
+.RS
+.PP
+This has the effect that a copy of the current value of all four are
+pushed onto a stack for every function call, as well as popped when
+every function returns.
+This means that functions can assign to any and all of those globals
+without worrying that the change will affect other functions.
+Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply
+printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this:
+.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]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library and the extended math library before
+running any code, including any expressions or files specified on the
+command line.
+.RS
+.PP
+To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]irand\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxrand\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]rand\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]seed\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "20." 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 "21." 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 "22." 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.
+This means that the pseudo-random values from bc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]--standard\f[R] or \f[B]-w\f[R]/\f[B]--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]gcd(a, b)\f[R]
+Returns the greatest common divisor (factor) of the truncated absolute
+value of \f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.TP
+\f[B]lcm(a, b)\f[R]
+Returns the least common multiple of the truncated absolute value of
+\f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.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]band(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]and\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]or\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bxor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]xor\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshl(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of \f[B]a\f[R] bit-shifted left by
+\f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshr(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the truncated result of \f[B]a\f[R]
+bit-shifted right by \f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnotn(x, n)\f[R]
+Takes the truncated absolute value of \f[B]x\f[R] and does a bitwise not
+as though it has the same number of bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot8(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]8\f[R] binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot16(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]16\f[R] binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot32(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]32\f[R] binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot64(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]64\f[R] binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brevn(x, n)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the same number of 8-bit bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev8(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 8 binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev16(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 16 binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev32(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 32 binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev64(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 64 binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]broln(x, p, n)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol8(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol16(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol32(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol64(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brorn(x, p, n)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror8(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror16(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror32(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror64(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmodn(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of the multiplication of the truncated absolute
+value of \f[B]n\f[R] and \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod8(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod16(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod32(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod64(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bunrev(t)\f[R]
+Assumes \f[B]t\f[R] is a bitwise-reversed number with an extra set bit
+one place more significant than the real most significant bit (which was
+the least significant bit in the original number).
+This number is reversed and returned without the extra set bit.
+.RS
+.PP
+This function is used to implement other bitwise functions; it is not
+meant to be used by users, but it can be.
+.RE
+.TP
+\f[B]plz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]plznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.TP
+\f[B]pnlz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]pnlznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.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]s2u(x)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer and returns the non-negative
+integer that would have the same representation in binary.
+.TP
+\f[B]s2un(x,n)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer with \f[B]n\f[R] bytes and
+returns the non-negative integer that would have the same representation
+in binary.
+If \f[B]x\f[R] cannot fit into \f[B]n\f[R] 2\[cq]s-complement signed
+bytes, it is truncated to fit.
+.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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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..d5b3324514ad
--- /dev/null
+++ b/contrib/bc/manuals/bc/HN.1.md
@@ -0,0 +1,2313 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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.
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **irand**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxrand**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **rand**
+ * **read**
+ * **seed**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+20. **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**.
+21. **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**.
+22. **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. This
+means that the pseudo-random values from bc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+## 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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**.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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.
+
+**gcd(a, b)**
+
+: Returns the greatest common divisor (factor) of the truncated absolute value
+ of **a** and the truncated absolute value of **b**.
+
+**lcm(a, b)**
+
+: Returns the least common multiple of the truncated absolute value of **a**
+ and the truncated absolute value of **b**.
+
+**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**).
+
+**band(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **and** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **or** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bxor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **xor** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshl(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of **a** bit-shifted left by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshr(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the truncated result of **a** bit-shifted right by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bnotn(x, n)**
+
+: Takes the truncated absolute value of **x** and does a bitwise not as though
+ it has the same number of bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot8(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **8** binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot16(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **16** binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot32(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **32** binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot64(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **64** binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brevn(x, n)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the same number of 8-bit bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev8(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 8 binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev16(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 16 binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev32(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 32 binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev64(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 64 binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**broln(x, p, n)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol8(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol16(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol32(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol64(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brorn(x, p, n)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror8(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror16(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror32(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror64(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmodn(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of the multiplication of the truncated absolute value of **n** and
+ **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod8(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod16(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod32(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod64(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bunrev(t)**
+
+: Assumes **t** is a bitwise-reversed number with an extra set bit one place
+ more significant than the real most significant bit (which was the least
+ significant bit in the original number). This number is reversed and
+ returned without the extra set bit.
+
+ This function is used to implement other bitwise functions; it is not meant
+ to be used by users, but it can be.
+
+**plz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**plznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**pnlz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**pnlznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**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**.
+
+**s2u(x)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer and returns the
+ non-negative integer that would have the same representation in binary.
+
+**s2un(x,n)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer with **n** bytes and
+ returns the non-negative integer that would have the same representation in
+ binary. If **x** cannot fit into **n** 2's-complement signed bytes, it is
+ truncated to fit.
+
+**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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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/N.1 b/contrib/bc/manuals/bc/N.1
new file mode 100644
index 000000000000..56fca3d02b4d
--- /dev/null
+++ b/contrib/bc/manuals/bc/N.1
@@ -0,0 +1,2777 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH NAME
+.PP
+bc - arbitrary-precision decimal arithmetic language and calculator
+.SH SYNOPSIS
+.PP
+\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]]
+[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]]
+[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+bc(1) is an interactive processor for a language first standardized in
+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.
+.PP
+\f[B]Note\f[R]: If running this bc(1) on \f[I]any\f[R] script meant for
+another bc(1) gives a parse error, it is probably because a word this
+bc(1) reserves as a keyword is used as the name of a function, variable,
+or array.
+To fix that, use the command-line option \f[B]-r\f[R] \f[I]keyword\f[R],
+where \f[I]keyword\f[R] is the keyword that is used as a name in the
+script.
+For more information, see the \f[B]OPTIONS\f[R] section.
+.PP
+If parsing scripts meant for other bc(1) implementations still does not
+work, that is a bug and should be reported.
+See the \f[B]BUGS\f[R] section.
+.SH OPTIONS
+.PP
+The following are the options that bc(1) accepts.
+.TP
+\f[B]-g\f[R], \f[B]--global-stacks\f[R]
+Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and
+\f[B]seed\f[R] into stacks.
+.RS
+.PP
+This has the effect that a copy of the current value of all four are
+pushed onto a stack for every function call, as well as popped when
+every function returns.
+This means that functions can assign to any and all of those globals
+without worrying that the change will affect other functions.
+Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply
+printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this:
+.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]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-l\f[R], \f[B]--mathlib\f[R]
+Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R]
+and loads the included math library and the extended math library before
+running any code, including any expressions or files specified on the
+command line.
+.RS
+.PP
+To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section.
+.RE
+.TP
+\f[B]-P\f[R], \f[B]--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
+These options override the \f[B]BC_PROMPT\f[R] and \f[B]BC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in bc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of bc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]read()\f[R] built-in function is called.
+.PP
+These options \f[I]do\f[R] override the \f[B]BC_PROMPT\f[R] and
+\f[B]BC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-r\f[R] \f[I]keyword\f[R], \f[B]--redefine\f[R]=\f[I]keyword\f[R]
+Redefines \f[I]keyword\f[R] in order to allow it to be used as a
+function, variable, or array name.
+This is useful when this bc(1) gives parse errors when parsing scripts
+meant for other bc(1) implementations.
+.RS
+.PP
+The keywords this bc(1) allows to be redefined are:
+.IP \[bu] 2
+\f[B]abs\f[R]
+.IP \[bu] 2
+\f[B]asciify\f[R]
+.IP \[bu] 2
+\f[B]continue\f[R]
+.IP \[bu] 2
+\f[B]divmod\f[R]
+.IP \[bu] 2
+\f[B]else\f[R]
+.IP \[bu] 2
+\f[B]halt\f[R]
+.IP \[bu] 2
+\f[B]irand\f[R]
+.IP \[bu] 2
+\f[B]last\f[R]
+.IP \[bu] 2
+\f[B]limits\f[R]
+.IP \[bu] 2
+\f[B]maxibase\f[R]
+.IP \[bu] 2
+\f[B]maxobase\f[R]
+.IP \[bu] 2
+\f[B]maxrand\f[R]
+.IP \[bu] 2
+\f[B]maxscale\f[R]
+.IP \[bu] 2
+\f[B]modexp\f[R]
+.IP \[bu] 2
+\f[B]print\f[R]
+.IP \[bu] 2
+\f[B]rand\f[R]
+.IP \[bu] 2
+\f[B]read\f[R]
+.IP \[bu] 2
+\f[B]seed\f[R]
+.IP \[bu] 2
+\f[B]stream\f[R]
+.PP
+If any of those keywords are used as a function, variable, or array name
+in a script, use this option with the keyword as the argument.
+If multiple are used, use this option for all of them; it can be used
+multiple times.
+.PP
+Keywords are \f[I]not\f[R] redefined when parsing the builtin math
+library (see the \f[B]LIBRARY\f[R] section).
+.PP
+It is a fatal error to redefine keywords mandated by the POSIX standard.
+It is a fatal error to attempt to redefine words that this bc(1) does
+not reserve as keywords.
+.RE
+.TP
+\f[B]-q\f[R], \f[B]--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]--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]--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]--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]--warn\f[R]
+Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and
+not errors) are printed for non-standard extensions and execution
+continues normally.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]BC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, bc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files or expressions are given by the \f[B]-f\f[R],
+\f[B]--file\f[R], \f[B]-e\f[R], or \f[B]--expression\f[R] options, then
+bc(1) read from \f[B]stdin\f[R].
+.PP
+However, there are a few caveats to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if the parse cannot complete.
+That means that starting a string without ending it or starting a
+function, \f[B]if\f[R] statement, or loop without ending it will also
+cause bc(1) to not execute.
+.PP
+Second, after an \f[B]if\f[R] statement, bc(1) doesn\[cq]t know if an
+\f[B]else\f[R] statement will follow, so it will not execute until it
+knows there will not be an \f[B]else\f[R] statement.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]--standard\f[R]) and \f[B]-w\f[R]
+(\f[B]--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].
+Returns \f[B]1\f[R] for \f[B]0\f[R] with no decimal places.
+If given a string, the length of the string is returned.
+Passing a string to \f[B]length(E)\f[R] is a \f[B]non-portable
+extension\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]modexp(E, E, E)\f[R]: Modular exponentiation, where the first
+expression is the base, the second is the exponent, and the third is the
+modulus.
+All three values must be integers.
+The second argument must be non-negative.
+The third argument must be non-zero.
+This is a \f[B]non-portable extension\f[R].
+.IP "10." 4
+\f[B]divmod(E, E, I[])\f[R]: Division and modulus in one operation.
+This is for optimization.
+The first expression is the dividend, and the second is the divisor,
+which must be non-zero.
+The return value is the quotient, and the modulus is stored in index
+\f[B]0\f[R] of the provided array (the last argument).
+This is a \f[B]non-portable extension\f[R].
+.IP "11." 4
+\f[B]asciify(E)\f[R]: If \f[B]E\f[R] is a string, returns a string that
+is the first letter of its argument.
+If it is a number, calculates the number mod \f[B]256\f[R] and returns
+that number as a one-character string.
+This is a \f[B]non-portable extension\f[R].
+.IP "12." 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 "13." 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 "14." 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 "15." 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 "16." 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 "17." 4
+\f[B]line_length()\f[R]: The line length set with
+\f[B]BC_LINE_LENGTH\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+This is a \f[B]non-portable extension\f[R].
+.IP "18." 4
+\f[B]global_stacks()\f[R]: \f[B]0\f[R] if global stacks are not enabled
+with the \f[B]-g\f[R] or \f[B]--global-stacks\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "19." 4
+\f[B]leading_zero()\f[R]: \f[B]0\f[R] if leading zeroes are not enabled
+with the \f[B]-z\f[R] or \f[B]\[en]leading-zeroes\f[R] options, non-zero
+otherwise.
+See the \f[B]OPTIONS\f[R] section.
+This is a \f[B]non-portable extension\f[R].
+.IP "20." 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 "21." 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 "22." 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.
+This means that the pseudo-random values from bc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]--\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]--\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]stream\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R]
+.IP "16." 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, 15, and 16 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 Strings
+.PP
+If strings appear as a statement by themselves, they are printed without
+a trailing newline.
+.PP
+In addition to appearing as a lone statement by themselves, strings can
+be assigned to variables and array elements.
+They can also be passed to functions in variable parameters.
+.PP
+If any statement that expects a string is given a variable that had a
+string assigned to it, the statement acts as though it had received a
+string.
+.PP
+If any math operation is attempted on a string or a variable or array
+element that has been assigned a string, an error is raised, and bc(1)
+resets (see the \f[B]RESET\f[R] section).
+.PP
+Assigning strings to variables and array elements and passing them to
+functions are \f[B]non-portable extensions\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
+\f[B]\[rs]a\f[R]: \f[B]\[rs]a\f[R]
+.PP
+\f[B]\[rs]b\f[R]: \f[B]\[rs]b\f[R]
+.PP
+\f[B]\[rs]\[rs]\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]e\f[R]: \f[B]\[rs]\f[R]
+.PP
+\f[B]\[rs]f\f[R]: \f[B]\[rs]f\f[R]
+.PP
+\f[B]\[rs]n\f[R]: \f[B]\[rs]n\f[R]
+.PP
+\f[B]\[rs]q\f[R]: \f[B]\[lq]\f[R]
+.PP
+\f[B]\[rs]r\f[R]: \f[B]\[rs]r\f[R]
+.PP
+\f[B]\[rs]t\f[R]: \f[B]\[rs]t\f[R]
+.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 Stream Statement
+.PP
+The \[lq]expressions in a \f[B]stream\f[R] statement may also be
+strings.
+.PP
+If a \f[B]stream\f[R] statement is given a string, it prints the string
+as though the string had appeared as its own statement.
+In other words, the \f[B]stream\f[R] statement prints strings normally,
+without a newline.
+.PP
+If a \f[B]stream\f[R] statement is given a number, a copy of it is
+truncated and its absolute value is calculated.
+The result is then printed as though \f[B]obase\f[R] is \f[B]256\f[R]
+and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+.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]--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]--standard\f[R] or \f[B]-w\f[R]/\f[B]--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]gcd(a, b)\f[R]
+Returns the greatest common divisor (factor) of the truncated absolute
+value of \f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.TP
+\f[B]lcm(a, b)\f[R]
+Returns the least common multiple of the truncated absolute value of
+\f[B]a\f[R] and the truncated absolute value of \f[B]b\f[R].
+.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]band(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]and\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]or\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bxor(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of the bitwise \f[B]xor\f[R]
+operation between them.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshl(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the result of \f[B]a\f[R] bit-shifted left by
+\f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bshr(a, b)\f[R]
+Takes the truncated absolute value of both \f[B]a\f[R] and \f[B]b\f[R]
+and calculates and returns the truncated result of \f[B]a\f[R]
+bit-shifted right by \f[B]b\f[R] places.
+.RS
+.PP
+If you want to use signed two\[cq]s complement arguments, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnotn(x, n)\f[R]
+Takes the truncated absolute value of \f[B]x\f[R] and does a bitwise not
+as though it has the same number of bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot8(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]8\f[R] binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot16(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]16\f[R] binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot32(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]32\f[R] binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot64(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has \f[B]64\f[R] binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bnot(x)\f[R]
+Does a bitwise not of the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brevn(x, n)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the same number of 8-bit bytes as the truncated absolute
+value of \f[B]n\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev8(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 8 binary digits (1 unsigned byte).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev16(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 16 binary digits (2 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev32(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 32 binary digits (4 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev64(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has 64 binary digits (8 unsigned bytes).
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brev(x)\f[R]
+Runs a bit reversal on the truncated absolute value of \f[B]x\f[R] as
+though it has the minimum number of power of two unsigned bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]broln(x, p, n)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol8(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol16(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol32(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol64(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brol(x, p)\f[R]
+Does a left bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]brorn(x, p, n)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the same number of unsigned 8-bit bytes as
+the truncated absolute value of \f[B]n\f[R], by the number of places
+equal to the truncated absolute value of \f[B]p\f[R] modded by the
+\f[B]2\f[R] to the power of the number of binary digits in \f[B]n\f[R]
+8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror8(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]8\f[R] binary digits (\f[B]1\f[R]
+unsigned byte), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror16(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]16\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror32(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]32\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror64(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has \f[B]64\f[R] binary digits (\f[B]2\f[R]
+unsigned bytes), by the number of places equal to the truncated absolute
+value of \f[B]p\f[R] modded by \f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bror(x, p)\f[R]
+Does a right bitwise rotatation of the truncated absolute value of
+\f[B]x\f[R], as though it has the minimum number of power of two
+unsigned 8-bit bytes, by the number of places equal to the truncated
+absolute value of \f[B]p\f[R] modded by 2 to the power of the number of
+binary digits in the minimum number of 8-bit bytes.
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmodn(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of the multiplication of the truncated absolute
+value of \f[B]n\f[R] and \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod8(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]8\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod16(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]16\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod32(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]32\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bmod64(x, n)\f[R]
+Returns the modulus of the truncated absolute value of \f[B]x\f[R] by
+\f[B]2\f[R] to the power of \f[B]64\f[R].
+.RS
+.PP
+If you want to a use signed two\[cq]s complement argument, use
+\f[B]s2u(x)\f[R] to convert.
+.RE
+.TP
+\f[B]bunrev(t)\f[R]
+Assumes \f[B]t\f[R] is a bitwise-reversed number with an extra set bit
+one place more significant than the real most significant bit (which was
+the least significant bit in the original number).
+This number is reversed and returned without the extra set bit.
+.RS
+.PP
+This function is used to implement other bitwise functions; it is not
+meant to be used by users, but it can be.
+.RE
+.TP
+\f[B]plz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]plznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed with a leading zero, regardless
+of the use of the \f[B]-z\f[R] option (see the \f[B]OPTIONS\f[R]
+section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.TP
+\f[B]pnlz(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and without a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, without a trailing newline.
+.RE
+.TP
+\f[B]pnlznl(x)\f[R]
+If \f[B]x\f[R] is not equal to \f[B]0\f[R] and greater that \f[B]-1\f[R]
+and less than \f[B]1\f[R], it is printed without a leading zero,
+regardless of the use of the \f[B]-z\f[R] option (see the
+\f[B]OPTIONS\f[R] section) and with a trailing newline.
+.RS
+.PP
+Otherwise, \f[B]x\f[R] is printed normally, with a trailing newline.
+.RE
+.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]s2u(x)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer and returns the non-negative
+integer that would have the same representation in binary.
+.TP
+\f[B]s2un(x,n)\f[R]
+Returns \f[B]x\f[R] if it is non-negative.
+If it \f[I]is\f[R] negative, then it calculates what \f[B]x\f[R] would
+be as a 2\[cq]s-complement signed integer with \f[B]n\f[R] bytes and
+returns the non-negative integer that would have the same representation
+in binary.
+If \f[B]x\f[R] cannot fit into \f[B]n\f[R] 2\[cq]s-complement signed
+bytes, it is truncated to fit.
+.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]\[lq]some
+`bc' file.bc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]BC_BANNER\f[R]
+If this environment variable exists and contains an integer, then a
+non-zero value activates the copyright banner when bc(1) is in
+interactive mode, while zero deactivates it.
+.RS
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+does not print the banner when not in interactive mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_SIGINT_RESET\f[R]
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because bc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when bc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes bc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes bc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then bc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes bc(1) use
+TTY mode, and zero makes bc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]BC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes bc(1) use a
+prompt, and zero or a non-integer makes bc(1) not use a prompt.
+If this environment variable does not exist and \f[B]BC_TTY_MODE\f[R]
+does, then the value of the \f[B]BC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+bc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]BC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, bc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]BC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, bc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]BC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then bc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]BC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]BC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]BC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]BC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]BC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]BC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause bc(1) to do one of two things.
+.PP
+If bc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]BC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, bc(1) will exit.
+.PP
+However, if bc(1) is in interactive mode, and the
+\f[B]BC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then bc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If bc(1) is processing input from a file in interactive 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, and only when bc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If bc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]BC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If 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..51dad376b56d
--- /dev/null
+++ b/contrib/bc/manuals/bc/N.1.md
@@ -0,0 +1,2339 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# NAME
+
+bc - arbitrary-precision decimal arithmetic language and calculator
+
+# SYNOPSIS
+
+**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...]
+
+# DESCRIPTION
+
+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.
+
+**Note**: If running this bc(1) on *any* script meant for another bc(1) gives a
+parse error, it is probably because a word this bc(1) reserves as a keyword is
+used as the name of a function, variable, or array. To fix that, use the
+command-line option **-r** *keyword*, where *keyword* is the keyword that is
+used as a name in the script. For more information, see the **OPTIONS** section.
+
+If parsing scripts meant for other bc(1) implementations still does not work,
+that is a bug and should be reported. See the **BUGS** section.
+
+# 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**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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).
+
+ These options override the **BC_PROMPT** and **BC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in bc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of bc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **read()** built-in function is called.
+
+ These options *do* override the **BC_PROMPT** and **BC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ This is a **non-portable extension**.
+
+**-r** *keyword*, **-\-redefine**=*keyword*
+
+: Redefines *keyword* in order to allow it to be used as a function, variable,
+ or array name. This is useful when this bc(1) gives parse errors when
+ parsing scripts meant for other bc(1) implementations.
+
+ The keywords this bc(1) allows to be redefined are:
+
+ * **abs**
+ * **asciify**
+ * **continue**
+ * **divmod**
+ * **else**
+ * **halt**
+ * **irand**
+ * **last**
+ * **limits**
+ * **maxibase**
+ * **maxobase**
+ * **maxrand**
+ * **maxscale**
+ * **modexp**
+ * **print**
+ * **rand**
+ * **read**
+ * **seed**
+ * **stream**
+
+ If any of those keywords are used as a function, variable, or array name in
+ a script, use this option with the keyword as the argument. If multiple are
+ used, use this option for all of them; it can be used multiple times.
+
+ Keywords are *not* redefined when parsing the builtin math library (see the
+ **LIBRARY** section).
+
+ It is a fatal error to redefine keywords mandated by the POSIX standard. It
+ is a fatal error to attempt to redefine words that this bc(1) does not
+ reserve as keywords.
+
+**-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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **BC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, bc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, bc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files or expressions are given by the **-f**, **-\-file**, **-e**, or
+**-\-expression** options, then bc(1) read from **stdin**.
+
+However, there are a few caveats to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+the parse cannot complete. That means that starting a string without ending it
+or starting a function, **if** statement, or loop without ending it will also
+cause bc(1) to not execute.
+
+Second, after an **if** statement, bc(1) doesn't know if an **else** statement
+will follow, so it will not execute until it knows there will not be an **else**
+statement.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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**. Returns
+ **1** for **0** with no decimal places. If given a string, the length of the
+ string is returned. Passing a string to **length(E)** is a **non-portable
+ extension**.
+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. **modexp(E, E, E)**: Modular exponentiation, where the first expression is
+ the base, the second is the exponent, and the third is the modulus. All
+ three values must be integers. The second argument must be non-negative. The
+ third argument must be non-zero. This is a **non-portable extension**.
+10. **divmod(E, E, I[])**: Division and modulus in one operation. This is for
+ optimization. The first expression is the dividend, and the second is the
+ divisor, which must be non-zero. The return value is the quotient, and the
+ modulus is stored in index **0** of the provided array (the last argument).
+ This is a **non-portable extension**.
+11. **asciify(E)**: If **E** is a string, returns a string that is the first
+ letter of its argument. If it is a number, calculates the number mod **256**
+ and returns that number as a one-character string. This is a **non-portable
+ extension**.
+12. **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.
+13. **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**.
+14. **maxibase()**: The max allowable **ibase**. This is a **non-portable
+ extension**.
+15. **maxobase()**: The max allowable **obase**. This is a **non-portable
+ extension**.
+16. **maxscale()**: The max allowable **scale**. This is a **non-portable
+ extension**.
+17. **line_length()**: The line length set with **BC_LINE_LENGTH** (see the
+ **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**.
+18. **global_stacks()**: **0** if global stacks are not enabled with the **-g**
+ or **-\-global-stacks** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+19. **leading_zero()**: **0** if leading zeroes are not enabled with the **-z**
+ or **--leading-zeroes** options, non-zero otherwise. See the **OPTIONS**
+ section. This is a **non-portable extension**.
+20. **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**.
+21. **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**.
+22. **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. This
+means that the pseudo-random values from bc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+## 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. **stream** **E** **,** ... **,** **E**
+16. **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, 15, and 16 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**.
+
+## Strings
+
+If strings appear as a statement by themselves, they are printed without a
+trailing newline.
+
+In addition to appearing as a lone statement by themselves, strings can be
+assigned to variables and array elements. They can also be passed to functions
+in variable parameters.
+
+If any statement that expects a string is given a variable that had a string
+assigned to it, the statement acts as though it had received a string.
+
+If any math operation is attempted on a string or a variable or array element
+that has been assigned a string, an error is raised, and bc(1) resets (see the
+**RESET** section).
+
+Assigning strings to variables and array elements and passing them to functions
+are **non-portable extensions**.
+
+## 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.
+
+## Stream Statement
+
+The "expressions in a **stream** statement may also be strings.
+
+If a **stream** statement is given a string, it prints the string as though the
+string had appeared as its own statement. In other words, the **stream**
+statement prints strings normally, without a newline.
+
+If a **stream** statement is given a number, a copy of it is truncated and its
+absolute value is calculated. The result is then printed as though **obase** is
+**256** and each digit is interpreted as an 8-bit ASCII character, making it a
+byte stream.
+
+## 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.
+
+**gcd(a, b)**
+
+: Returns the greatest common divisor (factor) of the truncated absolute value
+ of **a** and the truncated absolute value of **b**.
+
+**lcm(a, b)**
+
+: Returns the least common multiple of the truncated absolute value of **a**
+ and the truncated absolute value of **b**.
+
+**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**).
+
+**band(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **and** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **or** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bxor(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of the bitwise **xor** operation between them.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshl(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the result of **a** bit-shifted left by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bshr(a, b)**
+
+: Takes the truncated absolute value of both **a** and **b** and calculates
+ and returns the truncated result of **a** bit-shifted right by **b** places.
+
+ If you want to use signed two's complement arguments, use **s2u(x)** to
+ convert.
+
+**bnotn(x, n)**
+
+: Takes the truncated absolute value of **x** and does a bitwise not as though
+ it has the same number of bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot8(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **8** binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot16(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **16** binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot32(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **32** binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot64(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ **64** binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bnot(x)**
+
+: Does a bitwise not of the truncated absolute value of **x** as though it has
+ the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brevn(x, n)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the same number of 8-bit bytes as the truncated absolute value of **n**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev8(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 8 binary digits (1 unsigned byte).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev16(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 16 binary digits (2 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev32(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 32 binary digits (4 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev64(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has 64 binary digits (8 unsigned bytes).
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brev(x)**
+
+: Runs a bit reversal on the truncated absolute value of **x** as though it
+ has the minimum number of power of two unsigned bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**broln(x, p, n)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol8(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol16(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol32(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol64(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brol(x, p)**
+
+: Does a left bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**brorn(x, p, n)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the same number of unsigned 8-bit bytes as the truncated
+ absolute value of **n**, by the number of places equal to the truncated
+ absolute value of **p** modded by the **2** to the power of the number of
+ binary digits in **n** 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror8(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **8** binary digits (**1** unsigned byte), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror16(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **16** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror32(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **32** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror64(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has **64** binary digits (**2** unsigned bytes), by the number of
+ places equal to the truncated absolute value of **p** modded by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bror(x, p)**
+
+: Does a right bitwise rotatation of the truncated absolute value of **x**, as
+ though it has the minimum number of power of two unsigned 8-bit bytes, by
+ the number of places equal to the truncated absolute value of **p** modded
+ by 2 to the power of the number of binary digits in the minimum number of
+ 8-bit bytes.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmodn(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of the multiplication of the truncated absolute value of **n** and
+ **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod8(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **8**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod16(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **16**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod32(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **32**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bmod64(x, n)**
+
+: Returns the modulus of the truncated absolute value of **x** by **2** to the
+ power of **64**.
+
+ If you want to a use signed two's complement argument, use **s2u(x)** to
+ convert.
+
+**bunrev(t)**
+
+: Assumes **t** is a bitwise-reversed number with an extra set bit one place
+ more significant than the real most significant bit (which was the least
+ significant bit in the original number). This number is reversed and
+ returned without the extra set bit.
+
+ This function is used to implement other bitwise functions; it is not meant
+ to be used by users, but it can be.
+
+**plz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**plznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed with a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**pnlz(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and without a trailing newline.
+
+ Otherwise, **x** is printed normally, without a trailing newline.
+
+**pnlznl(x)**
+
+: If **x** is not equal to **0** and greater that **-1** and less than **1**,
+ it is printed without a leading zero, regardless of the use of the **-z**
+ option (see the **OPTIONS** section) and with a trailing newline.
+
+ Otherwise, **x** is printed normally, with a trailing newline.
+
+**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**.
+
+**s2u(x)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer and returns the
+ non-negative integer that would have the same representation in binary.
+
+**s2un(x,n)**
+
+: Returns **x** if it is non-negative. If it *is* negative, then it calculates
+ what **x** would be as a 2's-complement signed integer with **n** bytes and
+ returns the non-negative integer that would have the same representation in
+ binary. If **x** cannot fit into **n** 2's-complement signed bytes, it is
+ truncated to fit.
+
+**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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**BC_BANNER**
+
+: If this environment variable exists and contains an integer, then a non-zero
+ value activates the copyright banner when bc(1) is in interactive mode,
+ while zero deactivates it.
+
+ If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) does not print
+ the banner when not in interactive mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_SIGINT_RESET**
+
+: If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because bc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when bc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes bc(1) reset
+ on **SIGINT**, rather than exit, and zero makes bc(1) exit. If this
+ environment variable exists and is *not* an integer, then bc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes bc(1) use TTY
+ mode, and zero makes bc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**BC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes bc(1) use a prompt,
+ and zero or a non-integer makes bc(1) not use a prompt. If this environment
+ variable does not exist and **BC_TTY_MODE** does, then the value of the
+ **BC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **BC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving 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 situations.
+
+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. bc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **BC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, bc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **BC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, bc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **BC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then bc(1) will not turn TTY
+mode on.
+
+If the environment variable **BC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **BC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **BC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **BC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **BC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **BC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause bc(1) to do one of two things.
+
+If bc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **BC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, bc(1) will
+exit.
+
+However, if bc(1) is in interactive mode, and the **BC_SIGINT_RESET** or its
+default is an integer and non-zero, then bc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If bc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If bc(1)
+is processing input from a file in interactive 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, and only when bc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause bc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+bc(1) supports interactive command-line editing.
+
+If bc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**BC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+If 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/bcl.3 b/contrib/bc/manuals/bcl.3
new file mode 100644
index 000000000000..9370417dcfef
--- /dev/null
+++ b/contrib/bc/manuals/bcl.3
@@ -0,0 +1,1394 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "BCL" "3" "June 2021" "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]bool bcl_leadingZeroes(\f[R]\f[I]void\f[R]\f[B]);\f[R]
+.PP
+\f[B]void bcl_setLeadingZeroes(bool\f[R]
+\f[I]leadingZeroes\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]BCL_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
+bcl(3) assumes that it is allowed to use the \f[B]bcl\f[R],
+\f[B]Bcl\f[R], \f[B]bc\f[R], and \f[B]Bc\f[R] prefixes for symbol names
+without collision.
+.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.
+.PP
+The default is \f[B]false\f[R].
+.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]bool bcl_leadingZeroes(\f[R]\f[I]void\f[R]\f[B])\f[R]
+Queries and returns the state of whether leading zeroes are added to
+strings returned by \f[B]bcl_string()\f[R] when numbers are greater than
+\f[B]-1\f[R], less than \f[B]1\f[R], and not equal to \f[B]0\f[R].
+If \f[B]true\f[R] is returned, then leading zeroes will be added.
+.RS
+.PP
+The default is \f[B]false\f[R].
+.RE
+.TP
+\f[B]void bcl_setLeadingZeroes(bool\f[R] \f[I]leadingZeroes\f[R]\f[B])\f[R]
+Sets the state of whether leading zeroes are added to strings returned
+by \f[B]bcl_string()\f[R] when numbers are greater than \f[B]-1\f[R],
+less than \f[B]1\f[R], and not equal to \f[B]0\f[R].
+If \f[I]leadingZeroes\f[R] is \f[B]true\f[R], leading zeroes will be
+added to strings returned by \f[B]bcl_string()\f[R].
+.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[\f[R]\f[I]BCL_SEED_SIZE\f[R]\f[B]])\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]BCL_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..fa630fc79f1a
--- /dev/null
+++ b/contrib/bc/manuals/bcl.3.md
@@ -0,0 +1,1202 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# 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_**);**
+
+**bool bcl_leadingZeroes(**_void_**);**
+
+**void bcl_setLeadingZeroes(bool** _leadingZeroes_**);**
+
+**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_**[**_BCL_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.)
+
+bcl(3) assumes that it is allowed to use the **bcl**, **Bcl**, **bc**, and
+**Bc** prefixes for symbol names without collision.
+
+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.
+
+ The default is **false**.
+
+**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.
+
+**bool bcl_leadingZeroes(**_void_**)**
+
+: Queries and returns the state of whether leading zeroes are added to strings
+ returned by **bcl_string()** when numbers are greater than **-1**, less than
+ **1**, and not equal to **0**. If **true** is returned, then leading zeroes
+ will be added.
+
+ The default is **false**.
+
+**void bcl_setLeadingZeroes(bool** _leadingZeroes_**)**
+
+: Sets the state of whether leading zeroes are added to strings returned by
+ **bcl_string()** when numbers are greater than **-1**, less than **1**, and
+ not equal to **0**. If *leadingZeroes* is **true**, leading zeroes will be
+ added to strings returned by **bcl_string()**.
+
+**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[**_BCL_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_**[**_BCL_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/build.md b/contrib/bc/manuals/build.md
new file mode 100644
index 000000000000..13e969e8e673
--- /dev/null
+++ b/contrib/bc/manuals/build.md
@@ -0,0 +1,838 @@
+# 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.
+
+## Windows
+
+For releases, Windows builds of `bc`, `dc`, and `bcl` are available for download
+from <https://git.yzena.com/gavin/bc> and GitHub.
+
+However, if you wish to build it yourself, this `bc` can be built using Visual
+Studio or MSBuild.
+
+Unfortunately, only one build configuration (besides Debug or Release) is
+supported: extra math enabled, history and NLS (locale support) disabled, with
+both calculators built. The default [settings][11] are `BC_BANNER=1`,
+`{BC,DC}_SIGINT_RESET=0`, `{BC,DC}_TTY_MODE=1`, `{BC,DC}_PROMPT=1`.
+
+The library can also be built on Windows.
+
+### Visual Studio
+
+In Visual Studio, open up the solution file (`bc.sln` for `bc`, or `bcl.sln` for
+the library), select the desired configuration, and build.
+
+### MSBuild
+
+To build with MSBuild, first, *be sure that you are using the MSBuild that comes
+with Visual Studio*.
+
+To build `bc`, run the following from the root directory:
+
+```
+msbuild -property:Configuration=<config> bc.sln
+```
+
+where `<config>` is either one of `Debug` or `Release`.
+
+To build the library, run the following from the root directory:
+
+```
+msbuild -property:Configuration=<config> bcl.sln
+```
+
+where `<config>` is either one of `Debug` or `Release`.
+
+## POSIX-Compatible Systems
+
+Building `bc`, `dc`, and `bcl` (the library) is more complex than on Windows
+because many build options are supported.
+
+### Cross Compiling
+
+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`.
+
+### 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`.
+
+#### `INCLUDEDIR`
+
+The directory to install header files in.
+
+Can be overridden by passing the `--includedir` option to `configure.sh`.
+
+Defaults to `$PREFIX/include`.
+
+#### `LIBDIR`
+
+The directory to install libraries in.
+
+Can be overridden by passing the `--libdir` option to `configure.sh`.
+
+Defaults to `$PREFIX/lib`.
+
+#### `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.
+
+### 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 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).
+
+#### History
+
+To disable hisory, 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.
+
+This option affects the [build type][7].
+
+#### 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.
+
+This option affects the [build type][7].
+
+#### 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.
+
+This option affects the [build type][7].
+
+#### 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 -k32
+./configure.sh --karatsuba-len 32
+```
+
+Both commands are equivalent.
+
+Default is `32`.
+
+***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.
+
+#### Settings
+
+This `bc` and `dc` have a few settings to override default behavior.
+
+The defaults for these settings can be set by package maintainers, and the
+settings themselves can be overriden by users.
+
+To set a default to **on**, use the `-s` or `--set-default-on` option to
+`configure.sh`, with the name of the setting, as follows:
+
+```
+./configure.sh -s bc.banner
+./configure.sh --set-default-on=bc.banner
+```
+
+Both commands are equivalent.
+
+To set a default to **off**, use the `-S` or `--set-default-off` option to
+`configure.sh`, with the name of the setting, as follows:
+
+```
+./configure.sh -S bc.banner
+./configure.sh --set-default-off=bc.banner
+```
+
+Both commands are equivalent.
+
+Users can override the default settings set by packagers with environment
+variables. If the environment variable has an integer, then the setting is
+turned **on** for a non-zero integer, and **off** for zero.
+
+The table of the available settings, along with their defaults and the
+environment variables to override them, is below:
+
+```
+| Setting | Description | Default | Env Variable |
+| =============== | ==================== | ============ | ==================== |
+| bc.banner | Whether to display | 0 | BC_BANNER |
+| | the bc version | | |
+| | banner when in | | |
+| | interactive mode. | | |
+| --------------- | -------------------- | ------------ | -------------------- |
+| bc.sigint_reset | Whether SIGINT will | 1 | BC_SIGINT_RESET |
+| | reset bc, instead of | | |
+| | exiting, when in | | |
+| | interactive mode. | | |
+| --------------- | -------------------- | ------------ | -------------------- |
+| dc.sigint_reset | Whether SIGINT will | 1 | DC_SIGINT_RESET |
+| | reset dc, instead of | | |
+| | exiting, when in | | |
+| | interactive mode. | | |
+| --------------- | -------------------- | ------------ | -------------------- |
+| bc.tty_mode | Whether TTY mode for | 1 | BC_TTY_MODE |
+| | bc should be on when | | |
+| | available. | | |
+| --------------- | -------------------- | ------------ | -------------------- |
+| dc.tty_mode | Whether TTY mode for | 0 | BC_TTY_MODE |
+| | dc should be on when | | |
+| | available. | | |
+| --------------- | -------------------- | ------------ | -------------------- |
+| bc.prompt | Whether the prompt | $BC_TTY_MODE | BC_PROMPT |
+| | for bc should be on | | |
+| | in tty mode. | | |
+| --------------- | -------------------- | ------------ | -------------------- |
+| dc.prompt | Whether the prompt | $DC_TTY_MODE | DC_PROMPT |
+| | for dc should be on | | |
+| | in tty mode. | | |
+| --------------- | -------------------- | ------------ | -------------------- |
+```
+
+These settings are not meant to be changed on a whim. They are meant to ensure
+that this bc and dc will conform to the expectations of the user on each
+platform.
+
+#### 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.
+
+##### 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.
+
+##### 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.
+
+### 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
+```
+
+### Build Type
+
+`bc` and `dc` have 8 build types, affected by the [History][8], [NLS (Locale
+Support)][9], and [Extra Math][10] build options.
+
+The build types are as follows:
+
+* `A`: Nothing disabled.
+* `E`: Extra math disabled.
+* `H`: History disabled.
+* `N`: NLS disabled.
+* `EH`: Extra math and History disabled.
+* `EN`: Extra math and NLS disabled.
+* `HN`: History and NLS disabled.
+* `EHN`: Extra math, History, and NLS all disabled.
+
+These build types correspond to the generated manuals in `manuals/bc` and
+`manuals/dc`.
+
+### 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
+[7]: #build-type
+[8]: #history
+[9]: #nls-locale-support
+[10]: #extra-math
+[11]: #settings
diff --git a/contrib/bc/manuals/dc/A.1 b/contrib/bc/manuals/dc/A.1
new file mode 100644
index 000000000000..a7ff2e3a6963
--- /dev/null
+++ b/contrib/bc/manuals/dc/A.1
@@ -0,0 +1,1549 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]\[lq]\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]\[lq]\f[R] commands are
+guaranteed to \f[B]NOT\f[R] be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator.
+However, they \f[I]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+This means that the pseudo-random values from dc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\[lq]\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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]DC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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, and only when dc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If dc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]DC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.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_MESSAGES\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..0007cc76760a
--- /dev/null
+++ b/contrib/bc/manuals/dc/A.1.md
@@ -0,0 +1,1384 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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. This
+means that the pseudo-random values from dc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **DC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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, and only when dc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause dc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing.
+
+If dc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**DC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+**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_MESSAGES**.
+
+# 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..8760477a03ff
--- /dev/null
+++ b/contrib/bc/manuals/dc/E.1
@@ -0,0 +1,1342 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]DC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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, and only when dc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If dc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]DC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.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_MESSAGES\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..6a2c465e5642
--- /dev/null
+++ b/contrib/bc/manuals/dc/E.1.md
@@ -0,0 +1,1217 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **DC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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, and only when dc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause dc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing.
+
+If dc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**DC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+**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_MESSAGES**.
+
+# 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..4506001dfe55
--- /dev/null
+++ b/contrib/bc/manuals/dc/EH.1
@@ -0,0 +1,1316 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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_MESSAGES\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..06ec59d4b3f7
--- /dev/null
+++ b/contrib/bc/manuals/dc/EH.1.md
@@ -0,0 +1,1194 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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_MESSAGES**.
+
+# 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..1124d907bdd9
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHN.1
@@ -0,0 +1,1312 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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..50cb37ef2586
--- /dev/null
+++ b/contrib/bc/manuals/dc/EHN.1.md
@@ -0,0 +1,1189 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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/EN.1 b/contrib/bc/manuals/dc/EN.1
new file mode 100644
index 000000000000..beae0e46a9b6
--- /dev/null
+++ b/contrib/bc/manuals/dc/EN.1
@@ -0,0 +1,1338 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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,
+overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]DC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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, and only when dc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If dc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]DC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.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..db6f27f34576
--- /dev/null
+++ b/contrib/bc/manuals/dc/EN.1.md
@@ -0,0 +1,1212 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **DC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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, and only when dc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause dc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing.
+
+If dc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**DC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+**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/H.1 b/contrib/bc/manuals/dc/H.1
new file mode 100644
index 000000000000..b4ab9f511080
--- /dev/null
+++ b/contrib/bc/manuals/dc/H.1
@@ -0,0 +1,1523 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]\[lq]\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]\[lq]\f[R] commands are
+guaranteed to \f[B]NOT\f[R] be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator.
+However, they \f[I]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+This means that the pseudo-random values from dc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\[lq]\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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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_MESSAGES\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..647d486adc38
--- /dev/null
+++ b/contrib/bc/manuals/dc/H.1.md
@@ -0,0 +1,1361 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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. This
+means that the pseudo-random values from dc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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_MESSAGES**.
+
+# 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..eb35cb23ff7b
--- /dev/null
+++ b/contrib/bc/manuals/dc/HN.1
@@ -0,0 +1,1519 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]\[lq]\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]\[lq]\f[R] commands are
+guaranteed to \f[B]NOT\f[R] be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator.
+However, they \f[I]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+This means that the pseudo-random values from dc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\[lq]\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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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..70c962624833
--- /dev/null
+++ b/contrib/bc/manuals/dc/HN.1.md
@@ -0,0 +1,1356 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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. This
+means that the pseudo-random values from dc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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/N.1 b/contrib/bc/manuals/dc/N.1
new file mode 100644
index 000000000000..c5cc36ac9b10
--- /dev/null
+++ b/contrib/bc/manuals/dc/N.1
@@ -0,0 +1,1545 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" * Redistributions of source code must retain the above copyright notice,
+.\" this list of conditions and the following disclaimer.
+.\"
+.\" * Redistributions in binary form must reproduce the above copyright notice,
+.\" this list of conditions and the following disclaimer in the documentation
+.\" and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual"
+.SH Name
+.PP
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+.SH SYNOPSIS
+.PP
+\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]]
+[\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]]
+[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]]
+[\f[B]-e\f[R] \f[I]expr\f[R]]
+[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R]
+\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...]
+[\f[I]file\f[R]\&...]
+.SH DESCRIPTION
+.PP
+dc(1) is an arbitrary-precision calculator.
+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, then dc(1) reads from
+\f[B]stdin\f[R] (see the \f[B]STDIN\f[R] section).
+Otherwise, those files are processed, and dc(1) will then exit.
+.PP
+If a user wants to set up a standard environment, they can use
+\f[B]DC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+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].
+.SH OPTIONS
+.PP
+The following are the options that dc(1) accepts.
+.TP
+\f[B]-h\f[R], \f[B]--help\f[R]
+Prints a usage message and quits.
+.TP
+\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R]
+Print the version information (copyright header) and exit.
+.TP
+\f[B]-i\f[R], \f[B]--interactive\f[R]
+Forces interactive mode.
+(See the \f[B]INTERACTIVE MODE\f[R] section.)
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-L\f[R], \f[B]--no-line-length\f[R]
+Disables line length checking and prints numbers without backslashes and
+newlines.
+In other words, this option sets \f[B]BC_LINE_LENGTH\f[R] to \f[B]0\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]-P\f[R], \f[B]--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
+These options override the \f[B]DC_PROMPT\f[R] and \f[B]DC_TTY_MODE\f[R]
+environment variables (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-R\f[R], \f[B]--no-read-prompt\f[R]
+Disables the read prompt in TTY mode.
+(The read prompt is only enabled in TTY mode.
+See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that
+do not want a read prompt or are not used to having them in dc(1).
+Most of those users would want to put this option in
+\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+This option is also useful in hash bang lines of dc(1) scripts that
+prompt for user input.
+.RS
+.PP
+This option does not disable the regular prompt because the read prompt
+is only used when the \f[B]?\f[R] command is used.
+.PP
+These options \f[I]do\f[R] override the \f[B]DC_PROMPT\f[R] and
+\f[B]DC_TTY_MODE\f[R] environment variables (see the \f[B]ENVIRONMENT
+VARIABLES\f[R] section), but only for the read prompt.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-x\f[R] \f[B]--extended-register\f[R]
+Enables extended register mode.
+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]-z\f[R], \f[B]--leading-zeroes\f[R]
+Makes bc(1) print all numbers greater than \f[B]-1\f[R] and less than
+\f[B]1\f[R], and not equal to \f[B]0\f[R], with a leading zero.
+.RS
+.PP
+This can be set for individual numbers with the \f[B]plz(x)\f[R],
+plznl(x)**, \f[B]pnlz(x)\f[R], and \f[B]pnlznl(x)\f[R] functions in the
+extended math library (see the \f[B]LIBRARY\f[R] section).
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R]
+Evaluates \f[I]expr\f[R].
+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
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in
+\f[B]DC_ENV_ARGS\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.TP
+\f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R]
+Reads in \f[I]file\f[R] and evaluates it, line by line, as though it
+were read through \f[B]stdin\f[R].
+If expressions are also given (see above), the expressions are evaluated
+in the order given.
+.RS
+.PP
+If this option is given on the command-line (i.e., not in
+\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section),
+then after processing all expressions and files, dc(1) will exit, unless
+\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to
+\f[B]-f\f[R] or \f[B]--file\f[R].
+However, if any other \f[B]-e\f[R], \f[B]--expression\f[R],
+\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after
+\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and
+exit.
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.PP
+All long options are \f[B]non-portable extensions\f[R].
+.SH STDIN
+.PP
+If no files are given on the command-line and no files or expressions
+are given by the \f[B]-f\f[R], \f[B]--file\f[R], \f[B]-e\f[R], or
+\f[B]--expression\f[R] options, then dc(1) read from \f[B]stdin\f[R].
+.PP
+However, there is a caveat to this.
+.PP
+First, \f[B]stdin\f[R] is evaluated a line at a time.
+The only exception to this is if a string has been finished, but not
+ended.
+This means that, except for escaped brackets, all brackets must be
+balanced before dc(1) parses and executes.
+.SH STDOUT
+.PP
+Any non-error output is written to \f[B]stdout\f[R].
+In addition, if history (see the \f[B]HISTORY\f[R] section) and the
+prompt (see the \f[B]TTY MODE\f[R] section) are enabled, both are output
+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]\[lq]\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]\[lq]\f[R] commands are
+guaranteed to \f[B]NOT\f[R] be cryptographically secure.
+This is a consequence of using a seeded pseudo-random number generator.
+However, they \f[I]are\f[R] guaranteed to be reproducible with identical
+\f[B]seed\f[R] values.
+This means that the pseudo-random values from dc(1) should only be used
+where a reproducible stream of pseudo-random numbers is
+\f[I]ESSENTIAL\f[R].
+In any other case, use a non-seeded pseudo-random number generator.
+.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]256\f[R] and each
+digit is interpreted as an 8-bit 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]\[lq]\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]\f[I]characters\f[R]\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]256\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.
+.TP
+\f[B],\f[R]
+Pushes the depth of the execution stack onto the stack.
+The execution stack is the stack of string executions.
+The number that is pushed onto the stack is exactly as many as is needed
+to make dc(1) exit with the \f[B]Q\f[R] command, so the sequence
+\f[B],Q\f[R] will make dc(1) exit.
+.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.
+It will push \f[B]1\f[R] if the argument is \f[B]0\f[R] with no decimal
+places.
+.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 depth of the stack (before execution of this command)
+onto the stack.
+.TP
+\f[B]y\f[R]\f[I]r\f[R]
+Pushes the current stack depth of the register \f[I]r\f[R] onto the main
+stack.
+.RS
+.PP
+Because each register has a depth of \f[B]1\f[R] (with the value
+\f[B]0\f[R] in the top item) when dc(1) starts, dc(1) requires that each
+register\[cq]s stack must always have at least one item; dc(1) will give
+an error and reset otherwise (see the \f[B]RESET\f[R] section).
+This means that this command will never push \f[B]0\f[R].
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.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.
+.TP
+\f[B]Y\f[R]\f[I]r\f[R]
+Pushes the length of the array \f[I]r\f[R] onto the stack.
+.RS
+.PP
+This is a \f[B]non-portable extension\f[R].
+.RE
+.SS Global Settings
+.PP
+These commands retrieve global settings.
+These are the only commands that require multiple specific characters,
+and all of them begin with the letter \f[B]g\f[R].
+Only the characters below are allowed after the character \f[B]g\f[R];
+any other character produces a parse error (see the \f[B]ERRORS\f[R]
+section).
+.TP
+\f[B]gl\f[R]
+Pushes the line length set by \f[B]DC_LINE_LENGTH\f[R] (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) onto the stack.
+.TP
+\f[B]gz\f[R]
+Pushes \f[B]0\f[R] onto the stack if the leading zero setting has not
+been enabled with the \f[B]-z\f[R] or \f[B]--leading-zeroes\f[R] options
+(see the \f[B]OPTIONS\f[R] section), non-zero otherwise.
+.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, and it is a runtime error to attempt to pop that item off
+of the register 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 exceptions are: a newline (\f[B]`\[rs]n'\f[R]) and a left
+bracket (\f[B]`['\f[R]); it is a parse error for a newline or a left
+bracket 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]--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]\[lq]some
+`dc' file.dc\[rq]\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].
+.RS
+.PP
+The special value of \f[B]0\f[R] will disable line length checking and
+print numbers without regard to line length and without backslashes and
+newlines.
+.RE
+.TP
+\f[B]DC_SIGINT_RESET\f[R]
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), then this environment variable has no effect because dc(1)
+exits on \f[B]SIGINT\f[R] when not in interactive mode.
+.RS
+.PP
+However, when dc(1) is in interactive mode, then if this environment
+variable exists and contains an integer, a non-zero value makes dc(1)
+reset on \f[B]SIGINT\f[R], rather than exit, and zero makes dc(1) exit.
+If this environment variable exists and is \f[I]not\f[R] an integer,
+then dc(1) will exit on \f[B]SIGINT\f[R].
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_TTY_MODE\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, then a non-zero value makes dc(1) use
+TTY mode, and zero makes dc(1) not use TTY mode.
+.PP
+This environment variable overrides the default, which can be queried
+with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.TP
+\f[B]DC_PROMPT\f[R]
+If TTY mode is \f[I]not\f[R] available (see the \f[B]TTY MODE\f[R]
+section), then this environment variable has no effect.
+.RS
+.PP
+However, when TTY mode is available, then if this environment variable
+exists and contains an integer, a non-zero value makes dc(1) use a
+prompt, and zero or a non-integer makes dc(1) not use a prompt.
+If this environment variable does not exist and \f[B]DC_TTY_MODE\f[R]
+does, then the value of the \f[B]DC_TTY_MODE\f[R] environment variable
+is used.
+.PP
+This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
+variable override the default, which can be queried with the
+\f[B]-h\f[R] or \f[B]--help\f[R] options.
+.RE
+.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, overflow when calculating the size of a number, 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 any global
+(\f[B]ibase\f[R], \f[B]obase\f[R], or \f[B]scale\f[R]), giving 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 (including attempting to execute
+a number), 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]--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]--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]--interactive\f[R] option can turn it on in other situations.
+.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.
+dc(1) may also reset on \f[B]SIGINT\f[R] instead of exit, depending on
+the contents of, or default for, the \f[B]DC_SIGINT_RESET\f[R]
+environment variable (see the \f[B]ENVIRONMENT VARIABLES\f[R] section).
+.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, then \[lq]TTY mode\[rq] is considered to be
+available, and thus, dc(1) can turn on TTY mode, subject to some
+settings.
+.PP
+If there is the environment variable \f[B]DC_TTY_MODE\f[R] in the
+environment (see the \f[B]ENVIRONMENT VARIABLES\f[R] section), then if
+that environment variable contains a non-zero integer, dc(1) will turn
+on TTY mode when \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R]
+are all connected to a TTY.
+If the \f[B]DC_TTY_MODE\f[R] environment variable exists but is
+\f[I]not\f[R] a non-zero integer, then dc(1) will not turn TTY mode on.
+.PP
+If the environment variable \f[B]DC_TTY_MODE\f[R] does \f[I]not\f[R]
+exist, the default setting is used.
+The default setting can be queried with the \f[B]-h\f[R] or
+\f[B]--help\f[R] options.
+.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.
+.SS Command-Line History
+.PP
+Command-line history is only enabled if TTY mode is, i.e., that
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to
+a TTY and the \f[B]DC_TTY_MODE\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section) and its default do not disable
+TTY mode.
+See the \f[B]COMMAND LINE HISTORY\f[R] section for more information.
+.SS Prompt
+.PP
+If TTY mode is available, then a prompt can be enabled.
+Like TTY mode itself, it can be turned on or off with an environment
+variable: \f[B]DC_PROMPT\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.PP
+If the environment variable \f[B]DC_PROMPT\f[R] exists and is a non-zero
+integer, then the prompt is turned on when \f[B]stdin\f[R],
+\f[B]stdout\f[R], and \f[B]stderr\f[R] are connected to a TTY and the
+\f[B]-P\f[R] and \f[B]--no-prompt\f[R] options were not used.
+The read prompt will be turned on under the same conditions, except that
+the \f[B]-R\f[R] and \f[B]--no-read-prompt\f[R] options must also not be
+used.
+.PP
+However, if \f[B]DC_PROMPT\f[R] does not exist, the prompt can be
+enabled or disabled with the \f[B]DC_TTY_MODE\f[R] environment variable,
+the \f[B]-P\f[R] and \f[B]--no-prompt\f[R] options, and the \f[B]-R\f[R]
+and \f[B]--no-read-prompt\f[R] options.
+See the \f[B]ENVIRONMENT VARIABLES\f[R] and \f[B]OPTIONS\f[R] sections
+for more details.
+.SH SIGNAL HANDLING
+.PP
+Sending a \f[B]SIGINT\f[R] will cause dc(1) to do one of two things.
+.PP
+If dc(1) is not in interactive mode (see the \f[B]INTERACTIVE MODE\f[R]
+section), or the \f[B]DC_SIGINT_RESET\f[R] environment variable (see the
+\f[B]ENVIRONMENT VARIABLES\f[R] section), or its default, is either not
+an integer or it is zero, dc(1) will exit.
+.PP
+However, if dc(1) is in interactive mode, and the
+\f[B]DC_SIGINT_RESET\f[R] or its default is an integer and non-zero,
+then dc(1) will stop executing the current input and reset (see the
+\f[B]RESET\f[R] section) upon receiving a \f[B]SIGINT\f[R].
+.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 interactive mode,
+it will ask for more input.
+If dc(1) is processing input from a file in interactive 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, and only when dc(1)
+is in TTY mode (see the \f[B]TTY MODE\f[R] section), 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.
+.PP
+If dc(1) can be in TTY mode (see the \f[B]TTY MODE\f[R] section),
+history can be enabled.
+This means that command-line history can only be enabled when
+\f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all
+connected to a TTY.
+.PP
+Like TTY mode itself, it can be turned on or off with the environment
+variable \f[B]DC_TTY_MODE\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R]
+section).
+.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..fea23028e483
--- /dev/null
+++ b/contrib/bc/manuals/dc/N.1.md
@@ -0,0 +1,1379 @@
+<!---
+
+SPDX-License-Identifier: BSD-2-Clause
+
+Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+# Name
+
+dc - arbitrary-precision decimal reverse-Polish notation calculator
+
+# SYNOPSIS
+
+**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-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, then dc(1) reads from **stdin** (see
+the **STDIN** section). Otherwise, those files are processed, and dc(1) will
+then exit.
+
+If a user wants to set up a standard environment, they can use **DC_ENV_ARGS**
+(see the **ENVIRONMENT VARIABLES** section). 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**.
+
+# 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**.
+
+**-L**, **-\-no-line-length**
+
+: Disables line length checking and prints numbers without backslashes and
+ newlines. In other words, this option sets **BC_LINE_LENGTH** to **0** (see
+ the **ENVIRONMENT VARIABLES** 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**.
+
+ These options override the **DC_PROMPT** and **DC_TTY_MODE** environment
+ variables (see the **ENVIRONMENT VARIABLES** section).
+
+ This is a **non-portable extension**.
+
+**-R**, **-\-no-read-prompt**
+
+: Disables the read prompt in TTY mode. (The read prompt is only enabled in
+ TTY mode. See the **TTY MODE** section.) This is mostly for those users that
+ do not want a read prompt or are not used to having them in dc(1). Most of
+ those users would want to put this option in **BC_ENV_ARGS** (see the
+ **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang
+ lines of dc(1) scripts that prompt for user input.
+
+ This option does not disable the regular prompt because the read prompt is
+ only used when the **?** command is used.
+
+ These options *do* override the **DC_PROMPT** and **DC_TTY_MODE**
+ environment variables (see the **ENVIRONMENT VARIABLES** section), but only
+ for the read prompt.
+
+ 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**.
+
+**-z**, **-\-leading-zeroes**
+
+: Makes bc(1) print all numbers greater than **-1** and less than **1**, and
+ not equal to **0**, with a leading zero.
+
+ This can be set for individual numbers with the **plz(x)**, plznl(x)**,
+ **pnlz(x)**, and **pnlznl(x)** functions in the extended math library (see
+ the **LIBRARY** section).
+
+ 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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**, whether on the
+ command-line or in **DC_ENV_ARGS**. However, if any other **-e**,
+ **-\-expression**, **-f**, or **-\-file** arguments are given after **-f-**
+ or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+**-f** *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.
+
+ If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**,
+ see the **ENVIRONMENT VARIABLES** section), then after processing all
+ expressions and files, dc(1) will exit, unless **-** (**stdin**) was given
+ as an argument at least once to **-f** or **-\-file**. However, if any other
+ **-e**, **-\-expression**, **-f**, or **-\-file** arguments are given after
+ **-f-** or equivalent is given, dc(1) will give a fatal error and exit.
+
+ This is a **non-portable extension**.
+
+All long options are **non-portable extensions**.
+
+# STDIN
+
+If no files are given on the command-line and no files or expressions are given
+by the **-f**, **-\-file**, **-e**, or **-\-expression** options, then dc(1)
+read from **stdin**.
+
+However, there is a caveat to this.
+
+First, **stdin** is evaluated a line at a time. The only exception to this is if
+a string has been finished, but not ended. This means that, except for escaped
+brackets, all brackets must be balanced before dc(1) parses and executes.
+
+# STDOUT
+
+Any non-error output is written to **stdout**. In addition, if history (see the
+**HISTORY** section) and the prompt (see the **TTY MODE** section) are enabled,
+both are output 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. This
+means that the pseudo-random values from dc(1) should only be used where a
+reproducible stream of pseudo-random numbers is *ESSENTIAL*. In any other case,
+use a non-seeded pseudo-random number generator.
+
+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 **256** and each digit is
+ interpreted as an 8-bit 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 **256** 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.
+
+**,**
+
+: Pushes the depth of the execution stack onto the stack. The execution stack
+ is the stack of string executions. The number that is pushed onto the stack
+ is exactly as many as is needed to make dc(1) exit with the **Q** command,
+ so the sequence **,Q** will make dc(1) exit.
+
+## 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. It will push **1** if the argument is **0** with
+ no decimal places.
+
+ 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 depth of the stack (before execution of this command)
+ onto the stack.
+
+**y**_r_
+
+: Pushes the current stack depth of the register *r* onto the main stack.
+
+ Because each register has a depth of **1** (with the value **0** in the top
+ item) when dc(1) starts, dc(1) requires that each register's stack must
+ always have at least one item; dc(1) will give an error and reset otherwise
+ (see the **RESET** section). This means that this command will never push
+ **0**.
+
+ This is a **non-portable extension**.
+
+## 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.
+
+**Y**_r_
+
+: Pushes the length of the array *r* onto the stack.
+
+ This is a **non-portable extension**.
+
+## Global Settings
+
+These commands retrieve global settings. These are the only commands that
+require multiple specific characters, and all of them begin with the letter
+**g**. Only the characters below are allowed after the character **g**; any
+other character produces a parse error (see the **ERRORS** section).
+
+**gl**
+
+: Pushes the line length set by **DC_LINE_LENGTH** (see the **ENVIRONMENT
+ VARIABLES** section) onto the stack.
+
+**gz**
+
+: Pushes **0** onto the stack if the leading zero setting has not been enabled
+ with the **-z** or **-\-leading-zeroes** options (see the **OPTIONS**
+ section), non-zero otherwise.
+
+# 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, and it is a runtime error to attempt to pop that item
+off of the register 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 exceptions are: a
+newline (**'\\n'**) and a left bracket (**'['**); it is a parse error for a
+newline or a left bracket 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 'dc' file.dc"**, 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**.
+
+ The special value of **0** will disable line length checking and print
+ numbers without regard to line length and without backslashes and newlines.
+
+**DC_SIGINT_RESET**
+
+: If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section),
+ then this environment variable has no effect because dc(1) exits on
+ **SIGINT** when not in interactive mode.
+
+ However, when dc(1) is in interactive mode, then if this environment
+ variable exists and contains an integer, a non-zero value makes dc(1) reset
+ on **SIGINT**, rather than exit, and zero makes dc(1) exit. If this
+ environment variable exists and is *not* an integer, then dc(1) will exit on
+ **SIGINT**.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_TTY_MODE**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, then a non-zero value makes dc(1) use TTY
+ mode, and zero makes dc(1) not use TTY mode.
+
+ This environment variable overrides the default, which can be queried with
+ the **-h** or **-\-help** options.
+
+**DC_PROMPT**
+
+: If TTY mode is *not* available (see the **TTY MODE** section), then this
+ environment variable has no effect.
+
+ However, when TTY mode is available, then if this environment variable
+ exists and contains an integer, a non-zero value makes dc(1) use a prompt,
+ and zero or a non-integer makes dc(1) not use a prompt. If this environment
+ variable does not exist and **DC_TTY_MODE** does, then the value of the
+ **DC_TTY_MODE** environment variable is used.
+
+ This environment variable and the **DC_TTY_MODE** environment variable
+ override the default, which can be queried with the **-h** or **-\-help**
+ options.
+
+# 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, overflow when
+ calculating the size of a number, 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 any global (**ibase**,
+ **obase**, or **scale**), giving a bad expression to a **read()** call,
+ calling **read()** inside of a **read()** call, type errors (including
+ attempting to execute a number), 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 situations.
+
+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. dc(1) may also reset on **SIGINT** instead of exit,
+depending on the contents of, or default for, the **DC_SIGINT_RESET**
+environment variable (see the **ENVIRONMENT VARIABLES** section).
+
+# TTY MODE
+
+If **stdin**, **stdout**, and **stderr** are all connected to a TTY, then "TTY
+mode" is considered to be available, and thus, dc(1) can turn on TTY mode,
+subject to some settings.
+
+If there is the environment variable **DC_TTY_MODE** in the environment (see the
+**ENVIRONMENT VARIABLES** section), then if that environment variable contains a
+non-zero integer, dc(1) will turn on TTY mode when **stdin**, **stdout**, and
+**stderr** are all connected to a TTY. If the **DC_TTY_MODE** environment
+variable exists but is *not* a non-zero integer, then dc(1) will not turn TTY
+mode on.
+
+If the environment variable **DC_TTY_MODE** does *not* exist, the default
+setting is used. The default setting can be queried with the **-h** or
+**-\-help** options.
+
+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.
+
+## Command-Line History
+
+Command-line history is only enabled if TTY mode is, i.e., that **stdin**,
+**stdout**, and **stderr** are connected to a TTY and the **DC_TTY_MODE**
+environment variable (see the **ENVIRONMENT VARIABLES** section) and its default
+do not disable TTY mode. See the **COMMAND LINE HISTORY** section for more
+information.
+
+## Prompt
+
+If TTY mode is available, then a prompt can be enabled. Like TTY mode itself, it
+can be turned on or off with an environment variable: **DC_PROMPT** (see the
+**ENVIRONMENT VARIABLES** section).
+
+If the environment variable **DC_PROMPT** exists and is a non-zero integer, then
+the prompt is turned on when **stdin**, **stdout**, and **stderr** are connected
+to a TTY and the **-P** and **-\-no-prompt** options were not used. The read
+prompt will be turned on under the same conditions, except that the **-R** and
+**-\-no-read-prompt** options must also not be used.
+
+However, if **DC_PROMPT** does not exist, the prompt can be enabled or disabled
+with the **DC_TTY_MODE** environment variable, the **-P** and **-\-no-prompt**
+options, and the **-R** and **-\-no-read-prompt** options. See the **ENVIRONMENT
+VARIABLES** and **OPTIONS** sections for more details.
+
+# SIGNAL HANDLING
+
+Sending a **SIGINT** will cause dc(1) to do one of two things.
+
+If dc(1) is not in interactive mode (see the **INTERACTIVE MODE** section), or
+the **DC_SIGINT_RESET** environment variable (see the **ENVIRONMENT VARIABLES**
+section), or its default, is either not an integer or it is zero, dc(1) will
+exit.
+
+However, if dc(1) is in interactive mode, and the **DC_SIGINT_RESET** or its
+default is an integer and non-zero, then dc(1) will stop executing the current
+input and reset (see the **RESET** section) upon receiving a **SIGINT**.
+
+Note that "current input" can mean one of two things. If dc(1) is processing
+input from **stdin** in interactive mode, it will ask for more input. If dc(1)
+is processing input from a file in interactive 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, and only when dc(1) is in TTY mode (see the **TTY MODE** section), a
+**SIGHUP** will cause dc(1) to clean up and exit.
+
+# COMMAND LINE HISTORY
+
+dc(1) supports interactive command-line editing.
+
+If dc(1) can be in TTY mode (see the **TTY MODE** section), history can be
+enabled. This means that command-line history can only be enabled when
+**stdin**, **stdout**, and **stderr** are all connected to a TTY.
+
+Like TTY mode itself, it can be turned on or off with the environment variable
+**DC_TTY_MODE** (see the **ENVIRONMENT VARIABLES** section).
+
+**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/scripts/exec-install.sh b/contrib/bc/scripts/exec-install.sh
new file mode 100755
index 000000000000..25d56c6fc688
--- /dev/null
+++ b/contrib/bc/scripts/exec-install.sh
@@ -0,0 +1,67 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Print usage and exit with an error.
+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"
+
+# Process command-line arguments.
+test "$#" -ge 2 || usage
+
+installdir="$1"
+shift
+
+exec_suffix="$1"
+shift
+
+bindir="$scriptdir/../bin"
+
+# Install or symlink, depending on the type of file. If it's a file, install it.
+# If it's a symlink, create an equivalent in the install directory.
+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/scripts/functions.sh b/contrib/bc/scripts/functions.sh
new file mode 100755
index 000000000000..65ec0a1167fe
--- /dev/null
+++ b/contrib/bc/scripts/functions.sh
@@ -0,0 +1,328 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# This script is NOT meant to be run! It is meant to be sourced by other
+# scripts.
+
+# Reads and follows a link until it finds a real file. This is here because the
+# readlink utility is not part of the POSIX standard. Sigh...
+# @param f The link to find the original file for.
+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/}"
+}
+
+# Quick function for exiting with an error.
+# @param 1 A message to print.
+# @param 2 The exit code to use.
+err_exit() {
+
+ if [ "$#" -ne 2 ]; then
+ printf 'Invalid number of args to err_exit\n'
+ exit 1
+ fi
+
+ printf '%s\n' "$1"
+ exit "$2"
+}
+
+# Check the return code on a test and exit with a fail if it's non-zero.
+# @param d The calculator under test.
+# @param err The return code.
+# @param name The name of the test.
+checktest_retcode() {
+
+ _checktest_retcode_d="$1"
+ shift
+
+ _checktest_retcode_err="$1"
+ shift
+
+ _checktest_retcode_name="$1"
+ shift
+
+ if [ "$_checktest_retcode_err" -ne 0 ]; then
+ printf 'FAIL!!!\n'
+ err_exit "$_checktest_retcode_d failed test '$_checktest_retcode_name' with error code $_checktest_retcode_err" 1
+ fi
+}
+
+# Check the result of a test. First, it checks the error code using
+# checktest_retcode(). Then it checks the output against the expected output
+# and fails if it doesn't match.
+# @param d The calculator under test.
+# @param err The error code.
+# @param name The name of the test.
+# @param test_path The path to the test.
+# @param results_name The path to the file with the expected result.
+checktest() {
+
+ _checktest_d="$1"
+ shift
+
+ _checktest_err="$1"
+ shift
+
+ _checktest_name="$1"
+ shift
+
+ _checktest_test_path="$1"
+ shift
+
+ _checktest_results_name="$1"
+ shift
+
+ checktest_retcode "$_checktest_d" "$_checktest_err" "$_checktest_name"
+
+ _checktest_diff=$(diff "$_checktest_test_path" "$_checktest_results_name")
+
+ _checktest_err="$?"
+
+ if [ "$_checktest_err" -ne 0 ]; then
+ printf 'FAIL!!!\n'
+ printf '%s\n' "$_checktest_diff"
+ err_exit "$_checktest_d failed test $_checktest_name" 1
+ fi
+}
+
+# Die. With a message.
+# @param d The calculator under test.
+# @param msg The message to print.
+# @param name The name of the test.
+# @param err The return code from the test.
+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"
+}
+
+# Check that a test did not crash and die if it did.
+# @param d The calculator under test.
+# @param error The error code.
+# @param name The name of the test.
+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
+}
+
+# Check that a test had an error or crash.
+# @param d The calculator under test.
+# @param error The error code.
+# @param name The name of the test.
+# @param out The file that the test results were output to.
+# @param exebase The name of the executable.
+checkerrtest()
+{
+ _checkerrtest_d="$1"
+ shift
+
+ _checkerrtest_error="$1"
+ shift
+
+ _checkerrtest_name="$1"
+ shift
+
+ _checkerrtest_out="$1"
+ shift
+
+ _checkerrtest_exebase="$1"
+ shift
+
+ checkcrash "$_checkerrtest_d" "$_checkerrtest_error" "$_checkerrtest_name"
+
+ if [ "$_checkerrtest_error" -eq 0 ]; then
+ die "$_checkerrtest_d" "returned no error" "$_checkerrtest_name" 127
+ fi
+
+ # This is to check for memory errors with Valgrind, which is told to return
+ # 100 on memory errors.
+ if [ "$_checkerrtest_error" -eq 100 ]; then
+
+ _checkerrtest_output=$(cat "$_checkerrtest_out")
+ _checkerrtest_fatal_error="Fatal error"
+
+ if [ "${_checkerrtest_output##*$_checkerrtest_fatal_error*}" ]; then
+ printf "%s\n" "$_checkerrtest_output"
+ die "$_checkerrtest_d" "had memory errors on a non-fatal error" \
+ "$_checkerrtest_name" "$_checkerrtest_error"
+ fi
+ fi
+
+ if [ ! -s "$_checkerrtest_out" ]; then
+ die "$_checkerrtest_d" "produced no error message" "$_checkerrtest_name" "$_checkerrtest_error"
+ fi
+
+ # To display error messages, uncomment this line. This is useful when
+ # debugging.
+ #cat "$_checkerrtest_out"
+}
+
+# Replace a substring in a string with another. This function is the *real*
+# workhorse behind configure.sh's generation of a Makefile.
+#
+# This function uses a sed call that uses exclamation points `!` as delimiters.
+# As a result, needle can never contain an exclamation point. Oh well.
+#
+# @param str The string that will have any of the needle replaced by
+# replacement.
+# @param needle The needle to replace in str with replacement.
+# @param replacement The replacement for needle in str.
+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"
+}
+
+# Generates an NLS path based on the locale and executable name.
+#
+# This is a monstrosity for a reason.
+#
+# @param nlspath The $NLSPATH
+# @param locale The locale.
+# @param execname The name of the executable.
+gen_nlspath() {
+
+ _gen_nlspath_nlspath="$1"
+ shift
+
+ _gen_nlspath_locale="$1"
+ shift
+
+ _gen_nlspath_execname="$1"
+ shift
+
+ # Split the locale into its modifier and other parts.
+ _gen_nlspath_char="@"
+ _gen_nlspath_modifier="${_gen_nlspath_locale#*$_gen_nlspath_char}"
+ _gen_nlspath_tmplocale="${_gen_nlspath_locale%%$_gen_nlspath_char*}"
+
+ # Split the locale into charset and other parts.
+ _gen_nlspath_char="."
+ _gen_nlspath_charset="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}"
+ _gen_nlspath_tmplocale="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}"
+
+ # Check for an empty charset.
+ if [ "$_gen_nlspath_charset" = "$_gen_nlspath_tmplocale" ]; then
+ _gen_nlspath_charset=""
+ fi
+
+ # Split the locale into territory and language.
+ _gen_nlspath_char="_"
+ _gen_nlspath_territory="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}"
+ _gen_nlspath_language="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}"
+
+ # Check for empty territory and language.
+ if [ "$_gen_nlspath_territory" = "$_gen_nlspath_tmplocale" ]; then
+ _gen_nlspath_territory=""
+ fi
+
+ if [ "$_gen_nlspath_language" = "$_gen_nlspath_tmplocale" ]; then
+ _gen_nlspath_language=""
+ fi
+
+ # Prepare to replace the format specifiers. This is done by wrapping the in
+ # pipe characters. It just makes it easier to split them later.
+ _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
+
+ # Replace all the format specifiers.
+ _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")
+
+ # Get rid of pipe characters.
+ _gen_nlspath_nlspath=$(printf '%s' "$_gen_nlspath_nlspath" | tr -d '|')
+
+ # Return the result.
+ printf '%s' "$_gen_nlspath_nlspath"
+}
diff --git a/contrib/bc/scripts/karatsuba.py b/contrib/bc/scripts/karatsuba.py
new file mode 100755
index 000000000000..b8505186b526
--- /dev/null
+++ b/contrib/bc/scripts/karatsuba.py
@@ -0,0 +1,255 @@
+#! /usr/bin/python3 -B
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+import os
+import sys
+import subprocess
+import time
+
+# Print the usage and exit with an error.
+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)
+
+# Run a command. This is basically an alias.
+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()
+
+# We want to be in the root directory.
+os.chdir(testdir + "/..")
+
+print("\nWARNING: This script is for distro and package maintainers.")
+print("It is for finding the optimal Karatsuba number.")
+print("Though it only needs to be run once per release/platform,")
+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")
+
+# This script has to be run by itself.
+if __name__ != "__main__":
+ usage()
+
+# These constants can be changed, but I found they work well enough.
+mx = 520
+mx2 = mx // 2
+mn = 16
+
+num = "9" * mx
+
+args_idx = 4
+
+# Command-line processing.
+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)
+
+# Some basic tests.
+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
+
+# We build the list first because I want to just edit slots.
+for i in range(0, nruns):
+ runs.append(0)
+
+tests = [ "multiply", "modulus", "power", "sqrt" ]
+scripts = [ "multiply" ]
+
+# Test Link-Time Optimization.
+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" ])
+
+# Test parallel build. My machine has 16 cores.
+print("Testing \"make -j16\"")
+
+if p.returncode != 0:
+ print("make returned an error ({}); exiting...".format(p.returncode))
+ sys.exit(p.returncode)
+
+p = run([ "make", "-j16" ])
+
+if p.returncode == 0:
+ makecmd = [ "make", "-j16" ]
+ print("Using \"make -j16\"")
+else:
+ makecmd = [ "make" ]
+ print("Not using \"make -j16\"")
+
+# Set the max if the user did.
+if test_num != 0:
+ mx2 = test_num
+
+# This is the meat here.
+try:
+
+ # For each possible KARATSUBA_LEN...
+ for i in range(mn, mx2 + 1):
+
+ # Configure and compile.
+ 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)
+
+ # Test if desired.
+ 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("")
+
+ # If testing was *not* desired, assume the user wanted to time it.
+ 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:
+ # When timing, we want to quit when the user tells us to. However, we also
+ # want to report the best run, so we make sure to grab the times here before
+ # moving on.
+ nums = nums[0:i]
+ times = times[0:i]
+
+# If running timed tests...
+if test_num == 0:
+
+ # Report the optimal KARATSUBA_LEN
+ 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/scripts/link.sh b/contrib/bc/scripts/link.sh
new file mode 100755
index 000000000000..f1c403d50dda
--- /dev/null
+++ b/contrib/bc/scripts/link.sh
@@ -0,0 +1,63 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+usage() {
+ printf "usage: %s bin_dir link\n" "$0" 1>&2
+ exit 1
+}
+
+# Command-line processing.
+test "$#" -gt 1 || usage
+
+bindir="$1"
+shift
+
+link="$1"
+shift
+
+# For each executable...
+for exe in "$bindir"/*; do
+
+ # If the executable is *not* a link (is our target)...
+ if [ ! -L "$exe" ]; then
+
+ # We do fancy things to preserve the extension of the executable.
+ 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/scripts/locale_install.sh b/contrib/bc/scripts/locale_install.sh
new file mode 100755
index 000000000000..a67e6aa52970
--- /dev/null
+++ b/contrib/bc/scripts/locale_install.sh
@@ -0,0 +1,299 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Just print the usage and exit with an error.
+usage() {
+ if [ $# -eq 1 ]; then
+ printf '%s\n' "$1"
+ fi
+ printf "usage: %s [-l] NLSPATH main_exec [DESTDIR]\n" "$0" 1>&2
+ exit 1
+}
+
+# Run gencat on one file.
+# @param loc The location of the resulting cat file.
+# @param file The file to use as the source for the cat file.
+gencatfile() {
+
+ _gencatfile_loc="$1"
+ shift
+
+ _gencatfile_file="$1"
+ shift
+
+ mkdir -p $(dirname "$_gencatfile_loc")
+ gencat "$_gencatfile_loc" "$_gencatfile_file" > /dev/null 2>&1
+}
+
+# Return an exit code based on whether a locale exists.
+# @param locales The list of locales.
+# @param locale The locale to search for.
+# @param destdir The DESTDIR that locales should be installed to.
+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 $?
+}
+
+# Split a path into its components. They will be separated by newlines, so paths
+# cannot have newlines in them.
+# @param path The path to split.
+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"
+}
+
+# Generate a relative path from one path to another.
+# @param path1 The target path.
+# @param path2 The other path.
+relpath() {
+
+ _relpath_path1="$1"
+ shift
+
+ _relpath_path2="$1"
+ shift
+
+ # Very carefully set IFS in a portable way. No, you cannot do IFS=$'\n'.
+ _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"
+
+ # What this function does is find the parts that are the same and then
+ # calculates the difference based on how many folders up and down you must
+ # go.
+
+ # This first loop basically removes the parts that are the same between
+ # them.
+ 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
+
+ # Go up the appropriate number of times.
+ for _relpath_part in $_relpath_splitpath2; do
+ _relpath_path="../$_relpath_path"
+ done
+
+ _relpath_path="${_relpath_path%../}"
+
+ # Go down the appropriate number of times.
+ 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"
+
+# Set a default.
+all_locales=0
+
+# Process command-line args.
+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
+
+# Uninstall locales first.
+"$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 each relevant .msg file, run gencat.
+for file in $locales_dir/*.msg; do
+
+ locale=$(basename "$file" ".msg")
+
+ # If we are not installing all locales, there's a possibility we need to
+ # skip this one.
+ if [ "$all_locales" -eq 0 ]; then
+
+ # Check if the locale exists and if not skip.
+ localeexists "$locales" "$locale" "$destdir"
+ err="$?"
+
+ if [ "$err" -eq 0 ]; then
+ continue
+ fi
+ fi
+
+ # We skip the symlinks for now.
+ if [ -L "$file" ]; then
+ continue
+ fi
+
+ # Generate the proper location for the cat file.
+ loc=$(gen_nlspath "$destdir/$nlspath" "$locale" "$main_exec")
+
+ gencatfile "$loc" "$file"
+
+done
+
+# Now that we have done the non-symlinks, it's time to do the symlinks. Think
+# that this second loop is unnecessary and that you can combine the two? Well,
+# make sure that when you figure out you are wrong that you add to this comment
+# with your story. Fortunately for me, I learned fast.
+for file in $locales_dir/*.msg; do
+
+ locale=$(basename "$file" ".msg")
+
+ # Do the same skip as the above loop.
+ if [ "$all_locales" -eq 0 ]; then
+
+ localeexists "$locales" "$locale" "$destdir"
+ err="$?"
+
+ if [ "$err" -eq 0 ]; then
+ continue
+ fi
+ fi
+
+ # Generate the proper location for the cat file.
+ loc=$(gen_nlspath "$destdir/$nlspath" "$locale" "$main_exec")
+
+ # Make sure the directory exists.
+ mkdir -p $(dirname "$loc")
+
+ # Make sure to skip non-symlinks; they are already done.
+ if [ -L "$file" ]; then
+
+ # This song and dance is because we want to generate relative symlinks.
+ # They take less space, but also, they are more resilient to being
+ # moved.
+ 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 the target file doesn't exist (because it's for a locale that is
+ # not installed), generate it anyway. It's easier this way.
+ if [ ! -f "$destdir/$linksrc" ]; then
+ gencatfile "$destdir/$linksrc" "$linkdir/$link"
+ fi
+
+ # Finally, symlink to the install of the generated cat file that
+ # corresponds to the correct msg file.
+ ln -fs "$rel" "$loc"
+ fi
+
+done
diff --git a/contrib/bc/scripts/locale_uninstall.sh b/contrib/bc/scripts/locale_uninstall.sh
new file mode 100755
index 000000000000..3e79e083b803
--- /dev/null
+++ b/contrib/bc/scripts/locale_uninstall.sh
@@ -0,0 +1,67 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+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"
+
+# Process command-line arguments.
+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/scripts/safe-install.sh b/contrib/bc/scripts/safe-install.sh
new file mode 100755
index 000000000000..041088386682
--- /dev/null
+++ b/contrib/bc/scripts/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..6601cfb2eeb6
--- /dev/null
+++ b/contrib/bc/src/args.c
@@ -0,0 +1,288 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Code for processing command-line arguments.
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif // _WIN32
+
+#include <vector.h>
+#include <read.h>
+#include <args.h>
+#include <opt.h>
+
+/**
+ * Adds @a str to the list of expressions to execute later.
+ * @param str The string to add to the list of expressions.
+ */
+static void bc_args_exprs(const char *str) {
+ BC_SIG_ASSERT_LOCKED;
+ if (vm.exprs.v == NULL) bc_vec_init(&vm.exprs, sizeof(uchar), BC_DTOR_NONE);
+ bc_vec_concat(&vm.exprs, str);
+ bc_vec_concat(&vm.exprs, "\n");
+}
+
+/**
+ * Adds the contents of @a file to the list of expressions to execute later.
+ * @param file The name of the file whose contents should be added to the list
+ * of expressions to execute.
+ */
+static void bc_args_file(const char *file) {
+
+ char *buf;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ vm.file = file;
+
+ buf = bc_read_file(file);
+
+ assert(buf != NULL);
+
+ bc_args_exprs(buf);
+ free(buf);
+}
+
+#if BC_ENABLED
+
+/**
+ * Redefines a keyword, if it exists and is not a POSIX keyword. Otherwise, it
+ * throws a fatal error.
+ * @param keyword The keyword to redefine.
+ */
+static void bc_args_redefine(const char *keyword) {
+
+ size_t i;
+
+ for (i = 0; i < bc_lex_kws_len; ++i) {
+
+ const BcLexKeyword *kw = bc_lex_kws + i;
+
+ if (!strcmp(keyword, kw->name)) {
+
+ if (BC_LEX_KW_POSIX(kw)) break;
+
+ vm.redefined_kws[i] = true;
+
+ return;
+ }
+ }
+
+ bc_error(BC_ERR_FATAL_ARG, 0, keyword);
+}
+
+#endif // BC_ENABLED
+
+void bc_args(int argc, char *argv[], bool exit_exprs) {
+
+ int c;
+ size_t i;
+ bool do_exit = false, version = false;
+ BcOpt opts;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ bc_opt_init(&opts, argv);
+
+ // This loop should look familiar to anyone who has used getopt() or
+ // getopt_long() in C.
+ while ((c = bc_opt_parse(&opts, bc_args_lopt)) != -1) {
+
+ switch (c) {
+
+ case 'e':
+ {
+ // Barf if not allowed.
+ if (vm.no_exprs)
+ bc_verr(BC_ERR_FATAL_OPTION, "-e (--expression)");
+
+ // Add the expressions and set exit.
+ bc_args_exprs(opts.optarg);
+ vm.exit_exprs = (exit_exprs || vm.exit_exprs);
+
+ break;
+ }
+
+ case 'f':
+ {
+ // Figure out if exiting on expressions is disabled.
+ if (!strcmp(opts.optarg, "-")) vm.no_exprs = true;
+ else {
+
+ // Barf if not allowed.
+ if (vm.no_exprs)
+ bc_verr(BC_ERR_FATAL_OPTION, "-f (--file)");
+
+ // Add the expressions and set exit.
+ bc_args_file(opts.optarg);
+ vm.exit_exprs = (exit_exprs || vm.exit_exprs);
+ }
+
+ break;
+ }
+
+ case 'h':
+ {
+ bc_vm_info(vm.help);
+ do_exit = true;
+ break;
+ }
+
+ case 'i':
+ {
+ vm.flags |= BC_FLAG_I;
+ break;
+ }
+
+ case 'z':
+ {
+ vm.flags |= BC_FLAG_Z;
+ break;
+ }
+
+ case 'L':
+ {
+ vm.line_len = 0;
+ break;
+ }
+
+ case 'P':
+ {
+ vm.flags &= ~(BC_FLAG_P);
+ break;
+ }
+
+ case 'R':
+ {
+ vm.flags &= ~(BC_FLAG_R);
+ 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);
+ vm.flags &= ~(BC_FLAG_Q);
+ break;
+ }
+
+ case 'r':
+ {
+ bc_args_redefine(opts.optarg);
+ 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_error() should
+ // longjmp() out.
+ case '?':
+ case ':':
+ default:
+ {
+ BC_UNREACHABLE
+ abort();
+ }
+#endif // NDEBUG
+ }
+ }
+
+ if (version) bc_vm_info(NULL);
+ if (do_exit) {
+ vm.status = (sig_atomic_t) BC_STATUS_QUIT;
+ BC_JMP;
+ }
+
+ // We do not print the banner if expressions are used or dc is used.
+ if (!BC_IS_BC || vm.exprs.len > 1) vm.flags &= ~(BC_FLAG_Q);
+
+ // We need to make sure the files list is initialized. We don't want to
+ // initialize it if there are no files because it's just a waste of memory.
+ if (opts.optind < (size_t) argc && vm.files.v == NULL)
+ bc_vec_init(&vm.files, sizeof(char*), BC_DTOR_NONE);
+
+ // Add all the files to the vector.
+ 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..4f35cc42b916
--- /dev/null
+++ b/contrib/bc/src/bc.c
@@ -0,0 +1,63 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The main procedure of bc.
+ *
+ */
+
+#if BC_ENABLED
+
+#include <string.h>
+
+#include <bc.h>
+#include <vm.h>
+
+/**
+ * The main function for bc.
+ * @param argc The number of arguments.
+ * @param argv The arguments.
+ */
+void bc_main(int argc, char *argv[]) {
+
+ // All of these just set bc-specific items in BcVm.
+
+ 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);
+}
+#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..cdbdf24b17ac
--- /dev/null
+++ b/contrib/bc/src/bc_lex.c
@@ -0,0 +1,479 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The lexer for bc.
+ *
+ */
+
+#if BC_ENABLED
+
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <bc.h>
+#include <vm.h>
+
+/**
+ * Lexes an identifier, which may be a keyword.
+ * @param l The lexer.
+ */
+static void bc_lex_identifier(BcLex *l) {
+
+ // We already passed the first character, so we need to be sure to include
+ // it.
+ const char *buf = l->buf + l->i - 1;
+ size_t i;
+
+ // This loop is simply checking for keywords.
+ 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] != '_') {
+
+ // If the keyword has been redefined, and redefinition is allowed
+ // (it is not allowed for builtin libraries), break out of the loop
+ // and use it as a name. This depends on the argument parser to
+ // ensure that only non-POSIX keywords get redefined.
+ if (!vm.no_redefine && vm.redefined_kws[i]) break;
+
+ l->t = BC_LEX_KW_AUTO + (BcLexType) i;
+
+ // Warn or error, as appropriate for the mode, if the keyword is not
+ // in the POSIX standard.
+ 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;
+
+ // Already have the token; bail.
+ return;
+ }
+ }
+
+ // If not a keyword, parse the name.
+ bc_lex_name(l);
+
+ // POSIX doesn't allow identifiers that are more than one character, so we
+ // might have to warn or error here too.
+ if (BC_ERR(l->str.len - 1 > 1))
+ bc_lex_verr(l, BC_ERR_POSIX_NAME_LEN, l->str.v);
+}
+
+/**
+ * Parses a bc string. This is separate from dc strings because dc strings need
+ * to be balanced.
+ * @param l The lexer.
+ */
+static void bc_lex_string(BcLex *l) {
+
+ // We need to keep track of newlines to increment them properly.
+ size_t len, nlines, i;
+ const char *buf;
+ char c;
+ bool got_more;
+
+ l->t = BC_LEX_STR;
+
+ do {
+
+ nlines = 0;
+ buf = l->buf;
+ got_more = false;
+
+ assert(!vm.is_stdin || buf == vm.buffer.v);
+
+ // Fortunately for us, bc doesn't escape quotes. Instead, the equivalent
+ // is '\q', which makes this loop simpler.
+ for (i = l->i; (c = buf[i]) && c != '"'; ++i) nlines += (c == '\n');
+
+ if (BC_ERR(c == '\0') && !vm.eof && l->is_stdin)
+ got_more = bc_lex_readLine(l);
+
+ } while (got_more && c != '"');
+
+ // If the string did not end properly, barf.
+ if (c != '"') {
+ l->i = i;
+ bc_lex_err(l, BC_ERR_PARSE_STRING);
+ }
+
+ // Set the temp string to the parsed string.
+ len = i - l->i;
+ bc_vec_string(&l->str, len, l->buf + l->i);
+
+ l->i = i + 1;
+ l->line += nlines;
+}
+
+/**
+ * This function takes a lexed operator and checks to see if it's the assignment
+ * version, setting the token appropriately.
+ * @param l The lexer.
+ * @param with The token to assign if it is an assignment operator.
+ * @param without The token to assign if it is not an assignment operator.
+ */
+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) {
+
+ // We increment here. This means that all lexing needs to take that into
+ // account, such as when parsing an identifier. If we don't, the first
+ // character of every identifier would be missing.
+ 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 '!':
+ {
+ // Even though it's not an assignment, we can use this.
+ bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT);
+
+ // POSIX doesn't allow boolean 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 '#':
+ {
+ // POSIX does not allow line comments.
+ 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];
+
+ // Either we have boolean and or an error. And boolean and is not
+ // allowed by POSIX.
+ 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];
+
+ // Have to check for increment first.
+ 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];
+
+ // Have to check for decrement first.
+ 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 it's alone, it's an alias for last.
+ 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];
+
+ // Check for shift.
+ 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];
+
+ // Check for shift.
+ 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 '\\':
+ {
+ // In bc, a backslash+newline is whitespace.
+ 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];
+
+ // Once again, boolean or is not allowed by POSIX.
+ 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..c64121ec5da8
--- /dev/null
+++ b/contrib/bc/src/bc_parse.c
@@ -0,0 +1,2278 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+// Before you embark on trying to understand this code, have you read the
+// Development manual (manuals/development.md) and the comment in include/bc.h
+// yet? No? Do that first. I'm serious.
+//
+// The reason is because this file holds the most sensitive and finicky code in
+// the entire codebase. Even getting history to work on Windows was nothing
+// compared to this. This is where dreams go to die, where dragons live, and
+// from which Ken Thompson himself would flee.
+
+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 void bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next);
+
+/**
+ * Returns true if an instruction could only have come from a "leaf" expression.
+ * For more on what leaf expressions are, read the comment for BC_PARSE_LEAF().
+ * @param t The instruction to test.
+ */
+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;
+}
+
+/**
+ * Returns true if the *previous* token was a delimiter. A delimiter is anything
+ * that can legally end a statement. In bc's case, it could be a newline, a
+ * semicolon, and a brace in certain cases.
+ * @param p The parser.
+ */
+static bool bc_parse_isDelimiter(const BcParse *p) {
+
+ BcLexType t = p->l.t;
+ bool good;
+
+ // If it's an obvious delimiter, say so.
+ if (BC_PARSE_DELIMITER(t)) return true;
+
+ good = false;
+
+ // If the current token is a keyword, then...beware. That means that we need
+ // to check for a "dangling" else, where there was no brace-delimited block
+ // on the previous if.
+ if (t == BC_LEX_KW_ELSE) {
+
+ size_t i;
+ uint16_t *fptr = NULL, flags = BC_PARSE_FLAG_ELSE;
+
+ // As long as going up the stack is valid for a dangling else, keep on.
+ for (i = 0; i < p->flags.len && BC_PARSE_BLOCK_STMT(flags); ++i) {
+
+ fptr = bc_vec_item_rev(&p->flags, i);
+ flags = *fptr;
+
+ // If we need a brace and don't have one, then we don't have a
+ // delimiter.
+ if ((flags & BC_PARSE_FLAG_BRACE) && p->l.last != BC_LEX_RBRACE)
+ return false;
+ }
+
+ // Oh, and we had also better have an if statement somewhere.
+ good = ((flags & BC_PARSE_FLAG_IF) != 0);
+ }
+ else if (t == BC_LEX_RBRACE) {
+
+ size_t i;
+
+ // Since we have a brace, we need to just check if a brace was needed.
+ 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;
+}
+
+/**
+ * Sets a previously defined exit label. What are labels? See the bc Parsing
+ * section of the Development manual (manuals/development.md).
+ * @param p The parser.
+ */
+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));
+
+ // Set the preallocated label to the correct index.
+ label = bc_vec_item(&func->labels, ip->idx);
+ *label = func->code.len;
+
+ // Now, we don't need the exit label; it is done.
+ bc_vec_pop(&p->exits);
+}
+
+/**
+ * Creates a label and sets it to idx. If this is an exit label, then idx is
+ * actually invalid, but it doesn't matter because it will be fixed by
+ * bc_parse_setLabel() later.
+ * @param p The parser.
+ * @param idx The index of the label.
+ */
+static void bc_parse_createLabel(BcParse *p, size_t idx) {
+ bc_vec_push(&p->func->labels, &idx);
+}
+
+/**
+ * Creates a conditional label. Unlike an exit label, this label is set at
+ * creation time because it comes *before* the code that will target it.
+ * @param p The parser.
+ * @param idx The index of the label.
+ */
+static void bc_parse_createCondLabel(BcParse *p, size_t idx) {
+ bc_parse_createLabel(p, p->func->code.len);
+ bc_vec_push(&p->conds, &idx);
+}
+
+/*
+ * Creates an exit label to be filled in later by bc_parse_setLabel(). Also, why
+ * create a label to be filled in later? Because exit labels are meant to be
+ * targeted by code that comes *before* the label. Since we have to parse that
+ * code first, and don't know how long it will be, we need to just make sure to
+ * reserve a slot to be filled in later when we know.
+ *
+ * By the way, this uses BcInstPtr because it was convenient. The field idx
+ * holds the index, and the field func holds the loop boolean.
+ *
+ * @param p The parser.
+ * @param idx The index of the label's position.
+ * @param loop True if the exit label is for a loop or not.
+ */
+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);
+}
+
+/**
+ * Pops the correct operators off of the operator stack based on the current
+ * operator. This is because of the Shunting-Yard algorithm. Lower prec means
+ * higher precedence.
+ * @param p The parser.
+ * @param type The operator.
+ * @param start The previous start of the operator stack. For more
+ * information, see the bc Parsing section of the Development
+ * manual (manuals/development.md).
+ * @param nexprs A pointer to the current number of expressions that have not
+ * been consumed yet. This is an IN and OUT parameter.
+ */
+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 we haven't hit the stop point yet.
+ while (p->ops.len > start) {
+
+ // Get the top operator.
+ t = BC_PARSE_TOP_OP(p);
+
+ // If it's a right paren, we have reached the end of whatever expression
+ // this is no matter what.
+ if (t == BC_LEX_LPAREN) break;
+
+ // Break for precedence. Precedence operates differently on left and
+ // right associativity, by the way. A left associative operator that
+ // matches the current precedence should take priority, but a right
+ // associative operator should not.
+ l = BC_PARSE_OP_PREC(t);
+ if (l >= r && (l != r || !left)) break;
+
+ // Do the housekeeping. In particular, make sure to note that one
+ // expression was consumed. (Two were, but another was added.)
+ 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);
+}
+
+/**
+ * Parses a right paren. In the Shunting-Yard algorithm, it needs to be put on
+ * the operator stack. But before that, it needs to consume whatever operators
+ * there are until it hits a left paren.
+ * @param p The parser.
+ * @param nexprs A pointer to the current number of expressions that have not
+ * been consumed yet. This is an IN and OUT parameter.
+ */
+static void bc_parse_rightParen(BcParse *p, size_t *nexprs) {
+
+ BcLexType top;
+
+ // Consume operators until a left paren.
+ while ((top = BC_PARSE_TOP_OP(p)) != BC_LEX_LPAREN) {
+ bc_parse_push(p, BC_PARSE_TOKEN_INST(top));
+ bc_vec_pop(&p->ops);
+ *nexprs -= !BC_PARSE_OP_PREFIX(top);
+ }
+
+ // We need to pop the left paren as well.
+ bc_vec_pop(&p->ops);
+
+ // Oh, and we also want the next token.
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parses function arguments.
+ * @param p The parser.
+ * @param flags Flags restricting what kind of expressions the arguments can
+ * be.
+ */
+static void bc_parse_args(BcParse *p, uint8_t flags) {
+
+ bool comma = false;
+ size_t nargs;
+
+ bc_lex_next(&p->l);
+
+ // Print and comparison operators not allowed. Well, comparison operators
+ // only for POSIX. But we do allow arrays, and we *must* get a value.
+ flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
+ flags |= (BC_PARSE_ARRAY | BC_PARSE_NEEDVAL);
+
+ // Count the arguments and parse them.
+ for (nargs = 0; p->l.t != BC_LEX_RPAREN; ++nargs) {
+
+ bc_parse_expr_status(p, flags, bc_parse_next_arg);
+
+ comma = (p->l.t == BC_LEX_COMMA);
+ if (comma) bc_lex_next(&p->l);
+ }
+
+ // An ending comma is FAIL.
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Now do the call with the number of arguments.
+ bc_parse_push(p, BC_INST_CALL);
+ bc_parse_pushIndex(p, nargs);
+}
+
+/**
+ * Parses a function call.
+ * @param p The parser.
+ * @param flags Flags restricting what kind of expressions the arguments can
+ * be.
+ */
+static void bc_parse_call(BcParse *p, const char *name, uint8_t flags) {
+
+ size_t idx;
+
+ bc_parse_args(p, flags);
+
+ // We just assert this because bc_parse_args() 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);
+
+ // The function does not exist yet. Create a space for it. If the user does
+ // not define it, it's a *runtime* error, not a parse error.
+ if (idx == BC_VEC_INVALID_IDX) {
+
+ BC_SIG_LOCK;
+
+ idx = bc_program_insertFunc(p->prog, name);
+
+ BC_SIG_UNLOCK;
+
+ assert(idx != BC_VEC_INVALID_IDX);
+
+ // Make sure that this pointer was not invalidated.
+ p->func = bc_vec_item(&p->prog->fns, p->fidx);
+ }
+ // The function exists, so set the right function index.
+ else idx = ((BcId*) bc_vec_item(&p->prog->fn_map, idx))->idx;
+
+ bc_parse_pushIndex(p, idx);
+
+ // Make sure to get the next token.
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parses a name/identifier-based expression. It could be a variable, an array
+ * element, an array itself (for function arguments), a function call, etc.
+ *
+ */
+static void bc_parse_name(BcParse *p, BcInst *type,
+ bool *can_assign, uint8_t flags)
+{
+ char *name;
+
+ BC_SIG_LOCK;
+
+ // We want a copy of the name since the lexer might overwrite its copy.
+ name = bc_vm_strdup(p->l.str.v);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ // We need the next token to see if it's just a variable or something more.
+ bc_lex_next(&p->l);
+
+ // Array element or array.
+ if (p->l.t == BC_LEX_LBRACKET) {
+
+ bc_lex_next(&p->l);
+
+ // Array only. This has to be a function parameter.
+ if (p->l.t == BC_LEX_RBRACKET) {
+
+ // Error if arrays are not allowed.
+ if (BC_ERR(!(flags & BC_PARSE_ARRAY)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ *type = BC_INST_ARRAY;
+ *can_assign = false;
+ }
+ else {
+
+ // If we are here, we have an array element. We need to set the
+ // expression parsing flags.
+ uint8_t flags2 = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) |
+ BC_PARSE_NEEDVAL;
+
+ bc_parse_expr_status(p, flags2, bc_parse_next_elem);
+
+ // The next token *must* be a right bracket.
+ 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;
+ }
+
+ // Make sure to get the next token.
+ bc_lex_next(&p->l);
+
+ // Push the instruction and the name of the identifier.
+ bc_parse_push(p, *type);
+ bc_parse_pushName(p, name, false);
+ }
+ else if (p->l.t == BC_LEX_LPAREN) {
+
+ // We are parsing a function call; error if not allowed.
+ 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 {
+ // Just a variable.
+ *type = BC_INST_VAR;
+ *can_assign = true;
+ bc_parse_push(p, BC_INST_VAR);
+ bc_parse_pushName(p, name, true);
+ }
+
+err:
+ // Need to make sure to unallocate the name.
+ BC_SIG_MAYLOCK;
+ free(name);
+ BC_LONGJMP_CONT;
+}
+
+/**
+ * Parses a builtin function that takes no arguments. This includes read(),
+ * rand(), maxibase(), maxobase(), maxscale(), and maxrand().
+ * @param p The parser.
+ * @param inst The instruction corresponding to the builtin.
+ */
+static void bc_parse_noArgBuiltin(BcParse *p, BcInst inst) {
+
+ // Must have a left paren.
+ bc_lex_next(&p->l);
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Must have a right paren.
+ 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);
+}
+
+/**
+ * Parses a builtin function that takes 1 argument. This includes length(),
+ * sqrt(), abs(), scale(), and irand().
+ * @param p The parser.
+ * @param type The lex token.
+ * @param flags The expression parsing flags for parsing the argument.
+ * @param prev An out parameter; the previous instruction pointer.
+ */
+static void bc_parse_builtin(BcParse *p, BcLexType type,
+ uint8_t flags, BcInst *prev)
+{
+ // Must have a left paren.
+ 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);
+
+ // Change the flags as needed for parsing the argument.
+ flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
+ flags |= BC_PARSE_NEEDVAL;
+
+ // Since length can take arrays, we need to specially add that flag.
+ if (type == BC_LEX_KW_LENGTH) flags |= BC_PARSE_ARRAY;
+
+ bc_parse_expr_status(p, flags, bc_parse_next_rel);
+
+ // Must have a right paren.
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Adjust previous based on the token and push it.
+ *prev = type - BC_LEX_KW_LENGTH + BC_INST_LENGTH;
+ bc_parse_push(p, *prev);
+
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parses a builtin function that takes 3 arguments. This includes modexp() and
+ * divmod().
+ */
+static void bc_parse_builtin3(BcParse *p, BcLexType type,
+ uint8_t flags, BcInst *prev)
+{
+ assert(type == BC_LEX_KW_MODEXP || type == BC_LEX_KW_DIVMOD);
+
+ // Must have a left paren.
+ 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);
+
+ // Change the flags as needed for parsing the argument.
+ flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
+ flags |= BC_PARSE_NEEDVAL;
+
+ bc_parse_expr_status(p, flags, bc_parse_next_builtin);
+
+ // Must have a comma.
+ if (BC_ERR(p->l.t != BC_LEX_COMMA))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+
+ bc_parse_expr_status(p, flags, bc_parse_next_builtin);
+
+ // Must have a comma.
+ if (BC_ERR(p->l.t != BC_LEX_COMMA))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+
+ // If it is a divmod, parse an array name. Otherwise, just parse another
+ // expression.
+ if (type == BC_LEX_KW_DIVMOD) {
+
+ // Must have a name.
+ if (BC_ERR(p->l.t != BC_LEX_NAME)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // This is safe because the next token should not overwrite the name.
+ bc_lex_next(&p->l);
+
+ // Must have a left bracket.
+ if (BC_ERR(p->l.t != BC_LEX_LBRACKET))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // This is safe because the next token should not overwrite the name.
+ bc_lex_next(&p->l);
+
+ // Must have a right bracket.
+ if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // This is safe because the next token should not overwrite the name.
+ bc_lex_next(&p->l);
+ }
+ else bc_parse_expr_status(p, flags, bc_parse_next_rel);
+
+ // Must have a right paren.
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Adjust previous based on the token and push it.
+ *prev = type - BC_LEX_KW_MODEXP + BC_INST_MODEXP;
+ bc_parse_push(p, *prev);
+
+ // If we have divmod, we need to assign the modulus to the array element, so
+ // we need to push the instructions for doing so.
+ if (type == BC_LEX_KW_DIVMOD) {
+
+ // The zeroth element.
+ bc_parse_push(p, BC_INST_ZERO);
+ bc_parse_push(p, BC_INST_ARRAY_ELEM);
+
+ // Push the array.
+ bc_parse_pushName(p, p->l.str.v, false);
+
+ // Swap them and assign. After this, the top item on the stack should
+ // be the quotient.
+ bc_parse_push(p, BC_INST_SWAP);
+ bc_parse_push(p, BC_INST_ASSIGN_NO_VAL);
+ }
+
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parses the scale keyword. This is special because scale can be a value or a
+ * builtin function.
+ * @param p The parser.
+ * @param type An out parameter; the instruction for the parse.
+ * @param can_assign An out parameter; whether the expression can be assigned
+ * to.
+ * @param flags The expression parsing flags for parsing a scale() arg.
+ */
+static void bc_parse_scale(BcParse *p, BcInst *type,
+ bool *can_assign, uint8_t flags)
+{
+ bc_lex_next(&p->l);
+
+ // Without the left paren, it's just the keyword.
+ if (p->l.t != BC_LEX_LPAREN) {
+
+ // Set, push, and return.
+ *type = BC_INST_SCALE;
+ *can_assign = true;
+ bc_parse_push(p, BC_INST_SCALE);
+ return;
+ }
+
+ // Handle the scale function.
+ *type = BC_INST_SCALE_FUNC;
+ *can_assign = false;
+
+ // Once again, adjust the flags.
+ 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);
+
+ // Must have a right paren.
+ 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);
+}
+
+/**
+ * Parses and increment or decrement operator. This is a bit complex.
+ * @param p The parser.
+ * @param prev An out parameter; the previous instruction pointer.
+ * @param can_assign An out parameter; whether the expression can be assigned
+ * to.
+ * @param nexs An in/out parameter; the number of expressions in the
+ * parse tree that are not used.
+ * @param flags The expression parsing flags for parsing a scale() arg.
+ */
+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 we can't assign to the previous token, then we have an error.
+ 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);
+ }
+
+ // Is the previous instruction for a variable?
+ if (BC_PARSE_INST_VAR(etype)) {
+
+ // If so, this is a postfix operator.
+ if (!*can_assign) bc_parse_err(p, BC_ERR_PARSE_ASSIGN);
+
+ // Only postfix uses BC_INST_INC and BC_INST_DEC.
+ *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 {
+
+ // This is a prefix operator. In that case, we just convert it to
+ // an assignment instruction.
+ *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;
+
+ // Is the next token a normal identifier?
+ if (type == BC_LEX_NAME) {
+
+ // Parse the name.
+ uint8_t flags2 = flags & ~BC_PARSE_ARRAY;
+ bc_parse_name(p, prev, can_assign, flags2 | BC_PARSE_NOCALL);
+ }
+ // Is the next token a global?
+ 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);
+ }
+ // Is the next token specifically scale, which needs special treatment?
+ else if (BC_NO_ERR(type == BC_LEX_KW_SCALE)) {
+
+ bc_lex_next(&p->l);
+
+ // Check that scale() was not used.
+ 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);
+ }
+ // Now we know we have an error.
+ else bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ *can_assign = false;
+
+ bc_parse_push(p, BC_INST_ONE);
+ bc_parse_push(p, inst);
+ }
+}
+
+/**
+ * Parses the minus operator. This needs special treatment because it is either
+ * subtract or negation.
+ * @param p The parser.
+ * @param prev An in/out parameter; the previous instruction.
+ * @param ops_bgn The size of the operator stack.
+ * @param rparen True if the last token was a right paren.
+ * @param binlast True if the last token was a binary operator.
+ * @param nexprs An in/out parameter; the number of unused expressions.
+ */
+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);
+
+ // Figure out if it's a minus or a negation.
+ 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);
+}
+
+/**
+ * Parses a string.
+ * @param p The parser.
+ * @param inst The instruction corresponding to how the string was found and
+ * how it should be printed.
+ */
+static void bc_parse_str(BcParse *p, BcInst inst) {
+ bc_parse_addString(p);
+ bc_parse_push(p, inst);
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parses a print statement.
+ * @param p The parser.
+ */
+static void bc_parse_print(BcParse *p, BcLexType type) {
+
+ BcLexType t;
+ bool comma = false;
+ BcInst inst = type == BC_LEX_KW_STREAM ?
+ BC_INST_PRINT_STREAM : BC_INST_PRINT_POP;
+
+ bc_lex_next(&p->l);
+
+ t = p->l.t;
+
+ // A print or stream statement has to have *something*.
+ if (bc_parse_isDelimiter(p)) bc_parse_err(p, BC_ERR_PARSE_PRINT);
+
+ do {
+
+ // If the token is a string, then print it with escapes.
+ // BC_INST_PRINT_POP plays that role for bc.
+ if (t == BC_LEX_STR) bc_parse_str(p, inst);
+ else {
+ // We have an actual number; parse and add a print instruction.
+ bc_parse_expr_status(p, BC_PARSE_NEEDVAL, bc_parse_next_print);
+ bc_parse_push(p, inst);
+ }
+
+ // Is the next token a comma?
+ comma = (p->l.t == BC_LEX_COMMA);
+
+ // Get the next token if we have a comma.
+ if (comma) bc_lex_next(&p->l);
+ else {
+
+ // If we don't have a comma, the statement needs to end.
+ if (!bc_parse_isDelimiter(p))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ else break;
+ }
+
+ t = p->l.t;
+
+ } while (true);
+
+ // If we have a comma but no token, that's bad.
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+}
+
+/**
+ * Parses a return statement.
+ * @param p The parser.
+ */
+static void bc_parse_return(BcParse *p) {
+
+ BcLexType t;
+ bool paren;
+ uchar inst = BC_INST_RET0;
+
+ // If we are not in a function, that's an error.
+ if (BC_ERR(!BC_PARSE_FUNC(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // If we are in a void function, make sure to return void.
+ if (p->func->voidfn) inst = BC_INST_RET_VOID;
+
+ bc_lex_next(&p->l);
+
+ t = p->l.t;
+ paren = (t == BC_LEX_LPAREN);
+
+ // An empty return statement just needs to push the selected instruction.
+ if (bc_parse_isDelimiter(p)) bc_parse_push(p, inst);
+ else {
+
+ BcParseStatus s;
+
+ // Need to parse the expression whose value will be returned.
+ s = bc_parse_expr_err(p, BC_PARSE_NEEDVAL, bc_parse_next_expr);
+
+ // If the expression was empty, just push the selected instruction.
+ if (s == BC_PARSE_STATUS_EMPTY_EXPR) {
+ bc_parse_push(p, inst);
+ bc_lex_next(&p->l);
+ }
+
+ // POSIX requires parentheses.
+ if (!paren || p->l.last != BC_LEX_RPAREN) {
+ bc_parse_err(p, BC_ERR_POSIX_RET);
+ }
+
+ // Void functions require an empty expression.
+ if (BC_ERR(p->func->voidfn)) {
+ if (s != BC_PARSE_STATUS_EMPTY_EXPR)
+ bc_parse_verr(p, BC_ERR_PARSE_RET_VOID, p->func->name);
+ }
+ // If we got here, we want to be sure to end the function with a real
+ // return instruction, just in case.
+ else bc_parse_push(p, BC_INST_RET);
+ }
+}
+
+/**
+ * Clears flags that indicate the end of an if statement and its block and sets
+ * the jump location.
+ * @param p The parser.
+ */
+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);
+}
+
+/**
+ * Ends (finishes parsing) the body of a control statement or a function.
+ * @param p The parser.
+ * @param brace True if the body was ended by a brace, false otherwise.
+ */
+static void bc_parse_endBody(BcParse *p, bool brace) {
+
+ bool has_brace, new_else = false;
+
+ // We cannot be ending a body if there are no bodies to end.
+ if (BC_ERR(p->flags.len <= 1)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ if (brace) {
+
+ // The brace was already gotten; make sure that the caller did not lie.
+ // We check for the requirement of braces later.
+ assert(p->l.t == BC_LEX_RBRACE);
+
+ bc_lex_next(&p->l);
+
+ // If the next token is not a delimiter, that is a problem.
+ if (BC_ERR(!bc_parse_isDelimiter(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ }
+
+ // Do we have a brace flag?
+ has_brace = (BC_PARSE_BRACE(p) != 0);
+
+ do {
+ size_t len = p->flags.len;
+ bool loop;
+
+ // If we have a brace flag but not a brace, that's a problem.
+ if (has_brace && !brace) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Are we inside a loop?
+ loop = (BC_PARSE_LOOP_INNER(p) != 0);
+
+ // If we are ending a loop or an else...
+ if (loop || BC_PARSE_ELSE(p)) {
+
+ // Loops have condition labels that we have to take care of as well.
+ 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);
+ }
+ // If we are ending a function...
+ 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);
+ }
+ // If we have a brace flag and not an if statement, we can pop the top
+ // of the flags stack because they have been taken care of above.
+ else if (has_brace && !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))) {
+
+ // Eat newlines.
+ while (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
+
+ // *Now* we can pop the flags.
+ bc_vec_pop(&p->flags);
+
+ // If we are allowed non-POSIX stuff...
+ if (!BC_S) {
+
+ // Have we found yet another dangling else?
+ *(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_IF_END;
+ new_else = (p->l.t == BC_LEX_KW_ELSE);
+
+ // Parse the else or end the if statement body.
+ if (new_else) bc_parse_else(p);
+ else if (!has_brace && (!BC_PARSE_IF_END(p) || brace))
+ bc_parse_noElse(p);
+ }
+ // POSIX requires us to do the bare minimum only.
+ else bc_parse_noElse(p);
+ }
+
+ // If these are both true, we have "used" the braces that we found.
+ if (brace && has_brace) brace = false;
+
+ // This condition was perhaps the hardest single part of the parser. If the
+ // flags stack does not have enough, we should stop. If we have a new else
+ // statement, we should stop. If we do have the end of an if statement and
+ // we have eaten the brace, we should stop. If we do have a brace flag, we
+ // should stop.
+ } while (p->flags.len > 1 && !new_else && (!BC_PARSE_IF_END(p) || brace) &&
+ !(has_brace = (BC_PARSE_BRACE(p) != 0)));
+
+ // If we have a brace, yet no body for it, that's a problem.
+ if (BC_ERR(p->flags.len == 1 && brace))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ else if (brace && BC_PARSE_BRACE(p)) {
+
+ // If we make it here, we have a brace and a flag for it.
+ uint16_t flags = BC_PARSE_TOP_FLAG(p);
+
+ // This condition ensure that the *last* body is correctly finished by
+ // popping its flags.
+ 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);
+ }
+ }
+}
+
+/**
+ * Starts the body of a control statement or function.
+ * @param p The parser.
+ * @param flags The current flags (will be edited).
+ */
+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);
+}
+
+/**
+ * Parses an if statement.
+ * @param p The parser.
+ */
+static void bc_parse_if(BcParse *p) {
+
+ // We are allowed relational operators, and we must have a value.
+ size_t idx;
+ uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
+
+ // Get the left paren and barf if necessary.
+ bc_lex_next(&p->l);
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Parse the condition.
+ bc_lex_next(&p->l);
+ bc_parse_expr_status(p, flags, bc_parse_next_rel);
+
+ // Must have a right paren.
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ bc_lex_next(&p->l);
+
+ // Insert the conditional jump instruction.
+ bc_parse_push(p, BC_INST_JUMP_ZERO);
+
+ idx = p->func->labels.len;
+
+ // Push the index for the instruction and create an exit label for an else
+ // statement.
+ bc_parse_pushIndex(p, idx);
+ bc_parse_createExitLabel(p, idx, false);
+
+ bc_parse_startBody(p, BC_PARSE_FLAG_IF);
+}
+
+/**
+ * Parses an else statement.
+ * @param p The parser.
+ */
+static void bc_parse_else(BcParse *p) {
+
+ size_t idx = p->func->labels.len;
+
+ // We must be at the end of an if statement.
+ if (BC_ERR(!BC_PARSE_IF_END(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Push an unconditional jump to make bc jump over the else statement if it
+ // executed the original if statement.
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, idx);
+
+ // Clear the else stuff. Yes, that function is misnamed for its use here,
+ // but deal with it.
+ bc_parse_noElse(p);
+
+ // Create the exit label and parse the body.
+ bc_parse_createExitLabel(p, idx, false);
+ bc_parse_startBody(p, BC_PARSE_FLAG_ELSE);
+
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parse a while loop.
+ * @param p The parser.
+ */
+static void bc_parse_while(BcParse *p) {
+
+ // We are allowed relational operators, and we must have a value.
+ size_t idx;
+ uint8_t flags = (BC_PARSE_REL | BC_PARSE_NEEDVAL);
+
+ // Get the left paren and barf if necessary.
+ 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);
+
+ // Create the labels. Loops need both.
+ bc_parse_createCondLabel(p, p->func->labels.len);
+ idx = p->func->labels.len;
+ bc_parse_createExitLabel(p, idx, true);
+
+ // Parse the actual condition and barf on non-right paren.
+ 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);
+
+ // Now we can push the conditional jump and start the body.
+ 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);
+}
+
+/**
+ * Parse a for loop.
+ * @param p The parser.
+ */
+static void bc_parse_for(BcParse *p) {
+
+ size_t cond_idx, exit_idx, body_idx, update_idx;
+
+ // Barf on the missing left paren.
+ 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);
+
+ // The first statement can be empty, but if it is, check for error in POSIX
+ // mode. Otherwise, parse it.
+ 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);
+
+ // Must have a semicolon.
+ if (BC_ERR(p->l.t != BC_LEX_SCOLON)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ // These are indices for labels. There are so many of them because the end
+ // of the loop must unconditionally jump to the update code. Then the update
+ // code must unconditionally jump to the condition code. Then the condition
+ // code must *conditionally* jump to the exit.
+ cond_idx = p->func->labels.len;
+ update_idx = cond_idx + 1;
+ body_idx = update_idx + 1;
+ exit_idx = body_idx + 1;
+
+ // This creates the condition label.
+ bc_parse_createLabel(p, p->func->code.len);
+
+ // Parse an expression if it exists.
+ 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 because an empty
+ // condition means that it is an infinite loop, so the condition must be
+ // non-zero. 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);
+
+ // An empty condition makes POSIX mad.
+ bc_parse_err(p, BC_ERR_POSIX_FOR);
+ }
+
+ // Must have a semicolon.
+ if (BC_ERR(p->l.t != BC_LEX_SCOLON))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ // Now we can set up the conditional jump to the exit and an unconditional
+ // jump to the body right after. The unconditional jump to the body is
+ // because there is update code coming right after the condition, so we need
+ // to skip it to get to the body.
+ 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);
+
+ // Now create the label for the update code.
+ bc_parse_createCondLabel(p, update_idx);
+
+ // Parse if not empty, and if it is, let POSIX yell if necessary.
+ 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);
+
+ // Must have a right paren.
+ if (BC_ERR(p->l.t != BC_LEX_RPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Set up a jump to the condition right after the update code.
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, cond_idx);
+ bc_parse_createLabel(p, p->func->code.len);
+
+ // Create an exit label for the body and start the body.
+ 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);
+}
+
+/**
+ * Parse a statement or token that indicates a loop exit. This includes an
+ * actual loop exit, the break keyword, or the continue keyword.
+ * @param p The parser.
+ * @param type The type of exit.
+ */
+static void bc_parse_loopExit(BcParse *p, BcLexType type) {
+
+ size_t i;
+ BcInstPtr *ip;
+
+ // Must have a loop. If we don't, that's an error.
+ if (BC_ERR(!BC_PARSE_LOOP(p))) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // If we have a break statement...
+ if (type == BC_LEX_KW_BREAK) {
+
+ // If there are no exits, something went wrong somewhere.
+ if (BC_ERR(!p->exits.len)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+
+ // Get the exit.
+ i = p->exits.len - 1;
+ ip = bc_vec_item(&p->exits, i);
+
+ // The condition !ip->func is true if the exit is not for a loop, so we
+ // need to find the first actual loop exit.
+ while (!ip->func && i < p->exits.len) ip = bc_vec_item(&p->exits, i--);
+
+ // Make sure everything is hunky dory.
+ assert(ip != NULL && (i < p->exits.len || ip->func));
+
+ // Set the index for the exit.
+ i = ip->idx;
+ }
+ // If we have a continue statement or just the loop end, jump to the
+ // condition (or update for a foor loop).
+ else i = *((size_t*) bc_vec_top(&p->conds));
+
+ // Add the unconditional jump.
+ bc_parse_push(p, BC_INST_JUMP);
+ bc_parse_pushIndex(p, i);
+
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parse a function (header).
+ * @param p The parser.
+ */
+static void bc_parse_func(BcParse *p) {
+
+ bool comma = false, voidfn;
+ uint16_t flags;
+ size_t idx;
+
+ bc_lex_next(&p->l);
+
+ // Must have a name.
+ if (BC_ERR(p->l.t != BC_LEX_NAME)) bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ // If the name is "void", and POSIX is not on, mark as void.
+ voidfn = (!BC_IS_POSIX && p->l.t == BC_LEX_NAME &&
+ !strcmp(p->l.str.v, "void"));
+
+ // We can safely do this because the expected token should not overwrite the
+ // function name.
+ bc_lex_next(&p->l);
+
+ // If we *don't* have another name, then void is the name of the function.
+ voidfn = (voidfn && p->l.t == BC_LEX_NAME);
+
+ // With a void function, allow POSIX to complain and get a new token.
+ if (voidfn) {
+
+ bc_parse_err(p, BC_ERR_POSIX_VOID);
+
+ // We can safely do this because the expected token should not overwrite
+ // the function name.
+ bc_lex_next(&p->l);
+ }
+
+ // Must have a left paren.
+ if (BC_ERR(p->l.t != BC_LEX_LPAREN))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ // Make sure the functions map and vector are synchronized.
+ assert(p->prog->fns.len == p->prog->fn_map.len);
+
+ // Must lock signals because vectors are changed, and the vector functions
+ // expect signals to be locked.
+ BC_SIG_LOCK;
+
+ // Insert the function by name into the map and vector.
+ idx = bc_program_insertFunc(p->prog, p->l.str.v);
+
+ BC_SIG_UNLOCK;
+
+ // Make sure the insert worked.
+ assert(idx);
+
+ // Update the function pointer and stuff in the parser and set its void.
+ bc_parse_updateFunc(p, idx);
+ p->func->voidfn = voidfn;
+
+ bc_lex_next(&p->l);
+
+ // While we do not have a right paren, we are still parsing arguments.
+ while (p->l.t != BC_LEX_RPAREN) {
+
+ BcType t = BC_TYPE_VAR;
+
+ // If we have an asterisk, we are parsing a reference argument.
+ if (p->l.t == BC_LEX_OP_MULTIPLY) {
+
+ t = BC_TYPE_REF;
+ bc_lex_next(&p->l);
+
+ // Let POSIX complain if necessary.
+ bc_parse_err(p, BC_ERR_POSIX_REF);
+ }
+
+ // If we don't have a name, the argument will not have a name. Barf.
+ if (BC_ERR(p->l.t != BC_LEX_NAME))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ // Increment the number of parameters.
+ p->func->nparams += 1;
+
+ // Copy the string in the lexer so that we can use the lexer again.
+ bc_vec_string(&p->buf, p->l.str.len, p->l.str.v);
+
+ bc_lex_next(&p->l);
+
+ // We are parsing an array parameter if this is true.
+ if (p->l.t == BC_LEX_LBRACKET) {
+
+ // Set the array type, unless we are already parsing a reference.
+ if (t == BC_TYPE_VAR) t = BC_TYPE_ARRAY;
+
+ bc_lex_next(&p->l);
+
+ // The brackets *must* be empty.
+ if (BC_ERR(p->l.t != BC_LEX_RBRACKET))
+ bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ bc_lex_next(&p->l);
+ }
+ // If we did *not* get a bracket, but we are expecting a reference, we
+ // have a problem.
+ else if (BC_ERR(t == BC_TYPE_REF))
+ bc_parse_verr(p, BC_ERR_PARSE_REF_VAR, p->buf.v);
+
+ // Test for comma and get the next token if it exists.
+ comma = (p->l.t == BC_LEX_COMMA);
+ if (comma) bc_lex_next(&p->l);
+
+ // Insert the parameter into the function.
+ bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line);
+ }
+
+ // If we have a comma, but no parameter, barf.
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ // Start the body.
+ flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER;
+ bc_parse_startBody(p, flags);
+
+ bc_lex_next(&p->l);
+
+ // POSIX requires that a brace be on the same line as the function header.
+ // If we don't have a brace, let POSIX throw an error.
+ if (p->l.t != BC_LEX_LBRACE) bc_parse_err(p, BC_ERR_POSIX_BRACE);
+}
+
+/**
+ * Parse an auto list.
+ * @param p The parser.
+ */
+static void bc_parse_auto(BcParse *p) {
+
+ bool comma, one;
+
+ // Error if the auto keyword appeared in the wrong place.
+ if (BC_ERR(!p->auto_part)) bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ bc_lex_next(&p->l);
+
+ p->auto_part = comma = false;
+
+ // We need at least one variable or array.
+ one = (p->l.t == BC_LEX_NAME);
+
+ // While we have a variable or array.
+ while (p->l.t == BC_LEX_NAME) {
+
+ BcType t;
+
+ // Copy the name from the lexer, so we can use it again.
+ bc_vec_string(&p->buf, p->l.str.len - 1, p->l.str.v);
+
+ bc_lex_next(&p->l);
+
+ // If we are parsing an array...
+ if (p->l.t == BC_LEX_LBRACKET) {
+
+ t = BC_TYPE_ARRAY;
+
+ bc_lex_next(&p->l);
+
+ // The brackets *must* be empty.
+ 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;
+
+ // Test for comma and get the next token if it exists.
+ comma = (p->l.t == BC_LEX_COMMA);
+ if (comma) bc_lex_next(&p->l);
+
+ // Insert the auto into the function.
+ bc_func_insert(p->func, p->prog, p->buf.v, t, p->l.line);
+ }
+
+ // If we have a comma, but no auto, barf.
+ if (BC_ERR(comma)) bc_parse_err(p, BC_ERR_PARSE_FUNC);
+
+ // If we don't have any variables or arrays, barf.
+ if (BC_ERR(!one)) bc_parse_err(p, BC_ERR_PARSE_NO_AUTO);
+
+ // The auto statement should be all that's in the statement.
+ if (BC_ERR(!bc_parse_isDelimiter(p)))
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+}
+
+/**
+ * Parses a body.
+ * @param p The parser.
+ * @param brace True if a brace was encountered, false otherwise.
+ */
+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);
+
+ // The body flag is for when we expect a body. We got a body, so clear the
+ // flag.
+ *flag_ptr &= ~(BC_PARSE_FLAG_BODY);
+
+ // If we are inside a function, that means we just barely entered it, and
+ // we can expect an auto list.
+ if (*flag_ptr & BC_PARSE_FLAG_FUNC_INNER) {
+
+ // We *must* have a brace in this case.
+ 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;
+
+ // Since we already have the auto keyword, parse.
+ bc_parse_auto(p);
+ }
+
+ // Eat a newline.
+ if (p->l.t == BC_LEX_NLINE) bc_lex_next(&p->l);
+ }
+ else {
+
+ // This is the easy part.
+ size_t len = p->flags.len;
+
+ assert(*flag_ptr);
+
+ // Parse a statement.
+ bc_parse_stmt(p);
+
+ // This is a very important condition to get right. If there is no
+ // brace, and no body flag, and the flags len hasn't shrunk, then we
+ // have a body that was not delimited by braces, so we need to end it
+ // now, after just one statement.
+ if (!brace && !BC_PARSE_BODY(p) && len <= p->flags.len)
+ bc_parse_endBody(p, false);
+ }
+}
+
+/**
+ * Parses a statement. This is the entry point for just about everything, except
+ * function definitions.
+ * @param p The parser.
+ */
+static void bc_parse_stmt(BcParse *p) {
+
+ size_t len;
+ uint16_t flags;
+ BcLexType type = p->l.t;
+
+ // Eat newline.
+ if (type == BC_LEX_NLINE) {
+ bc_lex_next(&p->l);
+ return;
+ }
+
+ // Eat auto list.
+ if (type == BC_LEX_KW_AUTO) {
+ bc_parse_auto(p);
+ return;
+ }
+
+ // If we reach this point, no auto list is allowed.
+ p->auto_part = false;
+
+ // Everything but an else needs to be taken care of here, but else is
+ // special.
+ if (type != BC_LEX_KW_ELSE) {
+
+ // After an if, no else found.
+ if (BC_PARSE_IF_END(p)) {
+
+ // Clear the expectation for else, end body, and return. Returning
+ // gives us a clean slate for parsing again.
+ bc_parse_noElse(p);
+ if (p->flags.len > 1 && !BC_PARSE_BRACE(p))
+ bc_parse_endBody(p, false);
+ return;
+ }
+ // With a left brace, we are parsing a body.
+ else if (type == BC_LEX_LBRACE) {
+
+ // We need to start a body if we are not expecting one yet.
+ if (!BC_PARSE_BODY(p)) {
+ bc_parse_startBody(p, BC_PARSE_FLAG_BRACE);
+ bc_lex_next(&p->l);
+ }
+ // If we *are* expecting a body, that body should get a brace. This
+ // takes care of braces being on a different line than if and loop
+ // headers.
+ else {
+ *(BC_PARSE_TOP_FLAG_PTR(p)) |= BC_PARSE_FLAG_BRACE;
+ bc_lex_next(&p->l);
+ bc_parse_body(p, true);
+ }
+
+ // If we have reached this point, we need to return for a clean
+ // slate.
+ return;
+ }
+ // This happens when we are expecting a body and get a single statement,
+ // i.e., a body with no braces surrounding it. Returns after for a clean
+ // slate.
+ 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) {
+
+ // All of these are valid for expressions.
+ 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
+ case BC_LEX_KW_SEED:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_SQRT:
+ case BC_LEX_KW_ABS:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_IRAND:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_ASCIIFY:
+ case BC_LEX_KW_MODEXP:
+ case BC_LEX_KW_DIVMOD:
+ case BC_LEX_KW_READ:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_RAND:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_MAXIBASE:
+ case BC_LEX_KW_MAXOBASE:
+ case BC_LEX_KW_MAXSCALE:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_MAXRAND:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_LINE_LENGTH:
+ case BC_LEX_KW_GLOBAL_STACKS:
+ case BC_LEX_KW_LEADING_ZERO:
+ {
+ bc_parse_expr_status(p, BC_PARSE_PRINT, bc_parse_next_expr);
+ break;
+ }
+
+ case BC_LEX_KW_ELSE:
+ {
+ bc_parse_else(p);
+ break;
+ }
+
+ // Just eat.
+ 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:
+ {
+ // `limits` is a compile-time command, so execute it right away.
+ 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_vm_printf("BC_RAND_MAX = %lu\n", BC_MAX_RAND);
+#endif // BC_ENABLE_EXTRA_MATH
+ 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_STREAM:
+ case BC_LEX_KW_PRINT:
+ {
+ bc_parse_print(p, type);
+ break;
+ }
+
+ case BC_LEX_KW_QUIT:
+ {
+ // Quit is a compile-time command. We don't exit directly, so the vm
+ // can clean up.
+ vm.status = BC_STATUS_QUIT;
+ BC_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 the flags did not change, we expect a delimiter.
+ 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);
+
+ // We should not let an EOF get here unless some partial parse was not
+ // completed, in which case, it's the user's fault.
+ if (BC_ERR(p->l.t == BC_LEX_EOF)) bc_parse_err(p, BC_ERR_PARSE_EOF);
+
+ // Functions need special parsing.
+ else if (p->l.t == BC_LEX_KW_DEFINE) {
+ if (BC_ERR(BC_PARSE_NO_EXEC(p))) {
+ if (p->flags.len == 1 &&
+ BC_PARSE_TOP_FLAG(p) == BC_PARSE_FLAG_IF_END)
+ {
+ bc_parse_noElse(p);
+ }
+ else bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ }
+ bc_parse_func(p);
+ }
+
+ // Otherwise, parse a normal statement.
+ else bc_parse_stmt(p);
+
+exit:
+
+ BC_SIG_MAYLOCK;
+
+ // We need to reset on error.
+ if (BC_ERR(((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig)))
+ bc_parse_reset(p);
+
+ BC_LONGJMP_CONT;
+}
+
+/**
+ * Parse an expression. This is the actual implementation of the Shunting-Yard
+ * Algorithm.
+ * @param p The parser.
+ * @param flags The flags for what is valid in the expression.
+ * @param next A set of tokens for what is valid *after* the expression.
+ * @return A parse status. In some places, an empty expression is an
+ * error, and sometimes, it is required. This allows this function
+ * to tell the caller if the expression was empty and let the
+ * caller handle it.
+ */
+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;
+ size_t nexprs, ops_bgn;
+ uint32_t i, nparens, nrelops;
+ bool pfirst, rprn, done, get_token, assign, bin_last, incdec, can_assign;
+
+ // One of these *must* be true.
+ assert(!(flags & BC_PARSE_PRINT) || !(flags & BC_PARSE_NEEDVAL));
+
+ // These are set very carefully. In fact, controlling the values of these
+ // locals is the biggest part of making this work. ops_bgn especially is
+ // important because it marks where the operator stack begins for *this*
+ // invocation of this function. That's because bc_parse_expr_err() is
+ // recursive (the Shunting-Yard Algorithm is most easily expressed
+ // recursively when parsing subexpressions), and each invocation needs to
+ // know where to stop.
+ //
+ // - nparens is the number of left parens without matches.
+ // - nrelops is the number of relational operators that appear in the expr.
+ // - nexprs is the number of unused expressions.
+ // - rprn is a right paren encountered last.
+ // - done means the expression has been fully parsed.
+ // - get_token is true when a token is needed at the end of an iteration.
+ // - assign is true when an assignment statement was parsed last.
+ // - incdec is true when the previous operator was an inc or dec operator.
+ // - can_assign is true when an assignemnt is valid.
+ // - bin_last is true when the previous instruction was a binary operator.
+ t = p->l.t;
+ pfirst = (p->l.t == BC_LEX_LPAREN);
+ nparens = nrelops = 0;
+ nexprs = 0;
+ ops_bgn = p->ops.len;
+ 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);
+ }
+
+ // This is the Shunting-Yard algorithm loop.
+ for (; !done && BC_PARSE_EXPR(t); t = p->l.t)
+ {
+ switch (t) {
+
+ case BC_LEX_OP_INC:
+ case BC_LEX_OP_DEC:
+ {
+ // These operators can only be used with items that can be
+ // assigned to.
+ 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:
+ {
+ // The previous token must have been a leaf expression, or the
+ // operator is in the wrong place.
+ 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;
+
+ // This is true if it was a binary operator last.
+ bin_last = (prev == BC_INST_MINUS);
+ if (bin_last) incdec = false;
+
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ // All of this group, including the fallthrough, is to parse binary
+ // operators.
+ 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:
+ {
+ // We need to make sure the assignment is valid.
+ 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:
+ {
+ // This is true if the operator if the token is a prefix
+ // operator. This is only for boolean not.
+ if (BC_PARSE_OP_PREFIX(t)) {
+
+ // Prefix operators are only allowed after binary operators
+ // or prefix operators.
+ if (BC_ERR(!bin_last && !BC_PARSE_OP_PREFIX(p->l.last)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+ }
+ // If we execute the else, that means we have a binary operator.
+ // If the previous operator was a prefix or a binary operator,
+ // then a binary operator is not allowed.
+ 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:
+ {
+ // A left paren is *not* allowed right after a leaf expr.
+ 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;
+
+ // Push the paren onto the operator stack.
+ 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;
+
+ // The right paren must not come after a prefix or binary
+ // operator.
+ if (BC_ERR(bin_last || BC_PARSE_PREV_PREFIX(prev)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ // If there are no parens left, we are done, but we need another
+ // token.
+ 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_STR:
+ {
+ // POSIX only allows strings alone.
+ if (BC_IS_POSIX) bc_parse_err(p, BC_ERR_POSIX_EXPR_STRING);
+
+ // A string is a leaf and cannot come right after a leaf.
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ bc_parse_addString(p);
+
+ get_token = true;
+ bin_last = rprn = false;
+ nexprs += 1;
+
+ break;
+ }
+
+ case BC_LEX_NAME:
+ {
+ // A name is a leaf and cannot come right after a leaf.
+ 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:
+ {
+ // A number is a leaf and cannot come right after a leaf.
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ // The number instruction is pushed in here.
+ 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
+ case BC_LEX_KW_SEED:
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ // All of these are leaves and cannot come right after a leaf.
+ 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
+ case BC_LEX_KW_IRAND:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_ASCIIFY:
+ {
+ // All of these are leaves and cannot come right after a leaf.
+ 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
+ case BC_LEX_KW_RAND:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_MAXIBASE:
+ case BC_LEX_KW_MAXOBASE:
+ case BC_LEX_KW_MAXSCALE:
+#if BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_MAXRAND:
+#endif // BC_ENABLE_EXTRA_MATH
+ case BC_LEX_KW_LINE_LENGTH:
+ case BC_LEX_KW_GLOBAL_STACKS:
+ case BC_LEX_KW_LEADING_ZERO:
+ {
+ // All of these are leaves and cannot come right after a leaf.
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ // Error if we have read and it's not allowed.
+ else if (t == BC_LEX_KW_READ && BC_ERR(flags & BC_PARSE_NOREAD))
+ bc_parse_err(p, BC_ERR_EXEC_REC_READ);
+
+ 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:
+ {
+ // This is a leaf and cannot come right after a leaf.
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ // Scale needs special work because it can be a variable *or* a
+ // function.
+ bc_parse_scale(p, &prev, &can_assign, flags);
+
+ rprn = get_token = bin_last = false;
+ nexprs += 1;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ case BC_LEX_KW_MODEXP:
+ case BC_LEX_KW_DIVMOD:
+ {
+ // This is a leaf and cannot come right after a leaf.
+ if (BC_ERR(BC_PARSE_LEAF(prev, bin_last, rprn)))
+ bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ bc_parse_builtin3(p, t, flags, &prev);
+
+ rprn = get_token = bin_last = incdec = can_assign = false;
+ nexprs += 1;
+ flags &= ~(BC_PARSE_ARRAY);
+
+ break;
+ }
+
+ default:
+ {
+#ifndef NDEBUG
+ // We should never get here, even in debug builds.
+ bc_parse_err(p, BC_ERR_PARSE_TOKEN);
+ break;
+#endif // NDEBUG
+ }
+ }
+
+ if (get_token) bc_lex_next(&p->l);
+ }
+
+ // Now that we have parsed the expression, we need to empty the operator
+ // stack.
+ while (p->ops.len > ops_bgn) {
+
+ top = BC_PARSE_TOP_OP(p);
+ assign = top >= BC_LEX_OP_ASSIGN_POWER && top <= BC_LEX_OP_ASSIGN;
+
+ // There should not be *any* parens on the stack anymore.
+ 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));
+
+ // Adjust the number of unused expressions.
+ nexprs -= !BC_PARSE_OP_PREFIX(top);
+ bc_vec_pop(&p->ops);
+
+ incdec = false;
+ }
+
+ // There must be only one expression at the top.
+ if (BC_ERR(nexprs != 1)) bc_parse_err(p, BC_ERR_PARSE_EXPR);
+
+ // Check that the next token is correct.
+ 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);
+
+ // Check that POSIX would be happy with the number of relational operators.
+ 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 this is true, then we might be in a situation where we don't print.
+ // We would want to have the increment/decrement operator not make an extra
+ // copy if it's not necessary.
+ if (!(flags & BC_PARSE_NEEDVAL) && !pfirst) {
+
+ // We have the easy case if the last operator was an assignment
+ // operator.
+ if (assign) {
+ inst = *((uchar*) bc_vec_top(&p->func->code));
+ inst += (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER);
+ incdec = false;
+ }
+ // If we have an inc/dec operator and we are *not* printing, implement
+ // the optimization to get rid of the extra copy.
+ 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);
+ }
+
+ // This condition allows us to change the previous assignment
+ // instruction (which does a copy) for a NO_VAL version, which does not.
+ // This condition is set if either of the above if statements ends up
+ // being true.
+ if (inst >= BC_INST_ASSIGN_POWER_NO_VAL &&
+ inst <= BC_INST_ASSIGN_NO_VAL)
+ {
+ // Pop the previous assignment instruction and push a new one.
+ // Inc/dec needs the extra instruction because it is now a binary
+ // operator and needs a second operand.
+ bc_vec_pop(&p->func->code);
+ if (incdec) bc_parse_push(p, BC_INST_ONE);
+ bc_parse_push(p, inst);
+ }
+ }
+
+ // If we might have to print...
+ if ((flags & BC_PARSE_PRINT)) {
+
+ // With a paren first or the last operator not being an assignment, we
+ // *do* want to print.
+ if (pfirst || !assign) bc_parse_push(p, BC_INST_PRINT);
+ }
+ // We need to make sure to push a pop instruction for assignment statements
+ // that will not print. The print will pop, but without it, we need to pop.
+ 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.
+ //
+ // Yes, this is one case where I reuse a variable for a different purpose;
+ // in this case, incdec being true now means that newlines are not valid.
+ 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;
+}
+
+/**
+ * Parses an expression with bc_parse_expr_err(), but throws an error if it gets
+ * an empty expression.
+ * @param p The parser.
+ * @param flags The flags for what is valid in the expression.
+ * @param next A set of tokens for what is valid *after* the expression.
+ */
+static 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..82475299ed78
--- /dev/null
+++ b/contrib/bc/src/data.c
@@ -0,0 +1,1320 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Constant data for bc.
+ *
+ */
+
+#include <assert.h>
+
+#include <opt.h>
+#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 <history.h>
+#include <library.h>
+#include <vm.h>
+
+#if !BC_ENABLE_LIBRARY
+
+#if BC_ENABLED
+
+/// The bc signal message and its length.
+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
+
+/// The dc signal message and its length.
+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
+
+/// The copyright banner.
+const char bc_copyright[] =
+ "Copyright (c) 2018-2021 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";
+
+#ifdef __OpenBSD__
+
+#if BC_ENABLE_EXTRA_MATH
+
+#if BC_ENABLE_HISTORY
+
+/// The pledges for starting bc.
+const char bc_pledge_start[] = "rpath stdio tty unveil";
+
+/// The final pledges with history enabled.
+const char bc_pledge_end_history[] = "rpath stdio tty";
+
+#else // BC_ENABLE_HISTORY
+
+/// The pledges for starting bc.
+const char bc_pledge_start[] = "rpath stdio unveil";
+
+#endif // BC_ENABLE_HISTORY
+
+/// The final pledges with history history disabled.
+const char bc_pledge_end[] = "rpath stdio";
+
+#else // BC_ENABLE_EXTRA_MATH
+
+#if BC_ENABLE_HISTORY
+
+/// The pledges for starting bc.
+const char bc_pledge_start[] = "rpath stdio tty";
+
+/// The final pledges with history enabled.
+const char bc_pledge_end_history[] = "stdio tty";
+
+#else // BC_ENABLE_HISTORY
+
+/// The pledges for starting bc.
+const char bc_pledge_start[] = "rpath stdio";
+
+#endif // BC_ENABLE_HISTORY
+
+/// The final pledges with history history disabled.
+const char bc_pledge_end[] = "stdio";
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+#else // __OpenBSD__
+
+/// The pledges for starting bc.
+const char bc_pledge_start[] = "";
+
+#if BC_ENABLE_HISTORY
+
+/// The final pledges with history enabled.
+const char bc_pledge_end_history[] = "";
+
+#endif // BC_ENABLE_HISTORY
+
+/// The final pledges with history history disabled.
+const char bc_pledge_end[] = "";
+
+#endif // __OpenBSD__
+
+/// The list of long options. There is a zero set at the end for detecting the
+/// end.
+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' },
+ { "leading-zeroes", BC_OPT_NONE, 'z' },
+ { "no-line-length", BC_OPT_NONE, 'L' },
+ { "no-prompt", BC_OPT_NONE, 'P' },
+ { "no-read-prompt", BC_OPT_NONE, 'R' },
+#if BC_ENABLED
+ { "global-stacks", BC_OPT_BC_ONLY, 'g' },
+ { "mathlib", BC_OPT_BC_ONLY, 'l' },
+ { "quiet", BC_OPT_BC_ONLY, 'q' },
+ { "redefine", BC_OPT_REQUIRED_BC_ONLY, 'r' },
+ { "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 },
+
+};
+
+/// The function header for error messages.
+const char* const bc_err_func_header = "Function:";
+
+/// The line format string for error messages.
+const char* const bc_err_line = ":%zu";
+
+/// The default error category strings.
+const char *bc_errs[] = {
+ "Math error:",
+ "Parse error:",
+ "Runtime error:",
+ "Fatal error:",
+#if BC_ENABLED
+ "Warning:",
+#endif // BC_ENABLED
+};
+
+/// The error category for each error.
+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_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_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, BC_ERR_IDX_PARSE,
+#endif // BC_ENABLED
+
+};
+
+/// The default error messages. There are NULL pointers because the positions
+/// must be preserved for the locales.
+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 text: %s",
+ "path is a directory: %s",
+ "bad command-line option: \"%s\"",
+ "option requires an argument: '%c' (\"%s\")",
+ "option takes no arguments: '%c' (\"%s\")",
+ "bad option argument: \"%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",
+ "stack for register \"%s\" has too few elements",
+#else // DC_ENABLED
+ NULL, 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 or stream 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",
+ "POSIX does not allow strings to be assigned to variables or arrays",
+#endif // BC_ENABLED
+
+};
+
+#endif // !BC_ENABLE_LIBRARY
+
+/// The destructors corresponding to BcDtorType enum items.
+const BcVecFree bc_vec_dtors[] = {
+ NULL,
+ bc_vec_free,
+ bc_num_free,
+#if !BC_ENABLE_LIBRARY
+#ifndef NDEBUG
+ bc_func_free,
+#endif // NDEBUG
+ bc_slab_free,
+ bc_const_free,
+ bc_result_free,
+#if BC_ENABLE_HISTORY
+ bc_history_string_free,
+#endif // BC_ENABLE_HISTORY
+#else // !BC_ENABLE_LIBRARY
+ bcl_num_destruct,
+#endif // !BC_ENABLE_LIBRARY
+};
+
+#if !BC_ENABLE_LIBRARY
+
+#if BC_ENABLE_HISTORY
+
+/// A flush type for not clearing current extras but not saving new ones either.
+const BcFlushType bc_flush_none = BC_FLUSH_NO_EXTRAS_NO_CLEAR;
+
+/// A flush type for clearing extras and not saving new ones.
+const BcFlushType bc_flush_err = BC_FLUSH_NO_EXTRAS_CLEAR;
+
+/// A flush type for clearing previous extras and saving new ones.
+const BcFlushType bc_flush_save = BC_FLUSH_SAVE_EXTRAS_CLEAR;
+#endif // BC_ENABLE_HISTORY
+
+#if BC_ENABLE_HISTORY
+
+/// A list of known bad terminals.
+const char *bc_history_bad_terms[] = { "dumb", "cons25", "emacs", NULL };
+
+/// A constant for tabs and its length. My tab handling is dumb and always
+/// outputs the entire thing.
+const char bc_history_tab[] = " ";
+const size_t bc_history_tab_len = sizeof(bc_history_tab) - 1;
+
+/// A list of wide chars. 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 },
+};
+
+/// The length of the wide chars list.
+const size_t bc_history_wchars_len =
+ sizeof(bc_history_wchars) / sizeof(bc_history_wchars[0]);
+
+/// A list of combining characters in Unicode. 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,
+};
+
+/// The length of the combining characters list.
+const size_t bc_history_combo_chars_len =
+ sizeof(bc_history_combo_chars) / sizeof(bc_history_combo_chars[0]);
+#endif // BC_ENABLE_HISTORY
+
+/// The human-readable name of the main function in bc source code.
+const char bc_func_main[] = "(main)";
+
+/// The human-readable name of the read function in bc source code.
+const char bc_func_read[] = "(read)";
+
+#if BC_DEBUG_CODE
+
+/// A list of names of instructions for easy debugging output.
+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",
+ "BC_INST_ARRAY",
+
+ "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_ASCIIFY",
+ "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",
+#if BC_ENABLED
+ "BC_INST_PRINT_STR",
+
+ "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",
+ "BC_INST_SWAP",
+ "BC_INST_MODEXP",
+ "BC_INST_DIVMOD",
+ "BC_INST_PRINT_STREAM",
+
+#if DC_ENABLED
+ "BC_INST_POP_EXEC",
+
+ "BC_INST_EXECUTE",
+ "BC_INST_EXEC_COND",
+
+ "BC_INST_PRINT_STACK",
+ "BC_INST_CLEAR_STACK",
+ "BC_INST_REG_STACK_LEN",
+ "BC_INST_STACK_LEN",
+ "BC_INST_DUPLICATE",
+
+ "BC_INST_LOAD",
+ "BC_INST_PUSH_VAR",
+ "BC_INST_PUSH_TO_VAR",
+
+ "BC_INST_QUIT",
+ "BC_INST_NQUIT",
+
+ "BC_INST_EXEC_STACK_LEN",
+#endif // DC_ENABLED
+
+ "BC_INST_INVALID",
+};
+
+#endif // BC_DEBUG_CODE
+
+/// A constant string for 0.
+const char bc_parse_zero[2] = "0";
+
+/// A constant string for 1.
+const char bc_parse_one[2] = "1";
+
+#if BC_ENABLED
+
+/// A list of keywords for bc. This needs to be updated if keywords change.
+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_LEX_KW_ENTRY("seed", 4, false),
+#endif // BC_ENABLE_EXTRA_MATH
+ 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_LEX_KW_ENTRY("irand", 5, false),
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_KW_ENTRY("asciify", 7, false),
+ BC_LEX_KW_ENTRY("modexp", 6, false),
+ BC_LEX_KW_ENTRY("divmod", 6, false),
+ BC_LEX_KW_ENTRY("quit", 4, true),
+ BC_LEX_KW_ENTRY("read", 4, false),
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_KW_ENTRY("rand", 4, false),
+#endif // BC_ENABLE_EXTRA_MATH
+ 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_LEX_KW_ENTRY("maxrand", 7, false),
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_KW_ENTRY("line_length", 11, false),
+ BC_LEX_KW_ENTRY("global_stacks", 13, false),
+ BC_LEX_KW_ENTRY("leading_zero", 12, false),
+ BC_LEX_KW_ENTRY("stream", 6, false),
+ BC_LEX_KW_ENTRY("else", 4, false),
+};
+
+/// The length of the list of bc keywords.
+const size_t bc_lex_kws_len = sizeof(bc_lex_kws) / sizeof(BcLexKeyword);
+
+#if BC_C11
+
+// This is here to ensure that BC_LEX_NKWS, which is needed for the
+// redefined_kws in BcVm, is correct. If it's correct under C11, it will be
+// correct under C99, and I did not know any other way of ensuring they remained
+// synchronized.
+static_assert(sizeof(bc_lex_kws) / sizeof(BcLexKeyword) == BC_LEX_NKWS,
+ "BC_LEX_NKWS is wrong.");
+
+#endif // BC_C11
+
+/// An array of booleans that correspond to token types. An entry is true if the
+/// token is valid in an expression, false otherwise. This will need to change
+/// if tokens change.
+const uint8_t bc_parse_exprs[] = {
+
+ // Starts with BC_LEX_EOF.
+ BC_PARSE_EXPR_ENTRY(false, false, true, true, true, true, true, true),
+
+ // Starts with BC_LEX_OP_MULTIPLY if extra math is enabled, BC_LEX_OP_DIVIDE
+ // otherwise.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+
+ // Starts with BC_LEX_OP_REL_EQ if extra math is enabled, BC_LEX_OP_REL_LT
+ // otherwise.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+
+#if BC_ENABLE_EXTRA_MATH
+
+ // Starts with BC_LEX_OP_ASSIGN_POWER.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+
+ // Starts with BC_LEX_OP_ASSIGN_RSHIFT.
+ BC_PARSE_EXPR_ENTRY(true, true, false, false, true, true, false, false),
+
+ // Starts with BC_LEX_RBRACKET.
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, true, true, true, false),
+
+ // Starts with BC_LEX_KW_BREAK.
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false),
+
+ // Starts with BC_LEX_KW_HALT.
+ BC_PARSE_EXPR_ENTRY(false, true, true, true, true, true, true, false),
+
+ // Starts with BC_LEX_KW_SQRT.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, false, true),
+
+ // Starts with BC_LEX_KW_MAXIBASE.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, true, true, true),
+
+ // Starts with BC_LEX_KW_STREAM.
+ BC_PARSE_EXPR_ENTRY(false, false, 0, 0, 0, 0, 0, 0)
+
+#else // BC_ENABLE_EXTRA_MATH
+
+ // Starts with BC_LEX_OP_ASSIGN_PLUS.
+ BC_PARSE_EXPR_ENTRY(true, true, true, false, false, true, true, false),
+
+ // Starts with BC_LEX_COMMA.
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, true, true, true),
+
+ // Starts with BC_LEX_KW_AUTO.
+ BC_PARSE_EXPR_ENTRY(false, false, false, false, false, false, false, false),
+
+ // Starts with BC_LEX_KW_WHILE.
+ BC_PARSE_EXPR_ENTRY(false, false, true, true, true, true, true, false),
+
+ // Starts with BC_LEX_KW_SQRT.
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, false, true, true),
+
+ // Starts with BC_LEX_KW_MAXSCALE,
+ BC_PARSE_EXPR_ENTRY(true, true, true, true, true, false, false, 0)
+
+#endif // BC_ENABLE_EXTRA_MATH
+};
+
+/// 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.
+
+/// The valid next tokens for normal expressions.
+const BcParseNext bc_parse_next_expr =
+ BC_PARSE_NEXT(4, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_RBRACE, BC_LEX_EOF);
+
+/// The valid next tokens for function argument expressions.
+const BcParseNext bc_parse_next_arg =
+ BC_PARSE_NEXT(2, BC_LEX_RPAREN, BC_LEX_COMMA);
+
+/// The valid next tokens for expressions in print statements.
+const BcParseNext bc_parse_next_print =
+ BC_PARSE_NEXT(4, BC_LEX_COMMA, BC_LEX_NLINE, BC_LEX_SCOLON, BC_LEX_EOF);
+
+/// The valid next tokens for if statement conditions or loop conditions. This
+/// is used in for loops for the update expression and for builtin function.
+///
+/// The name is an artifact of history, and is related to @a BC_PARSE_REL (see
+/// include/parse.h). It refers to how POSIX only allows some operators as part
+/// of the conditional of for loops, while loops, and if statements.
+const BcParseNext bc_parse_next_rel = BC_PARSE_NEXT(1, BC_LEX_RPAREN);
+
+/// The valid next tokens for array element expressions.
+const BcParseNext bc_parse_next_elem = BC_PARSE_NEXT(1, BC_LEX_RBRACKET);
+
+/// The valid next tokens for for loop initialization expressions and condition
+/// expressions.
+const BcParseNext bc_parse_next_for = BC_PARSE_NEXT(1, BC_LEX_SCOLON);
+
+/// The valid next tokens for read expressions.
+const BcParseNext bc_parse_next_read =
+ BC_PARSE_NEXT(2, BC_LEX_NLINE, BC_LEX_EOF);
+
+/// The valid next tokens for the arguments of a builtin function with multiple
+/// arguments.
+const BcParseNext bc_parse_next_builtin = BC_PARSE_NEXT(1, BC_LEX_COMMA);
+
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+
+/// A list of instructions that need register arguments in dc.
+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, BC_LEX_REG_STACK_LEVEL, BC_LEX_ARRAY_LENGTH,
+};
+
+/// The length of the list of register instructions.
+const size_t dc_lex_regs_len = sizeof(dc_lex_regs) / sizeof(uint8_t);
+
+/// A list corresponding to characters starting at double quote ("). If an entry
+/// is BC_LEX_INVALID, then that character needs extra lexing in dc. If it does
+/// not, the character can trivially be replaced by the entry. Positions are
+/// kept because it corresponds to the ASCII table. This may need to be changed
+/// if tokens change.
+const uchar dc_lex_tokens[] = {
+#if BC_ENABLE_EXTRA_MATH
+ BC_LEX_KW_IRAND,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ 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_LEX_KW_RAND,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_LPAREN, BC_LEX_RPAREN, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS,
+ BC_LEX_EXEC_STACK_LENGTH, 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_LEX_KW_SEED,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_KW_SCALE, BC_LEX_LOAD_POP, BC_LEX_OP_BOOL_AND, BC_LEX_OP_BOOL_NOT,
+ BC_LEX_KW_OBASE, BC_LEX_KW_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_LEX_KW_MAXRAND,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_LEX_SCALE_FACTOR, BC_LEX_ARRAY_LENGTH, 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_KW_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_LEX_STORE_SEED,
+#else // BC_ENABLE_EXTRA_MATH
+ BC_LEX_INVALID,
+#endif // BC_ENABLE_EXTRA_MATH
+ 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_REG_STACK_LEVEL, BC_LEX_STACK_LEVEL,
+ BC_LEX_LBRACE, BC_LEX_KW_MODEXP, BC_LEX_RBRACE, BC_LEX_KW_DIVMOD,
+ BC_LEX_INVALID
+};
+
+/// A list of instructions that correspond to lex tokens. If an entry is
+/// BC_INST_INVALID, that lex token needs extra parsing in the dc parser.
+/// Otherwise, the token can trivially be replaced by the entry. This needs to
+/// be updated if the tokens change.
+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_INST_SEED,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_INST_LENGTH, BC_INST_PRINT,
+ BC_INST_SQRT, BC_INST_ABS,
+#if BC_ENABLE_EXTRA_MATH
+ BC_INST_IRAND,
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_INST_ASCIIFY, BC_INST_MODEXP, BC_INST_DIVMOD,
+ BC_INST_QUIT, BC_INST_INVALID,
+#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_LINE_LENGTH,
+#if BC_ENABLED
+ BC_INST_INVALID,
+#endif // BC_ENABLED
+ BC_INST_LEADING_ZERO, BC_INST_PRINT_STREAM, BC_INST_INVALID,
+ BC_INST_REL_EQ, BC_INST_INVALID,
+ BC_INST_EXECUTE, BC_INST_PRINT_STACK, BC_INST_CLEAR_STACK,
+ BC_INST_INVALID, BC_INST_STACK_LEN, BC_INST_DUPLICATE, BC_INST_SWAP,
+ BC_INST_POP,
+ 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_EXEC_STACK_LEN,
+ BC_INST_SCALE_FUNC, BC_INST_INVALID,
+};
+#endif // DC_ENABLED
+
+#endif // !BC_ENABLE_LIBRARY
+
+#if BC_ENABLE_EXTRA_MATH
+
+/// A constant for the rand multiplier.
+const BcRandState bc_rand_multiplier = BC_RAND_MULTIPLIER;
+
+#endif // BC_ENABLE_EXTRA_MATH
+
+#if BC_LONG_BIT >= 64
+
+/// A constant array for the max of a bigdig number as a BcDig array.
+const BcDig bc_num_bigdigMax[] = {
+ 709551616U,
+ 446744073U,
+ 18U,
+};
+
+/// A constant array for the max of 2 times a bigdig number as a BcDig array.
+const BcDig bc_num_bigdigMax2[] = {
+ 768211456U,
+ 374607431U,
+ 938463463U,
+ 282366920U,
+ 340U,
+};
+
+#else // BC_LONG_BIT >= 64
+
+/// A constant array for the max of a bigdig number as a BcDig array.
+const BcDig bc_num_bigdigMax[] = {
+ 7296U,
+ 9496U,
+ 42U,
+};
+
+/// A constant array for the max of 2 times a bigdig number as a BcDig array.
+const BcDig bc_num_bigdigMax2[] = {
+ 1616U,
+ 955U,
+ 737U,
+ 6744U,
+ 1844U,
+};
+
+#endif // BC_LONG_BIT >= 64
+
+/// The size of the bigdig max array.
+const size_t bc_num_bigdigMax_size = sizeof(bc_num_bigdigMax) / sizeof(BcDig);
+
+/// The size of the bigdig max times 2 array.
+const size_t bc_num_bigdigMax2_size = sizeof(bc_num_bigdigMax2) / sizeof(BcDig);
+
+/// A string of digits for easy conversion from characters to digits.
+const char bc_num_hex_digits[] = "0123456789ABCDEF";
+
+/// An array for easy conversion from exponent to power of 10.
+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
+
+/// An array of functions for binary operators corresponding to the order of
+/// the instructions for the operators.
+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
+};
+
+/// An array of functions for binary operators allocation requests corresponding
+/// to the order of the instructions for the operators.
+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
+};
+
+/// An array of unary operator functions corresponding to the order of the
+/// instructions.
+const BcProgramUnary bc_program_unarys[] = {
+ bc_program_negate, bc_program_not,
+#if BC_ENABLE_EXTRA_MATH
+ bc_program_trunc,
+#endif // BC_ENABLE_EXTRA_MATH
+};
+
+/// A filename for when parsing expressions.
+const char bc_program_exprs_name[] = "<exprs>";
+
+/// A filename for when parsing stdin..
+const char bc_program_stdin_name[] = "<stdin>";
+
+/// A ready message for SIGINT catching.
+const char bc_program_ready_msg[] = "ready for more input\n";
+
+/// The length of the ready message.
+const size_t bc_program_ready_msg_len = sizeof(bc_program_ready_msg) - 1;
+
+/// A list of escape characters that a print statement should treat specially.
+const char bc_program_esc_chars[] = "ab\\efnqrt";
+
+/// A list of characters corresponding to the escape characters above.
+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..67bc3e16c3c2
--- /dev/null
+++ b/contrib/bc/src/dc.c
@@ -0,0 +1,63 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The main procedure of dc.
+ *
+ */
+
+#if DC_ENABLED
+
+#include <string.h>
+
+#include <dc.h>
+#include <vm.h>
+
+/**
+ * The main function for dc.
+ * @param argc The number of arguments.
+ * @param argv The arguments.
+ */
+void dc_main(int argc, char *argv[]) {
+
+ // All of these just set dc-specific items in BcVm.
+
+ 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);
+}
+#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..5c6950ba9698
--- /dev/null
+++ b/contrib/bc/src/dc_lex.c
@@ -0,0 +1,276 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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);
+}
+
+/**
+ * Processes a dc command that needs a register. This is where the
+ * extended-register extension is implemented.
+ * @param l The lexer.
+ */
+static void dc_lex_register(BcLex *l) {
+
+ // If extended register is enabled and the character is whitespace...
+ if (DC_X && isspace(l->buf[l->i - 1])) {
+
+ char c;
+
+ // Eat the whitespace.
+ bc_lex_whitespace(l);
+ c = l->buf[l->i];
+
+ // Check for a letter or underscore.
+ if (BC_ERR(!isalpha(c) && c != '_'))
+ bc_lex_verr(l, BC_ERR_PARSE_CHAR, c);
+
+ // Parse a normal identifier.
+ l->i += 1;
+ bc_lex_name(l);
+ }
+ else {
+
+ // I don't allow newlines because newlines are used for controlling when
+ // execution happens, and allowing newlines would just be complex.
+ if (BC_ERR(l->buf[l->i - 1] == '\n'))
+ bc_lex_verr(l, BC_ERR_PARSE_CHAR, l->buf[l->i - 1]);
+
+ // Set the lexer string and token.
+ bc_vec_popAll(&l->str);
+ bc_vec_pushByte(&l->str, (uchar) l->buf[l->i - 1]);
+ bc_vec_pushByte(&l->str, '\0');
+ l->t = BC_LEX_NAME;
+ }
+}
+
+/**
+ * Parses a dc string. Since dc's strings need to check for balanced brackets,
+ * we can't just parse bc and dc strings with different start and end
+ * characters. Oh, and dc strings need to check for escaped brackets.
+ * @param l The lexer.
+ */
+static void dc_lex_string(BcLex *l) {
+
+ size_t depth, nls, i;
+ char c;
+ bool got_more;
+
+ // Set the token and clear the string.
+ l->t = BC_LEX_STR;
+ bc_vec_popAll(&l->str);
+
+ do {
+
+ depth = 1;
+ nls = 0;
+ got_more = false;
+
+ assert(!l->is_stdin || l->buf == vm.buffer.v);
+
+ // This is the meat. As long as we don't run into the NUL byte, and we
+ // have "depth", which means we haven't completely balanced brackets
+ // yet, we continue eating the string.
+ for (i = l->i; (c = l->buf[i]) && depth; ++i) {
+
+ // Check for escaped brackets and set the depths as appropriate.
+ if (c == '\\') {
+ c = l->buf[++i];
+ if (!c) break;
+ }
+ else {
+ depth += (c == '[');
+ depth -= (c == ']');
+ }
+
+ // We want to adjust the line in the lexer as necessary.
+ nls += (c == '\n');
+
+ if (depth) bc_vec_push(&l->str, &c);
+ }
+
+ if (BC_ERR(c == '\0' && depth)) {
+ if (!vm.eof && l->is_stdin) got_more = bc_lex_readLine(l);
+ if (got_more) bc_vec_popAll(&l->str);
+ }
+
+ } while (got_more && depth);
+
+ // Obviously, if we didn't balance, that's an error.
+ 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;
+}
+
+/**
+ * Lexes a dc token. This is the dc implementation of BcLexNext.
+ * @param l The lexer.
+ */
+void dc_lex_token(BcLex *l) {
+
+ char c = l->buf[l->i++], c2;
+ size_t i;
+
+ // If the last token was a command that needs a register, we need to parse a
+ // register, so do so.
+ for (i = 0; i < dc_lex_regs_len; ++i) {
+
+ // If the token is a register token, take care of it and return.
+ if (l->last == dc_lex_regs[i]) {
+ dc_lex_register(l);
+ return;
+ }
+ }
+
+ // These lines are for tokens that easily correspond to one character. We
+ // just set the token.
+ if (c >= '"' && c <= '~' &&
+ (l->t = dc_lex_tokens[(c - '"')]) != BC_LEX_INVALID)
+ {
+ return;
+ }
+
+ // This is the workhorse of the lexer when more complicated things are
+ // needed.
+ switch (c) {
+
+ case '\0':
+ case '\n':
+ case '\t':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ {
+ bc_lex_commonTokens(l, c);
+ break;
+ }
+
+ // We don't have the ! command, so we always expect certain things
+ // after the exclamation point.
+ 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 the character after is a number, this dot is part of a number.
+ // Otherwise, it's the BSD dot (equivalent to last).
+ 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 'g':
+ {
+ c2 = l->buf[l->i];
+
+ if (c2 == 'l') l->t = BC_LEX_KW_LINE_LENGTH;
+ else if (c2 == 'z') l->t = BC_LEX_KW_LEADING_ZERO;
+ else bc_lex_invalidChar(l, c2);
+
+ l->i += 1;
+
+ 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..b9b5afb66c44
--- /dev/null
+++ b/contrib/bc/src/dc_parse.c
@@ -0,0 +1,321 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+/**
+ * Parses a register. The lexer should have already lexed the true name of the
+ * register, per extended registers and such.
+ * @param p The parser.
+ * @param var True if the parser is for a variable, false otherwise.
+ */
+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);
+}
+
+/**
+ * Parses a dc string.
+ * @param p The parser.
+ */
+static inline void dc_parse_string(BcParse *p) {
+ bc_parse_addString(p);
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parses a token that requires a memory operation, like load or store.
+ * @param p The parser.
+ * @param inst The instruction to push for the memory operation.
+ * @param name Whether the load or store is to a variable or array, and not to
+ * a global.
+ * @param store True if the operation is a store, false otherwise.
+ */
+static void dc_parse_mem(BcParse *p, uchar inst, bool name, bool store) {
+
+ // Push the instruction.
+ bc_parse_push(p, inst);
+
+ // Parse the register if necessary.
+ if (name) dc_parse_register(p, inst != BC_INST_ARRAY_ELEM);
+
+ // Stores use the bc assign infrastructure, but they need to do a swap
+ // first.
+ if (store) {
+ bc_parse_push(p, BC_INST_SWAP);
+ bc_parse_push(p, BC_INST_ASSIGN_NO_VAL);
+ }
+
+ bc_lex_next(&p->l);
+}
+
+/**
+ * Parses a conditional execution instruction.
+ * @param p The parser.
+ * @param inst The instruction for the condition.
+ */
+static void dc_parse_cond(BcParse *p, uchar inst) {
+
+ // Push the instruction for the condition and the conditional execution.
+ bc_parse_push(p, inst);
+ bc_parse_push(p, BC_INST_EXEC_COND);
+
+ // Parse the register.
+ dc_parse_register(p, true);
+
+ bc_lex_next(&p->l);
+
+ // If the next token is an else, parse the else.
+ if (p->l.t == BC_LEX_KW_ELSE) {
+ dc_parse_register(p, true);
+ bc_lex_next(&p->l);
+ }
+ // Otherwise, push a marker for no else.
+ else bc_parse_pushIndex(p, SIZE_MAX);
+}
+
+/**
+ * Parses a token for dc.
+ * @param p The parser.
+ * @param t The token to parse.
+ * @param flags The flags that say what is allowed or not.
+ */
+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:
+ {
+ // This tells us whether or not the neg is for a command or at the
+ // beginning of a number. If it's a command, push it. Otherwise,
+ // fallthrough and parse the number.
+ 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);
+
+ // Push the negative instruction if we fell through from above.
+ if (t == BC_LEX_NEG) bc_parse_push(p, BC_INST_NEG);
+ get_token = true;
+
+ break;
+ }
+
+ case BC_LEX_KW_READ:
+ {
+ // Make sure the read is not recursive.
+ 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_REG_STACK_LEVEL:
+ {
+ dc_parse_mem(p, BC_INST_REG_STACK_LEN, 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;
+ }
+
+ case BC_LEX_ARRAY_LENGTH:
+ {
+ // Need to push the array first, based on how length is implemented.
+ bc_parse_push(p, BC_INST_ARRAY);
+ dc_parse_register(p, false);
+
+ bc_parse_push(p, BC_INST_LENGTH);
+
+ get_token = true;
+
+ break;
+ }
+
+ default:
+ {
+ // All other tokens should be taken care of by the caller, or they
+ // actually *are* invalid.
+ 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 need_expr, have_expr = false;
+
+ need_expr = ((flags & BC_PARSE_NOREAD) != 0);
+
+ // dc can just keep parsing forever basically, unlike bc, which has to have
+ // a whole bunch of complicated nonsense because its language was horribly
+ // designed.
+
+ // While we don't have EOF...
+ while ((t = p->l.t) != BC_LEX_EOF) {
+
+ // Eat newline.
+ if (t == BC_LEX_NLINE) {
+ bc_lex_next(&p->l);
+ continue;
+ }
+
+ // Get the instruction that corresponds to the token.
+ inst = dc_parse_insts[t];
+
+ // If the instruction is invalid, that means we have to do some harder
+ // parsing. So if not invalid, just push the instruction; otherwise,
+ // parse the token.
+ 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 we don't have an expression and need one, barf. Otherwise, just push a
+ // BC_INST_POP_EXEC if we have EOF and BC_PARSE_NOCALL, which dc uses to
+ // indicate that it is executing a string.
+ if (BC_ERR(need_expr && !have_expr)) bc_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 we have EOF, someone called this function one too many times.
+ // Otherwise, parse.
+ 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;
+
+ // Need to reset if there was an error.
+ if (BC_SIG_EXC) 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..35a4647dfabf
--- /dev/null
+++ b/contrib/bc/src/file.c
@@ -0,0 +1,311 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Code for implementing buffered I/O on my own terms.
+ *
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif // _WIN32
+
+#include <file.h>
+#include <vm.h>
+
+/**
+ * Translates an integer into a string.
+ * @param val The value to translate.
+ * @param buf The return parameter.
+ */
+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;
+
+ // We need to make sure the entire thing is zeroed.
+ 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;
+
+ // Since buf2 is reversed, reverse it into buf.
+ for (i = 0; i < len; ++i) buf[i] = buf2[len - i - 1];
+}
+
+/**
+ * Output to the file directly.
+ * @param fd The file descriptor.
+ * @param buf The buffer of data to output.
+ * @param n The number of bytes to output.
+ * @return A status indicating error or success. We could have a fatal I/O
+ * error or EOF.
+ */
+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 the number of bytes written is less than intended...
+ while (bytes < n) {
+
+ // Write.
+ ssize_t written = write(fd, buf + bytes, n - bytes);
+
+ // Check for error and return, if any.
+ 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, BcFlushType type)
+{
+ BcStatus s;
+
+ // If there is stuff to output...
+ if (f->len) {
+
+#if BC_ENABLE_HISTORY
+
+ // If history is enabled...
+ if (BC_TTY) {
+
+ // If we have been told to save the extras, and there *are*
+ // extras...
+ if (f->buf[f->len - 1] != '\n' &&
+ (type == BC_FLUSH_SAVE_EXTRAS_CLEAR ||
+ type == BC_FLUSH_SAVE_EXTRAS_NO_CLEAR))
+ {
+ size_t i;
+
+ // Look for the last newline.
+ for (i = f->len - 2; i < f->len && f->buf[i] != '\n'; --i);
+
+ i += 1;
+
+ // Save the extras.
+ bc_vec_string(&vm.history.extras, f->len - i, f->buf + i);
+ }
+ // Else clear the extras if told to.
+ else if (type >= BC_FLUSH_NO_EXTRAS_CLEAR) {
+ bc_vec_popAll(&vm.history.extras);
+ }
+ }
+#endif // BC_ENABLE_HISTORY
+
+ // Actually output.
+ 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, BcFlushType type) {
+
+ BcStatus s = bc_file_flushErr(f, type);
+
+ // If we have an error...
+ if (BC_ERR(s)) {
+
+ // For EOF, set it and jump.
+ if (s == BC_STATUS_EOF) {
+ vm.status = (sig_atomic_t) s;
+ BC_JMP;
+ }
+ // Blow up on fatal error. Okay, not blow up, just quit.
+ else bc_vm_fatalError(BC_ERR_FATAL_IO_ERR);
+ }
+}
+
+void bc_file_write(BcFile *restrict f, BcFlushType type,
+ const char *buf, size_t n)
+{
+ // If we have enough to flush, do it.
+ if (n > f->cap - f->len) {
+ bc_file_flush(f, type);
+ assert(!f->len);
+ }
+
+ // If the output is large enough to flush by itself, just output it.
+ // Otherwise, put it into the buffer.
+ 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];
+
+ // This is a poor man's printf(). While I could look up algorithms to make
+ // it as fast as possible, and should when I write the standard library for
+ // a new language, for bc, outputting is not the bottleneck. So we cheese it
+ // for now.
+
+ // Find each percent sign.
+ while ((percent = strchr(ptr, '%')) != NULL) {
+
+ char c;
+
+ // If the percent sign is not where we are, write what's inbetween to
+ // the buffer.
+ if (percent != ptr) {
+ size_t len = (size_t) (percent - ptr);
+ bc_file_write(f, bc_flush_none, ptr, len);
+ }
+
+ c = percent[1];
+
+ // We only parse some format specifiers, the ones bc uses. If you add
+ // more, you need to make sure to add them here.
+ if (c == 'c') {
+
+ uchar uc = (uchar) va_arg(args, int);
+
+ bc_file_putchar(f, bc_flush_none, uc);
+ }
+ else if (c == 's') {
+
+ char *s = va_arg(args, char*);
+
+ bc_file_puts(f, bc_flush_none, s);
+ }
+#if BC_DEBUG_CODE
+ // We only print signed integers in debug code.
+ else if (c == 'd') {
+
+ int d = va_arg(args, int);
+
+ // Take care of negative. Let's not worry about overflow.
+ if (d < 0) {
+ bc_file_putchar(f, bc_flush_none, '-');
+ d = -d;
+ }
+
+ // Either print 0 or translate and print.
+ if (!d) bc_file_putchar(f, bc_flush_none, '0');
+ else {
+ bc_file_ultoa((unsigned long long) d, buf);
+ bc_file_puts(f, bc_flush_none, buf);
+ }
+ }
+#endif // BC_DEBUG_CODE
+ else {
+
+ unsigned long long ull;
+
+ // These are the ones that it expects from here. Fortunately, all of
+ // these are unsigned types, so they can use the same code, more or
+ // less.
+ 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);
+
+ // Either print 0 or translate and print.
+ if (!ull) bc_file_putchar(f, bc_flush_none, '0');
+ else {
+ bc_file_ultoa(ull, buf);
+ bc_file_puts(f, bc_flush_none, buf);
+ }
+ }
+
+ // Increment to the next spot after the specifier.
+ ptr = percent + 2 + (c == 'l' || c == 'z');
+ }
+
+ // If we get here, there are no more percent signs, so we just output
+ // whatever is left.
+ if (ptr[0]) bc_file_puts(f, bc_flush_none, ptr);
+}
+
+void bc_file_puts(BcFile *restrict f, BcFlushType type, const char *str) {
+ bc_file_write(f, type, str, strlen(str));
+}
+
+void bc_file_putchar(BcFile *restrict f, BcFlushType type, uchar c) {
+
+ if (f->len == f->cap) bc_file_flush(f, type);
+
+ assert(f->len < f->cap);
+
+ f->buf[f->len] = (char) c;
+ f->len += 1;
+}
+
+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, bc_flush_none);
+}
diff --git a/contrib/bc/src/history.c b/contrib/bc/src/history.c
new file mode 100644
index 000000000000..b5ba0758075c
--- /dev/null
+++ b/contrib/bc/src/history.c
@@ -0,0 +1,1765 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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 <ctype.h>
+
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifndef _WIN32
+#include <strings.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#endif // _WIN32
+
+#include <status.h>
+#include <vector.h>
+#include <history.h>
+#include <read.h>
+#include <file.h>
+#include <vm.h>
+
+#if BC_DEBUG_CODE
+
+/// A file for outputting to when debugging.
+BcFile bc_history_debug_fp;
+
+/// A buffer for the above file.
+char *bc_history_debug_buf;
+
+#endif // BC_DEBUG_CODE
+
+/**
+ * Checks if the code is a wide character.
+ * @param cp The codepoint to check.
+ * @return True if @a cp is a wide character, false otherwise.
+ */
+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;
+}
+
+/**
+ * Checks if the code is a combining character.
+ * @param cp The codepoint to check.
+ * @return True if @a cp is a combining character, false otherwise.
+ */
+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;
+}
+
+/**
+ * Gets the length of previous UTF8 character.
+ * @param buf The buffer of characters.
+ * @param pos The index into the buffer.
+ */
+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);
+}
+
+/**
+ * Converts UTF-8 to a Unicode code point.
+ * @param s The string.
+ * @param len The length of the string.
+ * @param cp An out parameter for the codepoint.
+ * @return The number of bytes eaten by the codepoint.
+ */
+static size_t bc_history_codePoint(const char *s, size_t len, uint32_t *cp) {
+
+ if (len) {
+
+ uchar byte = (uchar) s[0];
+
+ // This is literally the UTF-8 decoding algorithm. Look that up if you
+ // don't understand this.
+
+ 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;
+}
+
+/**
+ * Gets the length of next grapheme.
+ * @param buf The buffer.
+ * @param buf_len The length of the buffer.
+ * @param pos The index into the buffer.
+ * @param col_len An out parameter for the length of the grapheme on screen.
+ * @return The number of bytes in the 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)) {
+
+ BC_UNREACHABLE
+
+ if (col_len != NULL) *col_len = 0;
+
+ return 0;
+ }
+
+ // Store the width of the character on screen.
+ if (col_len != NULL) *col_len = bc_history_wchar(cp) ? 2 : 1;
+
+ pos += len;
+
+ // Find the first non-combining character.
+ 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;
+}
+
+/**
+ * Gets the length of previous grapheme.
+ * @param buf The buffer.
+ * @param pos The index into the buffer.
+ * @return The number of bytes in the grapheme.
+ */
+static size_t bc_history_prevLen(const char *buf, size_t pos) {
+
+ size_t end = pos;
+
+ // Find the first non-combining character.
+ while (pos > 0) {
+
+ uint32_t cp;
+ size_t len = bc_history_prevCharLen(buf, pos);
+
+ pos -= len;
+ bc_history_codePoint(buf + pos, len, &cp);
+
+ // The original linenoise-mob had an extra parameter col_len, like
+ // bc_history_nextLen(), which, if not NULL, was set in this if
+ // statement. However, we always passed NULL, so just skip that.
+ if (!bc_history_comboChar(cp)) return end - pos;
+ }
+
+ BC_UNREACHABLE
+
+ return 0;
+}
+
+/**
+ * Reads @a n characters from stdin.
+ * @param buf The buffer to read into. The caller is responsible for making
+ * sure this is big enough for @a n.
+ * @param n The number of characters to read.
+ * @return The number of characters read or less than 0 on error.
+ */
+static ssize_t bc_history_read(char *buf, size_t n) {
+
+ ssize_t ret;
+
+ BC_SIG_LOCK;
+
+#ifndef _WIN32
+
+ do {
+ // We don't care about being interrupted.
+ ret = read(STDIN_FILENO, buf, n);
+ } while (ret == EINTR);
+
+#else // _WIN32
+
+ bool good;
+ DWORD read;
+ HANDLE hn = GetStdHandle(STD_INPUT_HANDLE);
+
+ good = ReadConsole(hn, buf, (DWORD) n, &read, NULL);
+
+ ret = (read != n) ? -1 : 1;
+
+#endif // _WIN32
+
+ BC_SIG_UNLOCK;
+
+ return ret;
+}
+
+/**
+ * Reads a Unicode code point into a buffer.
+ * @param buf The buffer to read into.
+ * @param buf_len The length of the buffer.
+ * @param cp An out parameter for the codepoint.
+ * @param nread An out parameter for the number of bytes read.
+ * @return BC_STATUS_EOF or BC_STATUS_SUCCESS.
+ */
+static BcStatus bc_history_readCode(char *buf, size_t buf_len,
+ uint32_t *cp, size_t *nread)
+{
+ ssize_t n;
+
+ assert(buf_len >= 1);
+
+ // Read a byte.
+ n = bc_history_read(buf, 1);
+ if (BC_ERR(n <= 0)) goto err;
+
+ // Get the byte.
+ uchar byte = ((uchar*) buf)[0];
+
+ // Once again, this is the UTF-8 decoding algorithm, but it has reads
+ // instead of actual decoding.
+ 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;
+ }
+ }
+
+ // Convert to the codepoint.
+ *nread = bc_history_codePoint(buf, buf_len, cp);
+
+ return BC_STATUS_SUCCESS;
+
+err:
+ // If we get here, we either had a fatal error of EOF.
+ if (BC_ERR(n < 0)) bc_vm_fatalError(BC_ERR_FATAL_IO_ERR);
+ else *nread = (size_t) n;
+ return BC_STATUS_EOF;
+}
+
+/**
+ * Gets the column length from beginning of buffer to current byte position.
+ * @param buf The buffer.
+ * @param buf_len The length of the buffer.
+ * @param pos The index into the buffer.
+ * @return The number of columns between the beginning of @a buffer to
+ * @a pos.
+ */
+static size_t bc_history_colPos(const char *buf, size_t buf_len, size_t pos) {
+
+ size_t ret = 0, off = 0;
+
+ // While we haven't reached the offset, get the length of the next grapheme.
+ while (off < pos && off < buf_len) {
+
+ size_t col_len, len;
+
+ len = bc_history_nextLen(buf, buf_len, off, &col_len);
+
+ off += len;
+ ret += col_len;
+ }
+
+ return ret;
+}
+
+/**
+ * Returns true if the terminal name is in the list of terminals we know are
+ * not able to understand basic escape sequences.
+ * @return True if the terminal is a bad terminal.
+ */
+static inline bool bc_history_isBadTerm(void) {
+
+ size_t i;
+ bool ret = false;
+ char *term = bc_vm_getenv("TERM");
+
+ if (term == NULL) return false;
+
+ for (i = 0; !ret && bc_history_bad_terms[i]; ++i)
+ ret = (!strcasecmp(term, bc_history_bad_terms[i]));
+
+ bc_vm_getenvFree(term);
+
+ return ret;
+}
+
+/**
+ * Enables raw mode (1960's black magic).
+ * @param h The history data.
+ */
+static void bc_history_enableRaw(BcHistory *h) {
+
+ // I don't do anything for Windows because in Windows, you set their
+ // equivalent of raw mode and leave it, so I do it in bc_history_init().
+
+#ifndef _WIN32
+ 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_fatalError(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_fatalError(BC_ERR_FATAL_IO_ERR);
+#endif // _WIN32
+
+ h->rawMode = true;
+}
+
+/**
+ * Disables raw mode.
+ * @param h The history data.
+ */
+static void bc_history_disableRaw(BcHistory *h) {
+
+ sig_atomic_t lock;
+
+ if (!h->rawMode) return;
+
+ BC_SIG_TRYLOCK(lock);
+
+#ifndef _WIN32
+ if (BC_ERR(tcsetattr(STDIN_FILENO, TCSAFLUSH, &h->orig_termios) != -1))
+ h->rawMode = false;
+#endif // _WIN32
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+/**
+ * Uses 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.
+ * @return The horizontal cursor position.
+ */
+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, bc_flush_none, "\x1b[6n", 4);
+ bc_file_flush(&vm.fout, bc_flush_none);
+
+ // Read the response: ESC [ rows ; cols R.
+ for (i = 0; i < sizeof(buf) - 1; ++i) {
+ if (bc_history_read(buf + i, 1) != 1 || buf[i] == 'R') break;
+ }
+
+ buf[i] = '\0';
+
+ // This is basically an error; we didn't get what we were expecting.
+ if (BC_ERR(buf[0] != BC_ACTION_ESC || buf[1] != '[')) return SIZE_MAX;
+
+ // Parse the rows.
+ ptr = buf + 2;
+ rows = strtoul(ptr, &ptr2, 10);
+
+ // Here we also didn't get what we were expecting.
+ if (BC_ERR(!rows || ptr2[0] != ';')) return SIZE_MAX;
+
+ // Parse the columns.
+ ptr = ptr2 + 1;
+ cols = strtoul(ptr, NULL, 10);
+
+ if (BC_ERR(!cols)) return SIZE_MAX;
+
+ return cols <= UINT16_MAX ? cols : 0;
+}
+
+/**
+ * Tries to get the number of columns in the current terminal, or assume 80
+ * if it fails.
+ * @return The number of columns in the terminal.
+ */
+static size_t bc_history_columns(void) {
+
+#ifndef _WIN32
+
+ 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, bc_flush_none, "\x1b[999C", 6);
+ bc_file_flush(&vm.fout, bc_flush_none);
+ cols = bc_history_cursorPos();
+ if (BC_ERR(cols == SIZE_MAX)) return BC_HIST_DEF_COLS;
+
+ // Restore position.
+ if (cols > start) {
+ bc_file_printf(&vm.fout, "\x1b[%zuD", cols - start);
+ bc_file_flush(&vm.fout, bc_flush_none);
+ }
+
+ return cols;
+ }
+
+ return ws.ws_col;
+
+#else // _WIN32
+
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ return 80;
+
+ return ((size_t) (csbi.srWindow.Right)) - csbi.srWindow.Left + 1;
+
+#endif // _WIN32
+}
+
+/**
+ * Gets the column length of prompt text. This is probably unnecessary because
+ * the prompts that I use are ASCII, but I kept it just in case.
+ * @param prompt The prompt.
+ * @param plen The length of the prompt.
+ * @return The column length of the prompt.
+ */
+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;
+
+ // The original linenoise-mob checked for ANSI escapes here on the prompt. I
+ // know the prompts do not have ANSI escapes. I deleted the code.
+ while (off < plen) buf[buf_len++] = prompt[off++];
+
+ return bc_history_colPos(buf, buf_len, buf_len);
+}
+
+/**
+ * Rewrites the currently edited line accordingly to the buffer content,
+ * cursor position, and number of columns of the terminal.
+ * @param h The history data.
+ */
+static void bc_history_refresh(BcHistory *h) {
+
+ char* buf = h->buf.v;
+ size_t colpos, len = BC_HIST_BUF_LEN(h), pos = h->pos, extras_len = 0;
+
+ bc_file_flush(&vm.fout, bc_flush_none);
+
+ // Get to the prompt column position from the left.
+ 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;
+ }
+
+ // Get to the prompt column position from the right.
+ while (h->pcol + bc_history_colPos(buf, len, len) > h->cols)
+ len -= bc_history_prevLen(buf, len);
+
+ // Cursor to left edge.
+ bc_file_write(&vm.fout, bc_flush_none, "\r", 1);
+
+ // Take the extra stuff into account. This is where history makes sure to
+ // preserve stuff that was printed without a newline.
+ if (h->extras.len > 1) {
+
+ extras_len = h->extras.len - 1;
+
+ bc_vec_grow(&h->buf, extras_len);
+
+ len += extras_len;
+ pos += extras_len;
+
+ bc_file_write(&vm.fout, bc_flush_none, h->extras.v, extras_len);
+ }
+
+ // Write the prompt, if desired.
+ if (BC_PROMPT) bc_file_write(&vm.fout, bc_flush_none, h->prompt, h->plen);
+
+ bc_file_write(&vm.fout, bc_flush_none, h->buf.v, len - extras_len);
+
+ // Erase to right.
+ bc_file_write(&vm.fout, bc_flush_none, "\x1b[0K", 4);
+
+ // We need to be sure to grow this.
+ if (pos >= h->buf.len - extras_len)
+ bc_vec_grow(&h->buf, pos + extras_len);
+
+ // Move cursor to original position.
+ colpos = bc_history_colPos(h->buf.v, len - extras_len, pos) + h->pcol;
+
+ // Set the cursor position again.
+ if (colpos) bc_file_printf(&vm.fout, "\r\x1b[%zuC", colpos);
+
+ bc_file_flush(&vm.fout, bc_flush_none);
+}
+
+/**
+ * Inserts the character(s) 'c' at cursor current position.
+ * @param h The history data.
+ * @param cbuf The character buffer to copy from.
+ * @param clen The number of characters to copy.
+ */
+static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen)
+{
+ bc_vec_grow(&h->buf, clen);
+
+ // If we are at the end of the line...
+ if (h->pos == BC_HIST_BUF_LEN(h)) {
+
+ size_t colpos = 0, len;
+
+ // Copy into the buffer.
+ memcpy(bc_vec_item(&h->buf, h->pos), cbuf, clen);
+
+ // Adjust the buffer.
+ h->pos += clen;
+ h->buf.len += clen - 1;
+ bc_vec_pushByte(&h->buf, '\0');
+
+ // Set the length and column position.
+ len = BC_HIST_BUF_LEN(h) + h->extras.len - 1;
+ colpos = bc_history_promptColLen(h->prompt, h->plen);
+ colpos += bc_history_colPos(h->buf.v, len, len);
+
+ // Do we have the trivial case?
+ if (colpos < h->cols) {
+
+ // Avoid a full update of the line in the trivial case.
+ bc_file_write(&vm.fout, bc_flush_none, cbuf, clen);
+ bc_file_flush(&vm.fout, bc_flush_none);
+ }
+ else bc_history_refresh(h);
+ }
+ else {
+
+ // Amount that we need to move.
+ size_t amt = BC_HIST_BUF_LEN(h) - h->pos;
+
+ // Move the stuff.
+ memmove(h->buf.v + h->pos + clen, h->buf.v + h->pos, amt);
+ memcpy(h->buf.v + h->pos, cbuf, clen);
+
+ // Adjust the buffer.
+ h->pos += clen;
+ h->buf.len += clen;
+ h->buf.v[BC_HIST_BUF_LEN(h)] = '\0';
+
+ bc_history_refresh(h);
+ }
+}
+
+/**
+ * Moves the cursor to the left.
+ * @param h The history data.
+ */
+static void bc_history_edit_left(BcHistory *h) {
+
+ // Stop at the left end.
+ if (h->pos <= 0) return;
+
+ h->pos -= bc_history_prevLen(h->buf.v, h->pos);
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Moves the cursor to the right.
+ * @param h The history data.
+*/
+static void bc_history_edit_right(BcHistory *h) {
+
+ // Stop at the right end.
+ 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);
+}
+
+/**
+ * Moves the cursor to the end of the current word.
+ * @param h The history data.
+ */
+static void bc_history_edit_wordEnd(BcHistory *h) {
+
+ size_t len = BC_HIST_BUF_LEN(h);
+
+ // Don't overflow.
+ if (!len || h->pos >= len) return;
+
+ // Find the word, then find the end of it.
+ 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);
+}
+
+/**
+ * Moves the cursor to the start of the current word.
+ * @param h The history data.
+ */
+static void bc_history_edit_wordStart(BcHistory *h) {
+
+ size_t len = BC_HIST_BUF_LEN(h);
+
+ // Stop with no data.
+ if (!len) return;
+
+ // Find the word, the find the beginning of the word.
+ 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);
+}
+
+/**
+ * Moves the cursor to the start of the line.
+ * @param h The history data.
+ */
+static void bc_history_edit_home(BcHistory *h) {
+
+ // Stop at the beginning.
+ if (!h->pos) return;
+
+ h->pos = 0;
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Moves the cursor to the end of the line.
+ * @param h The history data.
+ */
+static void bc_history_edit_end(BcHistory *h) {
+
+ // Stop at the end of the line.
+ if (h->pos == BC_HIST_BUF_LEN(h)) return;
+
+ h->pos = BC_HIST_BUF_LEN(h);
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Substitutes the currently edited line with the next or previous history
+ * entry as specified by 'dir' (direction).
+ * @param h The history data.
+ * @param dir The direction to substitute; true means previous, false next.
+ */
+static void bc_history_edit_next(BcHistory *h, bool dir) {
+
+ const char *dup, *str;
+
+ // Stop if there is no history.
+ if (h->history.len <= 1) return;
+
+ BC_SIG_LOCK;
+
+ // Duplicate the buffer.
+ if (h->buf.v[0]) dup = bc_vm_strdup(h->buf.v);
+ else dup = "";
+
+ // 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);
+
+ // Se the index appropriately at the ends.
+ if (h->idx == SIZE_MAX) {
+ h->idx = 0;
+ return;
+ }
+ else if (h->idx >= h->history.len) {
+ h->idx = h->history.len - 1;
+ return;
+ }
+
+ // Get the string.
+ 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);
+
+ // Set the position at the end.
+ h->pos = BC_HIST_BUF_LEN(h);
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Deletes the character at the right of the cursor without altering the cursor
+ * position. Basically, this is what happens with the "Delete" keyboard key.
+ * @param h The history data.
+ */
+static void bc_history_edit_delete(BcHistory *h) {
+
+ size_t chlen, len = BC_HIST_BUF_LEN(h);
+
+ // If there is no character, skip.
+ if (!len || h->pos >= len) return;
+
+ // Get the length of the character.
+ chlen = bc_history_nextLen(h->buf.v, len, h->pos, NULL);
+
+ // Move characters after it into its place.
+ memmove(h->buf.v + h->pos, h->buf.v + h->pos + chlen, len - h->pos - chlen);
+
+ // Make the buffer valid again.
+ h->buf.len -= chlen;
+ h->buf.v[BC_HIST_BUF_LEN(h)] = '\0';
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Deletes the character to the left of the cursor and moves the cursor back one
+ * space. Basically, this is what happens with the "Backspace" keyboard key.
+ * @param h The history data.
+ */
+static void bc_history_edit_backspace(BcHistory *h) {
+
+ size_t chlen, len = BC_HIST_BUF_LEN(h);
+
+ // If there are no characters, skip.
+ if (!h->pos || !len) return;
+
+ // Get the length of the previous character.
+ chlen = bc_history_prevLen(h->buf.v, h->pos);
+
+ // Move everything back one.
+ memmove(h->buf.v + h->pos - chlen, h->buf.v + h->pos, len - h->pos);
+
+ // Make the buffer valid again.
+ h->pos -= chlen;
+ h->buf.len -= chlen;
+ h->buf.v[BC_HIST_BUF_LEN(h)] = '\0';
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Deletes the previous word, maintaining the cursor at the start of the
+ * current word.
+ * @param h The history data.
+ */
+static void bc_history_edit_deletePrevWord(BcHistory *h) {
+
+ size_t diff, old_pos = h->pos;
+
+ // If at the beginning of the line, skip.
+ if (!old_pos) return;
+
+ // Find the word, then the beginning of the word.
+ while (h->pos > 0 && isspace(h->buf.v[h->pos - 1])) --h->pos;
+ while (h->pos > 0 && !isspace(h->buf.v[h->pos - 1])) --h->pos;
+
+ // Get the difference in position.
+ diff = old_pos - h->pos;
+
+ // Move the data back.
+ memmove(h->buf.v + h->pos, h->buf.v + old_pos,
+ BC_HIST_BUF_LEN(h) - old_pos + 1);
+
+ // Make the buffer valid again.
+ h->buf.len -= diff;
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Deletes the next word, maintaining the cursor at the same position.
+ * @param h The history data.
+ */
+static void bc_history_edit_deleteNextWord(BcHistory *h) {
+
+ size_t next_end = h->pos, len = BC_HIST_BUF_LEN(h);
+
+ // If at the end of the line, skip.
+ if (next_end == len) return;
+
+ // Find the word, then the end of the word.
+ while (next_end < len && isspace(h->buf.v[next_end])) ++next_end;
+ while (next_end < len && !isspace(h->buf.v[next_end])) ++next_end;
+
+ // Move the stuff into position.
+ memmove(h->buf.v + h->pos, h->buf.v + next_end, len - next_end);
+
+ // Make the buffer valid again.
+ h->buf.len -= next_end - h->pos;
+
+ bc_history_refresh(h);
+}
+
+/**
+ * Swaps two characters, the one under the cursor and the one to the left.
+ * @param h The history data.
+ */
+static void bc_history_swap(BcHistory *h) {
+
+ size_t pcl, ncl;
+ char auxb[5];
+
+ // Get the length of the previous and next characters.
+ pcl = bc_history_prevLen(h->buf.v, h->pos);
+ ncl = bc_history_nextLen(h->buf.v, BC_HIST_BUF_LEN(h), h->pos, NULL);
+
+ // To perform a swap we need:
+ // * Nonzero char length to the left.
+ // * To not be at the end of the line.
+ if (pcl && h->pos != BC_HIST_BUF_LEN(h) && pcl < 5 && ncl < 5) {
+
+ // Swap.
+ 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);
+
+ // Reset the position.
+ h->pos += ((~pcl) + 1) + ncl;
+
+ bc_history_refresh(h);
+ }
+}
+
+/**
+ * Raises the specified signal. This is a convenience function.
+ * @param h The history data.
+ * @param sig The signal to raise.
+ */
+static void bc_history_raise(BcHistory *h, int sig) {
+
+ // We really don't want to be in raw mode when longjmp()'s are flying.
+ bc_history_disableRaw(h);
+ raise(sig);
+}
+
+/**
+ * Handles escape sequences. This function will make sense if you know VT100
+ * escape codes; otherwise, it will be confusing.
+ * @param h The history data.
+ */
+static void bc_history_escape(BcHistory *h) {
+
+ char c, seq[3];
+
+ // Read a character into seq.
+ 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 {
+
+ // Read a character into seq.
+ if (BC_ERR(BC_HIST_READ(seq + 1, 1)))
+ bc_vm_fatalError(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_fatalError(BC_ERR_FATAL_IO_ERR);
+
+ if (seq[2] == '~' && c == '3') bc_history_edit_delete(h);
+ else if(seq[2] == ';') {
+
+ // Read two characters into seq.
+ if (BC_ERR(BC_HIST_READ(seq, 2)))
+ bc_vm_fatalError(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 {
+
+ 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;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Adds a line to the history.
+ * @param h The history data.
+ * @param line The line to add.
+ */
+static void bc_history_add(BcHistory *h, char *line) {
+
+ // If there is something already there...
+ if (h->history.len) {
+
+ // Get the previous.
+ char *s = *((char**) bc_vec_item_rev(&h->history, 0));
+
+ // Check for, and discard, duplicates.
+ if (!strcmp(s, line)) {
+
+ BC_SIG_LOCK;
+
+ free(line);
+
+ BC_SIG_UNLOCK;
+
+ return;
+ }
+ }
+
+ bc_vec_push(&h->history, &line);
+}
+
+/**
+ * Adds an empty line to the history. This is separate from bc_history_add()
+ * because we don't want it allocating.
+ * @param h The history data.
+ */
+static void bc_history_add_empty(BcHistory *h) {
+
+ const char *line = "";
+
+ // If there is something already there...
+ if (h->history.len) {
+
+ // Get the previous.
+ char *s = *((char**) bc_vec_item_rev(&h->history, 0));
+
+ // Check for, and discard, duplicates.
+ if (!s[0]) return;
+ }
+
+ bc_vec_push(&h->history, &line);
+}
+
+/**
+ * Resets the history state to nothing.
+ * @param h The history data.
+ */
+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);
+}
+
+/**
+ * Prints a control character.
+ * @param h The history data.
+ * @param c The control character to print.
+ */
+static void bc_history_printCtrl(BcHistory *h, unsigned int c) {
+
+ char str[3] = "^A";
+ const char newline[2] = "\n";
+
+ // Set the correct character.
+ str[1] = (char) (c + 'A' - BC_ACTION_CTRL_A);
+
+ // Concatenate the string.
+ bc_vec_concat(&h->buf, str);
+
+ bc_history_refresh(h);
+
+ // Pop the string.
+ bc_vec_npop(&h->buf, sizeof(str));
+ bc_vec_pushByte(&h->buf, '\0');
+
+#ifndef _WIN32
+ if (c != BC_ACTION_CTRL_C && c != BC_ACTION_CTRL_D)
+#endif // _WIN32
+ {
+ // We sometimes want to print a newline; for the times we don't; it's
+ // because newlines are taken care of elsewhere.
+ bc_file_write(&vm.fout, bc_flush_none, newline, sizeof(newline) - 1);
+ bc_history_refresh(h);
+ }
+}
+
+/**
+ * Edits a line of history. 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().
+ * @param h The history data.
+ * @param prompt The prompt.
+ * @return BC_STATUS_SUCCESS or BC_STATUS_EOF.
+ */
+static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
+
+ bc_history_reset(h);
+
+ // Don't write the saved output the first time. This is because it has
+ // already been written to output. In other words, don't uncomment the
+ // line below or add anything like it.
+ // bc_file_write(&vm.fout, bc_flush_none, h->extras.v, h->extras.len - 1);
+
+ // Write the prompt if desired.
+ if (BC_PROMPT) {
+
+ h->prompt = prompt;
+ h->plen = strlen(prompt);
+ h->pcol = bc_history_promptColLen(prompt, h->plen);
+
+ bc_file_write(&vm.fout, bc_flush_none, prompt, h->plen);
+ bc_file_flush(&vm.fout, bc_flush_none);
+ }
+
+ // This is the input loop.
+ for (;;) {
+
+ BcStatus s;
+ char cbuf[32];
+ unsigned int c = 0;
+ size_t nread = 0;
+
+ // Read a code.
+ 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:
+ {
+ // Return the line.
+ bc_vec_pop(&h->history);
+ return s;
+ }
+
+ case BC_ACTION_TAB:
+ {
+ // My tab handling is dumb; it just prints 8 spaces every time.
+ memcpy(cbuf, bc_history_tab, bc_history_tab_len + 1);
+ bc_history_edit_insert(h, cbuf, bc_history_tab_len);
+ break;
+ }
+
+#ifndef _WIN32
+ case BC_ACTION_CTRL_C:
+ {
+ bc_history_printCtrl(h, c);
+
+ // Quit if the user wants it.
+ if (!BC_SIGINT) {
+ vm.status = BC_STATUS_QUIT;
+ BC_JMP;
+ }
+
+ // Print the ready message.
+ bc_file_write(&vm.fout, bc_flush_none, vm.sigmsg, vm.siglen);
+ bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg,
+ bc_program_ready_msg_len);
+ bc_history_reset(h);
+ bc_history_refresh(h);
+
+ break;
+ }
+#endif // _WIN32
+
+ case BC_ACTION_BACKSPACE:
+ case BC_ACTION_CTRL_H:
+ {
+ bc_history_edit_backspace(h);
+ break;
+ }
+
+#ifndef _WIN32
+ // Act as end-of-file.
+ case BC_ACTION_CTRL_D:
+ {
+ bc_history_printCtrl(h, c);
+ return BC_STATUS_EOF;
+ }
+#endif // _WIN32
+
+ // 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, bc_flush_none, "\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 we have a control character, print it and raise signals as
+ // needed.
+ if ((c >= BC_ACTION_CTRL_A && c <= BC_ACTION_CTRL_Z) ||
+ c == BC_ACTION_CTRL_BSLASH)
+ {
+ bc_history_printCtrl(h, c);
+#ifndef _WIN32
+ if (c == BC_ACTION_CTRL_Z) bc_history_raise(h, SIGTSTP);
+ if (c == BC_ACTION_CTRL_S) bc_history_raise(h, SIGSTOP);
+ if (c == BC_ACTION_CTRL_BSLASH)
+ bc_history_raise(h, SIGQUIT);
+#else // _WIN32
+ vm.status = BC_STATUS_QUIT;
+ BC_JMP;
+#endif // _WIN32
+ }
+ // Otherwise, just insert.
+ else bc_history_edit_insert(h, cbuf, nread);
+ break;
+ }
+ }
+ }
+
+ return BC_STATUS_SUCCESS;
+}
+
+/**
+ * Returns true if stdin has more data. This is for multi-line pasting, and it
+ * does not work on Windows.
+ * @param h The history data.
+ */
+static inline bool bc_history_stdinHasData(BcHistory *h) {
+#ifndef _WIN32
+ int n;
+ return pselect(1, &h->rdset, NULL, NULL, &h->ts, &h->sigmask) > 0 ||
+ (ioctl(STDIN_FILENO, FIONREAD, &n) >= 0 && n > 0);
+#else // _WIN32
+ return false;
+#endif // _WIN32
+}
+
+BcStatus bc_history_line(BcHistory *h, BcVec *vec, const char *prompt) {
+
+ BcStatus s;
+ char* line;
+
+ assert(vm.fout.len == 0);
+
+ bc_history_enableRaw(h);
+
+ do {
+
+ // Do the edit.
+ s = bc_history_edit(h, prompt);
+
+ // Print a newline and flush.
+ bc_file_write(&vm.fout, bc_flush_none, "\n", 1);
+ bc_file_flush(&vm.fout, bc_flush_none);
+
+ // If we actually have data...
+ if (h->buf.v[0]) {
+
+ BC_SIG_LOCK;
+
+ // Duplicate it.
+ line = bc_vm_strdup(h->buf.v);
+
+ BC_SIG_UNLOCK;
+
+ // Store it.
+ bc_history_add(h, line);
+ }
+ // Add an empty string.
+ else bc_history_add_empty(h);
+
+ // Concatenate the line to the return vector.
+ bc_vec_concat(vec, h->buf.v);
+ bc_vec_concat(vec, "\n");
+
+ } while (!s && bc_history_stdinHasData(h));
+
+ assert(!s || s == BC_STATUS_EOF);
+
+ bc_history_disableRaw(h);
+
+ return s;
+}
+
+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) {
+
+#ifdef _WIN32
+ HANDLE out, in;
+#endif // _WIN32
+
+ BC_SIG_ASSERT_LOCKED;
+
+ h->rawMode = false;
+ h->badTerm = bc_history_isBadTerm();
+
+#ifdef _WIN32
+
+ h->orig_in = 0;
+ h->orig_out = 0;
+
+ in = GetStdHandle(STD_INPUT_HANDLE);
+ out = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ if (!h->badTerm) {
+ SetConsoleCP(CP_UTF8);
+ SetConsoleOutputCP(CP_UTF8);
+ if (!GetConsoleMode(in, &h->orig_in) ||
+ !GetConsoleMode(out, &h->orig_out))
+ {
+ h->badTerm = true;
+ return;
+ }
+ else {
+ DWORD reqOut = ENABLE_VIRTUAL_TERMINAL_PROCESSING |
+ DISABLE_NEWLINE_AUTO_RETURN;
+ DWORD reqIn = ENABLE_VIRTUAL_TERMINAL_INPUT;
+ if (!SetConsoleMode(in, h->orig_in | reqIn) ||
+ !SetConsoleMode(out, h->orig_out | reqOut))
+ {
+ h->badTerm = true;
+ }
+ }
+ }
+#endif // _WIN32
+
+ bc_vec_init(&h->buf, sizeof(char), BC_DTOR_NONE);
+ bc_vec_init(&h->history, sizeof(char*), BC_DTOR_HISTORY_STRING);
+ bc_vec_init(&h->extras, sizeof(char), BC_DTOR_NONE);
+
+#ifndef _WIN32
+ 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);
+#endif // _WIN32
+}
+
+void bc_history_free(BcHistory *h) {
+ BC_SIG_ASSERT_LOCKED;
+#ifndef _WIN32
+ bc_history_disableRaw(h);
+#else // _WIN32
+ SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), h->orig_in);
+ SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), h->orig_out);
+#endif // _WIN32
+#ifndef NDEBUG
+ bc_vec_free(&h->buf);
+ bc_vec_free(&h->history);
+ bc_vec_free(&h->extras);
+#endif // NDEBUG
+}
+
+#if BC_DEBUG_CODE
+
+/**
+ * Prints scan codes. This special mode is used by bc history in order to print
+ * scan codes on screen for debugging / development purposes.
+ * @param h The history data.
+ */
+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_flush_none);
+ bc_file_flush(&vm.fout, bc_flush_none);
+ }
+
+ 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..8532ebc66d7d
--- /dev/null
+++ b/contrib/bc/src/lang.c
@@ -0,0 +1,345 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Code to manipulate data structures in programs.
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lang.h>
+#include <program.h>
+#include <vm.h>
+
+void bc_const_free(void *constant) {
+
+ BcConst *c = constant;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(c->val != NULL);
+
+ bc_num_free(&c->num);
+}
+
+#if BC_ENABLED
+void bc_func_insert(BcFunc *f, BcProgram *p, char *name,
+ BcType type, size_t line)
+{
+ BcAuto a;
+ size_t i, idx;
+
+ // The function must *always* be valid.
+ assert(f != NULL);
+
+ // Get the index of the variable.
+ idx = bc_program_search(p, name, type == BC_TYPE_VAR);
+
+ // Search through all of the other autos/parameters.
+ for (i = 0; i < f->autos.len; ++i) {
+
+ // Get the auto.
+ BcAuto *aptr = bc_vec_item(&f->autos, i);
+
+ // If they match, barf.
+ if (BC_ERR(idx == aptr->idx && type == aptr->type)) {
+
+ const char *array = type == BC_TYPE_ARRAY ? "[]" : "";
+
+ bc_error(BC_ERR_PARSE_DUP_LOCAL, line, name, array);
+ }
+ }
+
+ // Set the auto.
+ a.idx = idx;
+ a.type = type;
+
+ // Push it.
+ 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), BC_DTOR_NONE);
+
+ bc_vec_init(&f->consts, sizeof(BcConst), BC_DTOR_CONST);
+
+ bc_vec_init(&f->strs, sizeof(char*), BC_DTOR_NONE);
+
+#if BC_ENABLED
+
+ // Only bc needs these things.
+ if (BC_IS_BC) {
+
+ bc_vec_init(&f->autos, sizeof(BcAuto), BC_DTOR_NONE);
+ bc_vec_init(&f->labels, sizeof(size_t), BC_DTOR_NONE);
+
+ 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_popAll(&f->code);
+
+ bc_vec_popAll(&f->consts);
+
+ bc_vec_popAll(&f->strs);
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+
+ bc_vec_popAll(&f->autos);
+ bc_vec_popAll(&f->labels);
+
+ f->nparams = 0;
+ f->voidfn = false;
+ }
+#endif // BC_ENABLED
+}
+
+#ifndef NDEBUG
+void bc_func_free(void *func) {
+
+ BcFunc *f = (BcFunc*) func;
+
+ BC_SIG_ASSERT_LOCKED;
+ assert(f != NULL);
+
+ bc_vec_free(&f->code);
+
+ bc_vec_free(&f->consts);
+
+ bc_vec_free(&f->strs);
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+
+ bc_vec_free(&f->autos);
+ bc_vec_free(&f->labels);
+ }
+#endif // BC_ENABLED
+}
+#endif // NDEBUG
+
+void bc_array_init(BcVec *a, bool nums) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ // Set the proper vector.
+ if (nums) bc_vec_init(a, sizeof(BcNum), BC_DTOR_NUM);
+ else bc_vec_init(a, sizeof(BcVec), BC_DTOR_VEC);
+
+ // We always want at least one item in the array.
+ 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);
+
+ // Make sure to destroy everything currently in d. This will put a lot of
+ // temps on the reuse list, so allocating later is not going to be as
+ // expensive as it seems. Also, it makes it easier to copy numbers that are
+ // strings.
+ bc_vec_popAll(d);
+
+ // Preexpand.
+ bc_vec_expand(d, s->cap);
+ d->len = s->len;
+
+ for (i = 0; i < s->len; ++i) {
+
+ BcNum *dnum, *snum;
+
+ dnum = bc_vec_item(d, i);
+ snum = bc_vec_item(s, i);
+
+ // We have to create a copy of the number as well.
+ if (BC_PROG_STR(snum)) memcpy(dnum, snum, sizeof(BcNum));
+ else 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 this is true, then we have a num array.
+ if (a->size == sizeof(BcNum) && a->dtor == BC_DTOR_NUM) {
+
+ // Initialize numbers until we reach the target.
+ while (len > a->len) {
+ BcNum *n = bc_vec_pushEmpty(a);
+ bc_num_init(n, BC_NUM_DEF_SIZE);
+ }
+ }
+ else {
+
+ assert(a->size == sizeof(BcVec) && a->dtor == BC_DTOR_VEC);
+
+ // Recursively initialize arrays until we reach the target. Having the
+ // second argument of bc_array_init() be true will activate the base
+ // case, so we're safe.
+ while (len > a->len) {
+ BcVec *v = bc_vec_pushEmpty(a);
+ bc_array_init(v, true);
+ }
+ }
+}
+
+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 is assumed to not be valid yet.
+ d->t = src->t;
+
+ // Yes, it depends on what type.
+ 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:
+ case BC_RESULT_ARRAY:
+ 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
+ // We should *never* try copying either of these.
+ 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:
+ case BC_RESULT_ARRAY:
+ 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..f8b32451aef7
--- /dev/null
+++ b/contrib/bc/src/lex.c
@@ -0,0 +1,311 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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;
+ bool end = false, got_more;
+ char c;
+
+ l->i += 1;
+ l->t = BC_LEX_WHITESPACE;
+
+ // This loop is complex because it might need to request more data from
+ // stdin if the comment is not ended. This loop is taken until the comment
+ // is finished or we have EOF.
+ do {
+
+ buf = l->buf;
+ got_more = false;
+
+ // If we are in stdin mode, the buffer must be the one used for stdin.
+ assert(!vm.is_stdin || buf == vm.buffer.v);
+
+ // Find the end of the comment.
+ for (i = l->i; !end; i += !end) {
+
+ // While we don't have an asterisk, eat, but increment nlines.
+ for (; (c = buf[i]) && c != '*'; ++i) nlines += (c == '\n');
+
+ // If this is true, we need to request more data.
+ if (BC_ERR(!c || buf[i + 1] == '\0')) {
+
+ // Read more.
+ if (!vm.eof && l->is_stdin) got_more = bc_lex_readLine(l);
+
+ break;
+ }
+
+ // If this turns true, we found the end. Yay!
+ end = (buf[i + 1] == '/');
+ }
+
+ } while (got_more && !end);
+
+ // If we didn't find the end, barf.
+ if (!end) {
+ l->i = i;
+ bc_lex_err(l, BC_ERR_PARSE_COMMENT);
+ }
+
+ l->i = i + 2;
+ l->line += nlines;
+}
+
+void bc_lex_whitespace(BcLex *l) {
+
+ char c;
+
+ l->t = BC_LEX_WHITESPACE;
+
+ // Eat. We don't eat newlines because they can be special.
+ 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);
+}
+
+/**
+ * Parses a number.
+ * @param l The lexer.
+ * @param start The start character.
+ * @param int_only Whether this function should only look for an integer. This
+ * is used to implement the exponent of scientific notation.
+ */
+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 == '.');
+
+ // This loop looks complex. It is not. It is asking if the character is not
+ // a nul byte and it if it a valid num character based on what we have found
+ // thus far, or whether it is a backslash followed by a newline. I can do
+ // i+1 on the buffer because the buffer must have a nul byte.
+ for (i = 0; (c = buf[i]) && (BC_LEX_NUM_CHAR(c, pt, int_only) ||
+ (c == '\\' && buf[i + 1] == '\n')); ++i)
+ {
+ // I don't need to test that the next character is a newline because
+ // the loop condition above ensures that.
+ if (c == '\\') {
+
+ 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 the next character is not a number character, bail.
+ if (!BC_LEX_NUM_CHAR(c, pt, int_only)) break;
+ }
+
+ // Did we find the radix point?
+ last_pt = (c == '.');
+
+ // If we did, and we already have one, then break because it's not part
+ // of this number.
+ if (pt && last_pt) break;
+
+ // Set whether we have found a radix point.
+ 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;
+
+ // Make sure the string is clear.
+ bc_vec_popAll(&l->str);
+ bc_vec_push(&l->str, &start);
+
+ // Parse the number.
+ l->i += bc_lex_num(l, start, false);
+
+#if BC_ENABLE_EXTRA_MATH
+ {
+ char c = l->buf[l->i];
+
+ // Do we have a number in scientific notation?
+ if (c == 'e') {
+
+#if BC_ENABLED
+ // Barf for POSIX.
+ if (BC_IS_POSIX) bc_lex_err(l, BC_ERR_POSIX_EXP_NUM);
+#endif // BC_ENABLED
+
+ // Push the e.
+ bc_vec_push(&l->str, &c);
+ l->i += 1;
+ c = l->buf[l->i];
+
+ // Check for negative specifically because bc_lex_num() does not.
+ if (c == BC_LEX_NEG_CHAR) {
+ bc_vec_push(&l->str, &c);
+ l->i += 1;
+ c = l->buf[l->i];
+ }
+
+ // We must have a number character, so barf if not.
+ if (BC_ERR(!BC_LEX_NUM_CHAR(c, false, true)))
+ bc_lex_verr(l, BC_ERR_PARSE_CHAR, c);
+
+ // Parse the exponent.
+ 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;
+
+ // Should be obvious. It's looking for valid characters.
+ while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i];
+
+ // Set the string to the identifier.
+ 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), BC_DTOR_NONE);
+}
+
+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;
+
+ // If this wasn't here, the line number would be off.
+ l->line += (l->i != 0 && l->buf[l->i - 1] == '\n');
+
+ // If the last token was EOF, someone called this one too many times.
+ if (BC_ERR(l->last == BC_LEX_EOF)) bc_lex_err(l, BC_ERR_PARSE_EOF);
+
+ l->t = BC_LEX_EOF;
+
+ // We are done if this is true.
+ 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);
+}
+
+/**
+ * Updates the buffer and len so that they are not invalidated when the stdin
+ * buffer grows.
+ * @param l The lexer.
+ * @param text The text.
+ * @param len The length of the text.
+ */
+static void bc_lex_fixText(BcLex *l, const char *text, size_t len) {
+ l->buf = text;
+ l->len = len;
+}
+
+bool bc_lex_readLine(BcLex *l) {
+
+ bool good = bc_vm_readLine(false);
+
+ bc_lex_fixText(l, vm.buffer.v, vm.buffer.len - 1);
+
+ return good;
+}
+
+void bc_lex_text(BcLex *l, const char *text, bool is_stdin) {
+ assert(l != NULL && text != NULL);
+ bc_lex_fixText(l, text, strlen(text));
+ l->i = 0;
+ l->t = l->last = BC_LEX_INVALID;
+ l->is_stdin = is_stdin;
+ bc_lex_next(l);
+}
diff --git a/contrib/bc/src/library.c b/contrib/bc/src/library.c
new file mode 100644
index 000000000000..e0bd3ee98b85
--- /dev/null
+++ b/contrib/bc/src/library.c
@@ -0,0 +1,1281 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+// The asserts in this file are important to testing; in many cases, the test
+// would not work without the asserts, so don't remove them without reason.
+//
+// Also, there are many uses of bc_num_clear() here; that is because numbers are
+// being reused, and a clean slate is required.
+//
+// Also, there are a bunch of BC_UNSETJMP and BC_SETJMP_LOCKED() between calls
+// to bc_num_init(). That is because locals are being initialized, and unlike bc
+// proper, this code cannot assume that allocation failures are fatal. So we
+// have to reset the jumps every time to ensure that the locals will be correct
+// after jumping.
+
+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_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;
+
+ // Setting these to NULL ensures that if an error occurs, we only free what
+ // is necessary.
+ vm.ctxts.v = NULL;
+ vm.jmp_bufs.v = NULL;
+ vm.out.v = NULL;
+
+ vm.abrt = false;
+
+ BC_SIG_LOCK;
+
+ // The jmp_bufs always has to be initialized first.
+ bc_vec_init(&vm.jmp_bufs, sizeof(sigjmp_buf), BC_DTOR_NONE);
+
+ BC_FUNC_HEADER_INIT(err);
+
+ bc_vm_init();
+
+ bc_vec_init(&vm.ctxts, sizeof(BclContext), BC_DTOR_NONE);
+ bc_vec_init(&vm.out, sizeof(uchar), BC_DTOR_NONE);
+
+ // We need to seed this in case /dev/random and /dev/urandm don't work.
+ srand((unsigned int) time(NULL));
+ bc_rand_init(&vm.rng);
+
+err:
+ // This is why we had to set them to NULL.
+ 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) {
+
+ size_t i;
+
+ vm.refs -= 1;
+
+ if (vm.refs) return;
+
+ BC_SIG_LOCK;
+
+ bc_rand_free(&vm.rng);
+ bc_vec_free(&vm.out);
+
+ 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);
+
+ bc_vm_atexit();
+
+ BC_SIG_UNLOCK;
+
+ memset(&vm, 0, sizeof(BcVm));
+
+ assert(!vm.running && !vm.sig && !vm.sig_lock);
+}
+
+void bcl_gc(void) {
+ BC_SIG_LOCK;
+ bc_vm_freeTemps();
+ BC_SIG_UNLOCK;
+}
+
+bool bcl_abortOnFatalError(void) {
+ return vm.abrt;
+}
+
+void bcl_setAbortOnFatalError(bool abrt) {
+ vm.abrt = abrt;
+}
+
+bool bcl_leadingZeroes(void) {
+ return vm.leading_zeroes;
+}
+
+void bcl_setLeadingZeroes(bool leadingZeroes) {
+ vm.leading_zeroes = leadingZeroes;
+}
+
+BclContext bcl_ctxt_create(void) {
+
+ BclContext ctxt = NULL;
+
+ BC_FUNC_HEADER_LOCK(err);
+
+ // We want the context to be free of any interference of other parties, so
+ // malloc() is appropriate here.
+ ctxt = bc_vm_malloc(sizeof(BclCtxt));
+
+ bc_vec_init(&ctxt->nums, sizeof(BcNum), BC_DTOR_BCL_NUM);
+ bc_vec_init(&ctxt->free_nums, sizeof(BclNumber), BC_DTOR_NONE);
+
+ 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_popAll(&ctxt->nums);
+ bc_vec_popAll(&ctxt->free_nums);
+}
+
+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);
+
+ // Errors are encoded as (0 - error_code). If the index is in that range, it
+ // is an encoded error.
+ 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;
+}
+
+/**
+ * Inserts a BcNum into a context's list of numbers.
+ * @param ctxt The context to insert into.
+ * @param n The BcNum to insert.
+ * @return The resulting BclNumber from the insert.
+ */
+static BclNumber bcl_num_insert(BclContext ctxt, BcNum *restrict n) {
+
+ BclNumber idx;
+
+ // If there is a free spot...
+ if (ctxt->free_nums.len) {
+
+ BcNum *ptr;
+
+ // Get the index of the free spot and remove it.
+ idx = *((BclNumber*) bc_vec_top(&ctxt->free_nums));
+ bc_vec_pop(&ctxt->free_nums);
+
+ // Copy the number into the spot.
+ ptr = bc_vec_item(&ctxt->nums, idx.i);
+ memcpy(ptr, n, sizeof(BcNum));
+ }
+ else {
+ // Just push the number onto the vector.
+ 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;
+}
+
+/**
+ * Destructs a number and marks its spot as free.
+ * @param ctxt The context.
+ * @param n The index of the number.
+ * @param num The number to destroy.
+ */
+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);
+
+ // Copy the number.
+ 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;
+}
+
+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);
+
+ *result = bc_num_bigdig(num);
+
+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;
+}
+
+/**
+ * Sets up and executes a binary operator operation.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param op The operation.
+ * @param req The function to get the size of the result for preallocation.
+ * @return The result of the operation.
+ */
+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);
+
+ // Clear and initialize the result.
+ 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;
+
+ // Eat the operands.
+ 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);
+
+ // Initialize the numbers.
+ bc_num_init(&cnum, req);
+ BC_UNSETJMP;
+ BC_SETJMP_LOCKED(err);
+ bc_num_init(&dnum, req);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_divmod(aptr, bptr, &cnum, &dnum, ctxt->scale);
+
+err:
+ BC_SIG_MAYLOCK;
+
+ // Eat the operands.
+ bcl_num_dtor(ctxt, a, aptr);
+ if (b.i != a.i) bcl_num_dtor(ctxt, b, bptr);
+
+ // If there was an error...
+ if (BC_ERR(vm.err)) {
+
+ // Free the results.
+ if (cnum.num != NULL) bc_num_free(&cnum);
+ if (dnum.num != NULL) bc_num_free(&dnum);
+
+ // Make sure the return values are invalid.
+ c->i = 0 - (size_t) BCL_ERROR_INVALID_NUM;
+ d->i = c->i;
+
+ BC_FUNC_FOOTER(e);
+ }
+ else {
+
+ BC_FUNC_FOOTER(e);
+
+ // Insert the results into the context.
+ *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);
+
+ // Prepare the result.
+ bc_num_clear(&d);
+
+ req = bc_num_divReq(aptr, cptr, 0);
+
+ // Initialize the result.
+ bc_num_init(&d, req);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_modexp(aptr, bptr, cptr, &d);
+
+err:
+ BC_SIG_MAYLOCK;
+
+ // Eat the operands.
+ 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);
+
+ // We have to take care of negative here because bc's number parsing does
+ // not.
+ neg = (val[0] == '-');
+
+ if (neg) val += 1;
+
+ if (!bc_num_strValid(val)) {
+ vm.err = BCL_ERROR_PARSE_INVALID_STR;
+ goto err;
+ }
+
+ // Clear and initialize the number.
+ bc_num_clear(&n);
+ bc_num_init(&n, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bc_num_parse(&n, val, (BcBigDig) ctxt->ibase);
+
+ // Set the negative.
+ 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);
+
+ // Clear the buffer.
+ bc_vec_popAll(&vm.out);
+
+ // Print to the buffer.
+ bc_num_print(nptr, (BcBigDig) ctxt->obase, false);
+ bc_vec_pushByte(&vm.out, '\0');
+
+ BC_SIG_LOCK;
+
+ // Just dup the string; the caller is responsible for it.
+ str = bc_vm_strdup(vm.out.v);
+
+err:
+
+ // Eat the operand.
+ 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);
+
+ // Clear and initialize the result.
+ 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;
+
+ // Eat the operand.
+ 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;
+}
+
+/**
+ * Helps bcl_frand(). This is separate because the error handling is easier that
+ * way. It is also easier to do ifrand that way.
+ * @param b The return parameter.
+ * @param places The number of decimal places to generate.
+ */
+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];
+
+ // Set up temporaries.
+ 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);
+
+ // Clear the temporary that might need to grow.
+ bc_num_clear(&pow);
+
+ BC_SIG_LOCK;
+
+ // Initialize the temporary that might need to grow.
+ bc_num_init(&pow, bc_num_powReq(&ten, &exp, 0));
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ // Generate the number.
+ bc_num_pow(&ten, &exp, &pow, 0);
+ bc_num_irand(&pow, b, &vm.rng);
+
+ // Make the number entirely fraction.
+ 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);
+
+ // Clear and initialize the number.
+ 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;
+}
+
+/**
+ * Helps bc_ifrand(). This is separate because error handling is easier that
+ * way.
+ * @param a The limit for bc_num_irand().
+ * @param b The return parameter.
+ * @param places The number of decimal places to generate.
+ */
+static void bcl_ifrandHelper(BcNum *restrict a, BcNum *restrict b,
+ size_t places)
+{
+ BcNum ir, fr;
+
+ // Clear the integer and fractional numbers.
+ bc_num_clear(&ir);
+ bc_num_clear(&fr);
+
+ BC_SIG_LOCK;
+
+ // Initialize the integer and fractional numbers.
+ bc_num_init(&ir, BC_NUM_DEF_SIZE);
+ bc_num_init(&fr, BC_NUM_DEF_SIZE);
+
+ BC_SETJMP_LOCKED(err);
+
+ 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);
+
+ // Clear and initialize the number.
+ bc_num_clear(&b);
+ bc_num_init(&b, BC_NUM_DEF_SIZE);
+
+ BC_SIG_UNLOCK;
+
+ bcl_ifrandHelper(aptr, &b, places);
+
+err:
+ BC_SIG_MAYLOCK;
+
+ // Eat the oprand.
+ 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[BCL_SEED_SIZE]) {
+
+ BclError e = BCL_ERROR_NONE;
+ size_t i;
+ ulong vals[BCL_SEED_ULONGS];
+
+ BC_FUNC_HEADER(err);
+
+ // Fill the array.
+ for (i = 0; i < BCL_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);
+
+ // Clear and initialize the number.
+ 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..38c87a415f2b
--- /dev/null
+++ b/contrib/bc/src/main.c
@@ -0,0 +1,96 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * The entry point for bc.
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <locale.h>
+
+#ifndef _WIN32
+#include <libgen.h>
+#endif // _WIN32
+
+#include <setjmp.h>
+
+#include <version.h>
+#include <status.h>
+#include <vm.h>
+#include <bc.h>
+#include <dc.h>
+
+int main(int argc, char *argv[]) {
+
+ char *name;
+ size_t len = strlen(BC_EXECPREFIX);
+
+ // Must set the locale properly in order to have the right error messages.
+ vm.locale = setlocale(LC_ALL, "");
+
+ // Set the start pledge().
+ bc_pledge(bc_pledge_start, NULL);
+
+ // Figure out the name of the calculator we are using. We can't use basename
+ // because it's not portable, but yes, this is stripping off the directory.
+ name = strrchr(argv[0], BC_FILE_SEP);
+ vm.name = (name == NULL) ? argv[0] : name + 1;
+
+ // If the name is longer than the length of the prefix, skip the prefix.
+ if (strlen(vm.name) > len) vm.name += len;
+
+ BC_SIG_LOCK;
+
+ // We *must* do this here. Otherwise, other code could not jump out all of
+ // the way.
+ bc_vec_init(&vm.jmp_bufs, sizeof(sigjmp_buf), BC_DTOR_NONE);
+
+ BC_SETJMP_LOCKED(exit);
+
+#if !DC_ENABLED
+ bc_main(argc, argv);
+#elif !BC_ENABLED
+ dc_main(argc, argv);
+#else
+ // BC_IS_BC uses vm.name, which was set above. So we're good.
+ if (BC_IS_BC) bc_main(argc, argv);
+ else dc_main(argc, argv);
+#endif
+
+exit:
+ BC_SIG_MAYLOCK;
+
+ // Ensure we exit appropriately.
+ return bc_vm_atexit((int) vm.status);
+}
diff --git a/contrib/bc/src/num.c b/contrib/bc/src/num.c
new file mode 100644
index 000000000000..dc3f63ab076e
--- /dev/null
+++ b/contrib/bc/src/num.c
@@ -0,0 +1,3931 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+// Before you try to understand this code, see the development manual
+// (manuals/development.md#numbers).
+
+static void bc_num_m(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale);
+
+/**
+ * Multiply two numbers and throw a math error if they overflow.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @return The product of the two operands.
+ */
+static inline size_t bc_num_mulOverflow(size_t a, size_t b) {
+ size_t res = a * b;
+ if (BC_ERR(BC_VM_MUL_OVERFLOW(a, b, res))) bc_err(BC_ERR_MATH_OVERFLOW);
+ return res;
+}
+
+/**
+ * Conditionally negate @a n based on @a neg. Algorithm taken from
+ * https://graphics.stanford.edu/~seander/bithacks.html#ConditionalNegate .
+ * @param n The value to turn into a signed value and negate.
+ * @param neg The condition to negate or not.
+ */
+static inline ssize_t bc_num_neg(size_t n, bool neg) {
+ return (((ssize_t) n) ^ -((ssize_t) neg)) + neg;
+}
+
+/**
+ * Compare a BcNum against zero.
+ * @param n The number to compare.
+ * @return -1 if the number is less than 0, 1 if greater, and 0 if equal.
+ */
+ssize_t bc_num_cmpZero(const BcNum *n) {
+ return bc_num_neg((n)->len != 0, BC_NUM_NEG(n));
+}
+
+/**
+ * Return the number of integer limbs in a BcNum. This is the opposite of rdx.
+ * @param n The number to return the amount of integer limbs for.
+ * @return The amount of integer limbs in @a n.
+ */
+static inline size_t bc_num_int(const BcNum *n) {
+ return n->len ? n->len - BC_NUM_RDX_VAL(n) : 0;
+}
+
+/**
+ * Expand a number's allocation capacity to at least req limbs.
+ * @param n The number to expand.
+ * @param req The number limbs to expand the allocation capacity to.
+ */
+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;
+ }
+}
+
+/**
+ * Set a number to 0 with the specified scale.
+ * @param n The number to set to zero.
+ * @param scale The scale to set the number to.
+ */
+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;
+}
+
+/**
+ * "Cleans" a number, which means reducing the length if the most significant
+ * limbs are zero.
+ * @param n The number to clean.
+ */
+static void bc_num_clean(BcNum *restrict n) {
+
+ // Reduce the length.
+ while (BC_NUM_NONZERO(n) && !n->num[n->len - 1]) n->len -= 1;
+
+ // Special cases.
+ if (BC_NUM_ZERO(n)) n->rdx = 0;
+ else {
+
+ // len must be at least as much as rdx.
+ size_t rdx = BC_NUM_RDX_VAL(n);
+ if (n->len < rdx) n->len = rdx;
+ }
+}
+
+/**
+ * Returns the log base 10 of @a i. I could have done this with floating-point
+ * math, and in fact, I originally did. However, that was the only
+ * floating-point code in the entire codebase, and I decided I didn't want any.
+ * This is fast enough. Also, it might handle larger numbers better.
+ * @param i The number to return the log base 10 of.
+ * @return The log base 10 of @a i.
+ */
+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;
+}
+
+/**
+ * Returns the number of decimal digits in a limb that are zero starting at the
+ * most significant digits. This basically returns how much of the limb is used.
+ * @param n The number.
+ * @return The number of decimal digits that are 0 starting at the most
+ * significant digits.
+ */
+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);
+}
+
+/**
+ * Return the total number of integer digits in a number. This is the opposite
+ * of scale, like bc_num_int() is the opposite of rdx.
+ * @param n The number.
+ * @return The number of integer digits in @a 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;
+}
+
+/**
+ * Returns the number of limbs of a number that are non-zero starting at the
+ * most significant limbs. This expects that there are *no* integer limbs in the
+ * number because it is specifically to figure out how many zero limbs after the
+ * decimal place to ignore. If there are zero limbs after non-zero limbs, they
+ * are counted as non-zero limbs.
+ * @param n The number.
+ * @return The number of non-zero limbs after the decimal point.
+ */
+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;
+}
+
+/**
+ * Performs a one-limb add with a carry.
+ * @param a The first limb.
+ * @param b The second limb.
+ * @param carry An in/out parameter; the carry in from the previous add and the
+ * carry out from this add.
+ * @return The resulting limb sum.
+ */
+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;
+}
+
+/**
+ * Performs a one-limb subtract with a carry.
+ * @param a The first limb.
+ * @param b The second limb.
+ * @param carry An in/out parameter; the carry in from the previous subtract
+ * and the carry out from this subtract.
+ * @return The resulting limb difference.
+ */
+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;
+}
+
+/**
+ * Add two BcDig arrays and store the result in the first array.
+ * @param a The first operand and out array.
+ * @param b The second operand.
+ * @param len The length of @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);
+
+ // Take care of the extra limbs in the bigger array.
+ for (; carry; ++i) a[i] = bc_num_addDigits(a[i], 0, &carry);
+}
+
+/**
+ * Subtract two BcDig arrays and store the result in the first array.
+ * @param a The first operand and out array.
+ * @param b The second operand.
+ * @param len The length of @a b.
+ */
+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);
+
+ // Take care of the extra limbs in the bigger array.
+ for (; carry; ++i) a[i] = bc_num_subDigits(a[i], 0, &carry);
+}
+
+/**
+ * Multiply a BcNum array by a one-limb number. This is a faster version of
+ * multiplication for when we can use it.
+ * @param a The BcNum to multiply by the one-limb number.
+ * @param b The one limb of the one-limb number.
+ * @param c The return parameter.
+ */
+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);
+
+ // Make sure the return parameter is big enough.
+ if (a->len + 1 > c->cap) bc_num_expand(c, a->len + 1);
+
+ // We want the entire return parameter to be zero for cleaning later.
+ memset(c->num, 0, BC_NUM_SIZE(c->cap));
+
+ // Actual multiplication loop.
+ 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);
+
+ // Finishing touches.
+ c->num[i] = (BcDig) carry;
+ c->len = a->len;
+ c->len += (carry != 0);
+
+ bc_num_clean(c);
+
+ // Postconditions.
+ 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);
+}
+
+/**
+ * Divide a BcNum array by a one-limb number. This is a faster version of divide
+ * for when we can use it.
+ * @param a The BcNum to multiply by the one-limb number.
+ * @param b The one limb of the one-limb number.
+ * @param c The return parameter for the quotient.
+ * @param rem The return parameter for the remainder.
+ */
+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);
+
+ // Actual division loop.
+ 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;
+ }
+
+ // Finishing touches.
+ c->len = a->len;
+ bc_num_clean(c);
+ *rem = carry;
+
+ // Postconditions.
+ 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);
+}
+
+/**
+ * Compare two BcDig arrays and return >0 if @a b is greater, <0 if @a b is
+ * less, and 0 if equal. Both @a a and @a b must have the same length.
+ * @param a The first array.
+ * @param b The second array.
+ * @param len The minimum length of the arrays.
+ */
+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);
+
+ // Same num? Equal.
+ if (a == b) return 0;
+
+ // Easy cases.
+ 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;
+
+ // Get the number of int limbs in each number and get the difference.
+ a_int = bc_num_int(a);
+ b_int = bc_num_int(b);
+ a_int -= b_int;
+
+ // If there's a difference, then just return the comparison.
+ if (a_int) return neg ? -((ssize_t) a_int) : (ssize_t) a_int;
+
+ // Get the rdx's and figure out the max.
+ ardx = BC_NUM_RDX_VAL(a);
+ brdx = BC_NUM_RDX_VAL(b);
+ a_max = (ardx > brdx);
+
+ // Set variables based on the above.
+ 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;
+ }
+
+ // Do a full limb-by-limb comparison.
+ cmp = bc_num_compare(max_num, min_num, b_int + min);
+
+ // If we found a difference, return it based on state.
+ if (cmp) return bc_num_neg((size_t) cmp, !a_max == !neg);
+
+ // If there was no difference, then the final step is to check which number
+ // has greater or lesser limbs beyond the other's.
+ 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;
+
+ // Grab these needed values; places_rdx is the rdx equivalent to places like
+ // rdx is to scale.
+ nrdx = BC_NUM_RDX_VAL(n);
+ places_rdx = nrdx ? nrdx - BC_NUM_RDX(n->scale - places) : 0;
+
+ // We cannot truncate more places than we have.
+ assert(places <= n->scale && (BC_NUM_ZERO(n) || places_rdx <= n->len));
+
+ n->scale -= places;
+ BC_NUM_RDX_SET(n, nrdx - places_rdx);
+
+ // Only when the number is nonzero do we need to do the hard stuff.
+ if (BC_NUM_NONZERO(n)) {
+
+ size_t pow;
+
+ // This calculates how many decimal digits are in the least significant
+ // limb.
+ pow = n->scale % BC_BASE_DIGS;
+ pow = pow ? BC_BASE_DIGS - pow : 0;
+ pow = bc_num_pow10[pow];
+
+ n->len -= places_rdx;
+
+ // We have to move limbs to maintain invariants. The limbs must begin at
+ // the beginning of the BcNum array.
+ 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;
+
+ // Easy case with zero; set the scale.
+ if (BC_NUM_ZERO(n)) {
+ n->scale += places;
+ return;
+ }
+
+ // Grab these needed values; places_rdx is the rdx equivalent to places like
+ // rdx is to scale.
+ nrdx = BC_NUM_RDX_VAL(n);
+ places_rdx = BC_NUM_RDX(places + n->scale) - nrdx;
+
+ // This is the hard case. We need to expand the number, move the limbs, and
+ // set the limbs that were just cleared.
+ 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));
+ }
+
+ // Finally, set scale and 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));
+}
+
+/**
+ * Retires (finishes) a multiplication or division operation.
+ */
+static void bc_num_retireMul(BcNum *restrict n, size_t scale,
+ bool neg1, bool neg2)
+{
+ // Make sure scale is correct.
+ if (n->scale < scale) bc_num_extend(n, scale - n->scale);
+ else bc_num_truncate(n, n->scale - scale);
+
+ bc_num_clean(n);
+
+ // We need to ensure rdx is correct.
+ if (BC_NUM_NONZERO(n)) n->rdx = BC_NUM_NEG_VAL(n, !neg1 != !neg2);
+}
+
+/**
+ * Splits a number into two BcNum's. This is used in Karatsuba.
+ * @param n The number to split.
+ * @param idx The index to split at.
+ * @param a An out parameter; the low part of @a n.
+ * @param b An out parameter; the high part of @a n.
+ */
+static void bc_num_split(const BcNum *restrict n, size_t idx,
+ BcNum *restrict a, BcNum *restrict b)
+{
+ // We want a and b to be clear.
+ assert(BC_NUM_ZERO(a));
+ assert(BC_NUM_ZERO(b));
+
+ // The usual case.
+ if (idx < n->len) {
+
+ // Set the fields first.
+ 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);
+
+ // Copy the arrays. This is not necessary for safety, but it is faster,
+ // for some reason.
+ memcpy(b->num, n->num + idx, BC_NUM_SIZE(b->len));
+ memcpy(a->num, n->num, BC_NUM_SIZE(idx));
+
+ bc_num_clean(b);
+ }
+ // If the index is weird, just skip the split.
+ else bc_num_copy(a, n);
+
+ bc_num_clean(a);
+}
+
+/**
+ * Copies a number into another, but shifts the rdx so that the result number
+ * only sees the integer part of the source number.
+ * @param n The number to copy.
+ * @param r The result number with a shifted rdx, len, and num.
+ */
+static void bc_num_shiftRdx(const BcNum *restrict n, BcNum *restrict r) {
+
+ size_t rdx = BC_NUM_RDX_VAL(n);
+
+ r->len = n->len - rdx;
+ r->cap = n->cap - rdx;
+ r->num = n->num + rdx;
+
+ BC_NUM_RDX_SET_NEG(r, 0, BC_NUM_NEG(n));
+ r->scale = 0;
+}
+
+/**
+ * Shifts a number so that all of the least significant limbs of the number are
+ * skipped. This must be undone by bc_num_unshiftZero().
+ * @param n The number to shift.
+ */
+static size_t bc_num_shiftZero(BcNum *restrict n) {
+
+ size_t i;
+
+ // If we don't have an integer, that is a problem, but it's also a bug
+ // because the caller should have set everything up right.
+ 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;
+}
+
+/**
+ * Undo the damage done by bc_num_unshiftZero(). This must be called like all
+ * cleanup functions: after a label used by setjmp() and longjmp().
+ * @param n The number to unshift.
+ * @param places_rdx The amount the number was originally shift.
+ */
+static void bc_num_unshiftZero(BcNum *restrict n, size_t places_rdx) {
+ n->len += places_rdx;
+ n->num -= places_rdx;
+}
+
+/**
+ * Shifts the digits right within a number by no more than BC_BASE_DIGS - 1.
+ * This is the final step on shifting numbers with the shift operators. It
+ * depends on the caller to shift the limbs properly because all it does is
+ * ensure that the rdx point is realigned to be between limbs.
+ * @param n The number to shift digits in.
+ * @param dig The number of places to shift right.
+ */
+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);
+
+ // Figure out the parameters for division.
+ pow = bc_num_pow10[dig];
+ dig = bc_num_pow10[BC_BASE_DIGS - dig];
+
+ // Run a series of divisions and mods with carries across the entire number
+ // array. This effectively shifts everything over.
+ 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);
+}
+
+/**
+ * Shift a number left by a certain number of places. This is the workhorse of
+ * the left shift operator.
+ * @param n The number to shift left.
+ * @param places The amount of places to shift @a n left by.
+ */
+static void bc_num_shiftLeft(BcNum *restrict n, size_t places) {
+
+ BcBigDig dig;
+ size_t places_rdx;
+ bool shift;
+
+ if (!places) return;
+
+ // Make sure to grow the number if necessary.
+ if (places > n->scale) {
+ size_t size = bc_vm_growSize(BC_NUM_RDX(places - n->scale), n->len);
+ if (size > SIZE_MAX - 1) bc_err(BC_ERR_MATH_OVERFLOW);
+ }
+
+ // If zero, we can just set the scale and bail.
+ if (BC_NUM_ZERO(n)) {
+ if (n->scale >= places) n->scale -= places;
+ else n->scale = 0;
+ return;
+ }
+
+ // When I changed bc to have multiple digits per limb, this was the hardest
+ // code to change. This and shift right. Make sure you understand this
+ // before attempting anything.
+
+ // This is how many limbs we will shift.
+ dig = (BcBigDig) (places % BC_BASE_DIGS);
+ shift = (dig != 0);
+
+ // Convert places to a rdx value.
+ places_rdx = BC_NUM_RDX(places);
+
+ // If the number is not an integer, we need special care. The reason an
+ // integer doesn't is because left shift would only extend the integer,
+ // whereas a non-integer might have its fractional part eliminated or only
+ // partially eliminated.
+ if (n->scale) {
+
+ size_t nrdx = BC_NUM_RDX_VAL(n);
+
+ // If the number's rdx is bigger, that's the hard case.
+ if (nrdx >= places_rdx) {
+
+ size_t mod = n->scale % BC_BASE_DIGS, revdig;
+
+ // We want mod to be in the range [1, BC_BASE_DIGS], not
+ // [0, BC_BASE_DIGS).
+ mod = mod ? mod : BC_BASE_DIGS;
+
+ // We need to reverse dig to get the actual number of digits.
+ revdig = dig ? BC_BASE_DIGS - dig : 0;
+
+ // If the two overflow BC_BASE_DIGS, we need to move an extra place.
+ if (mod + revdig > BC_BASE_DIGS) places_rdx = 1;
+ else places_rdx = 0;
+ }
+ else places_rdx -= nrdx;
+ }
+
+ // If this is non-zero, we need an extra place, so expand, move, and set.
+ 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;
+ }
+
+ // Set the scale appropriately.
+ 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));
+ }
+
+ // Finally, shift within limbs.
+ 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 zero, we can just set the scale and bail.
+ if (BC_NUM_ZERO(n)) {
+ n->scale += places;
+ bc_num_expand(n, BC_NUM_RDX(n->scale));
+ return;
+ }
+
+ // Amount within a limb we have to shift by.
+ dig = (BcBigDig) (places % BC_BASE_DIGS);
+ shift = (dig != 0);
+
+ scale = n->scale;
+
+ // Figure out how the scale is affected.
+ scale_mod = scale % BC_BASE_DIGS;
+ scale_mod = scale_mod ? scale_mod : BC_BASE_DIGS;
+
+ // We need to know the int length and rdx for places.
+ int_len = bc_num_int(n);
+ places_rdx = BC_NUM_RDX(places);
+
+ // If we are going to shift past a limb boundary or not, set accordingly.
+ if (scale_mod + dig > BC_BASE_DIGS) {
+ expand = places_rdx - 1;
+ places_rdx = 1;
+ }
+ else {
+ expand = places_rdx;
+ places_rdx = 0;
+ }
+
+ // Clamp expanding.
+ if (expand > int_len) expand -= int_len;
+ else expand = 0;
+
+ // Extend, expand, and zero.
+ 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));
+
+ // Set the fields.
+ n->len += expand;
+ n->scale = 0;
+ BC_NUM_RDX_SET(n, 0);
+
+ // Finally, shift within limbs.
+ 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));
+}
+
+/**
+ * Invert @a into @a b at the current scale.
+ * @param a The number to invert.
+ * @param b The return parameter. This must be preallocated.
+ * @param scale The current scale.
+ */
+static inline void bc_num_inv(BcNum *a, BcNum *b, size_t scale) {
+ assert(BC_NUM_NONZERO(a));
+ bc_num_div(&vm.one, a, b, scale);
+}
+
+/**
+ * Tests if a number is a integer with scale or not. Returns true if the number
+ * is not an integer. If it is, its integer shifted form is copied into the
+ * result parameter for use where only integers are allowed.
+ * @param n The integer to test and shift.
+ * @param r The number to store the shifted result into. This number should
+ * *not* be allocated.
+ * @return True if the number is a non-integer, false otherwise.
+ */
+static bool bc_num_nonInt(const BcNum *restrict n, BcNum *restrict r) {
+
+ bool zero;
+ size_t i, rdx = BC_NUM_RDX_VAL(n);
+
+ if (!rdx) {
+ memcpy(r, n, sizeof(BcNum));
+ return false;
+ }
+
+ zero = true;
+
+ for (i = 0; zero && i < rdx; ++i) zero = (n->num[i] == 0);
+
+ if (BC_ERR(!zero)) return true;
+
+ bc_num_shiftRdx(n, r);
+
+ return false;
+}
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * Execute common code for an operater that needs an integer for the second
+ * operand and return the integer operand as a BcBigDig.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The result operand.
+ * @return The second operand as a hardware integer.
+ */
+static BcBigDig bc_num_intop(const BcNum *a, const BcNum *b, BcNum *restrict c)
+{
+ BcNum temp;
+
+ if (BC_ERR(bc_num_nonInt(b, &temp))) bc_err(BC_ERR_MATH_NON_INTEGER);
+
+ bc_num_copy(c, a);
+
+ return bc_num_bigdig(&temp);
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * This is the actual implementation of add *and* subtract. Since 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. And then I convert substraction to addition
+ * of negative second operand. This is a BcNumBinOp function.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param sub Non-zero for a subtract, zero for an add.
+ */
+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;
+
+ 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
+ // precede the tests for any of the operands being zero.
+ b_neg = (BC_NUM_NEG(b) != sub);
+
+ // Figure out if we will actually add the numbers if their signs are equal
+ // or 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);
+
+ // Figure out which number will have its last limbs copied (for addition) or
+ // subtracted (for subtraction).
+ 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);
+
+ // Cache values for simple code later.
+ 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;
+
+ // This is true if the numbers have a different number of limbs after the
+ // decimal point.
+ 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));
+ }
+
+ // Future code needs to ignore the limbs we just did.
+ ptr_r += diff;
+ len_r -= diff;
+ }
+
+ // The return value pointer needs to ignore what we just did.
+ ptr_c += diff;
+ }
+
+ // This is the length that can be directly added/subtracted.
+ min_len = BC_MIN(len_l, len_r);
+
+ // After dealing with possible low array elements that depend on only one
+ // operand above, 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) {
+
+ // Actual subtraction.
+ for (i = 0; i < min_len; ++i)
+ ptr_c[i] = bc_num_subDigits(ptr_l[i], ptr_r[i], &carry);
+
+ // Finishing the limbs beyond the direct subtraction.
+ for (; i < len_l; ++i) ptr_c[i] = bc_num_subDigits(ptr_l[i], 0, &carry);
+ }
+ else {
+
+ // Actual addition.
+ for (i = 0; i < min_len; ++i)
+ ptr_c[i] = bc_num_addDigits(ptr_l[i], ptr_r[i], &carry);
+
+ // Finishing the limbs beyond the direct addition.
+ for (; i < len_l; ++i) ptr_c[i] = bc_num_addDigits(ptr_l[i], 0, &carry);
+
+ // Addition can create an extra limb. We take care of that here.
+ 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);
+}
+
+/**
+ * The simple multiplication that karatsuba dishes out to when the length of the
+ * numbers gets low enough. This doesn't use scale because it treats the
+ * operands as though they are integers.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ */
+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));
+
+ // Make sure c is big enough.
+ clen = bc_vm_growSize(alen, blen);
+ bc_num_expand(c, bc_vm_growSize(clen, 1));
+
+ // If we don't memset, then we might have uninitialized data use later.
+ ptr_c = c->num;
+ memset(ptr_c, 0, BC_NUM_SIZE(c->cap));
+
+ // This is the actual multiplication loop. It uses the lattice form of long
+ // multiplication (see the explanation on the web page at
+ // https://knilt.arcc.albany.edu/What_is_Lattice_Multiplication or the
+ // explanation at Wikipedia).
+ for (i = 0; i < clen; ++i) {
+
+ ssize_t sidx = (ssize_t) (i - blen + 1);
+ size_t j, k;
+
+ // These are the start indices.
+ j = (size_t) BC_MAX(0, sidx);
+ k = BC_MIN(i, blen - 1);
+
+ // On every iteration of this loop, a multiplication happens, then the
+ // sum is automatically calculated.
+ 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;
+ }
+ }
+
+ // Calculate the carry.
+ if (sum >= BC_BASE_POW) {
+ carry += sum / BC_BASE_POW;
+ sum %= BC_BASE_POW;
+ }
+
+ // Store and set up for next iteration.
+ 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;
+}
+
+/**
+ * Does a shifted add or subtract for Karatsuba below. This calls either
+ * bc_num_addArrays() or bc_num_subArrays().
+ * @param n An in/out parameter; the first operand and return parameter.
+ * @param a The second operand.
+ * @param shift The amount to shift @a n by when adding/subtracting.
+ * @param op The function to call, either bc_num_addArrays() or
+ * bc_num_subArrays().
+ */
+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);
+}
+
+/**
+ * Implements the Karatsuba algorithm.
+ */
+static void bc_num_k(const BcNum *a, const 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;
+ }
+
+ // Shell out to the simple algorithm with certain conditions.
+ if (a->len < BC_NUM_KARATSUBA_LEN || b->len < BC_NUM_KARATSUBA_LEN) {
+ bc_num_m_simp(a, b, c);
+ return;
+ }
+
+ // We need to calculate the max size of the numbers that can result from the
+ // operations.
+ max = BC_MAX(a->len, b->len);
+ max = BC_MAX(max, BC_NUM_DEF_SIZE);
+ max2 = (max + 1) / 2;
+
+ // Calculate the space needed for all of the temporary allocations. We do
+ // this to just allocate once.
+ total = bc_vm_arraySize(BC_NUM_KARATSUBA_ALLOCS, max);
+
+ BC_SIG_LOCK;
+
+ // Allocate space for all of the temporaries.
+ digs = dig_ptr = bc_vm_malloc(BC_NUM_SIZE(total));
+
+ // Set up the temporaries.
+ 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);
+
+ // Some temporaries need the ability to grow, so we allocate them
+ // separately.
+ 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;
+
+ // First, set up c.
+ bc_num_expand(c, max);
+ c->len = max;
+ memset(c->num, 0, BC_NUM_SIZE(c->len));
+
+ // Split the parameters.
+ bc_num_split(a, max2, &l1, &h1);
+ bc_num_split(b, max2, &l2, &h2);
+
+ // Do the subtraction.
+ bc_num_sub(&h1, &l1, &m1, 0);
+ bc_num_sub(&l2, &h2, &m2, 0);
+
+ // The if statements below are there for efficiency reasons. The best way to
+ // understand them is to understand the Karatsuba algorithm because now that
+ // the ollocations and splits are done, the algorithm is pretty
+ // straightforward.
+
+ 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;
+}
+
+/**
+ * Does checks for Karatsuba. It also changes things to ensure that the
+ * Karatsuba and simple multiplication can treat the numbers as integers. This
+ * is a BcNumBinOp function.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ */
+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;
+
+ // This sets the final scale according to the bc spec.
+ scale = BC_MAX(scale, ascale);
+ scale = BC_MAX(scale, bscale);
+ rscale = ascale + bscale;
+ scale = BC_MIN(rscale, scale);
+
+ // If this condition is true, we can use bc_num_mulArray(), which would be
+ // much faster.
+ if ((a->len == 1 || b->len == 1) && !a->rdx && !b->rdx) {
+
+ BcNum *operand;
+ BcBigDig dig;
+
+ // Set the correct operands.
+ 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);
+
+ // Need to make sure the sign is correct.
+ 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;
+
+ // We need copies because of all of the mutation needed to make Karatsuba
+ // think the numbers are integers.
+ 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));
+
+ // These are what makes them appear like integers.
+ 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;
+
+ // We want to ignore zero limbs.
+ 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);
+
+ // The return parameter needs to have its scale set. This is the start. It
+ // also needs to be shifted by the same amount as a and b have limbs after
+ // the decimal point.
+ zero = bc_vm_growSize(azero, bzero);
+ len = bc_vm_growSize(c->len, zero);
+
+ bc_num_expand(c, len);
+
+ // Shift c based on the limbs after the decimal point in a and b.
+ 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;
+}
+
+/**
+ * Returns true if the BcDig array has non-zero limbs, false otherwise.
+ * @param a The array to test.
+ * @param len The length of the array.
+ * @return True if @a has any non-zero limbs, false otherwise.
+ */
+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;
+}
+
+/**
+ * Compares a BcDig array against a BcNum. This is especially suited for
+ * division. Returns >0 if @a a is greater than @a b, <0 if it is less, and =0
+ * if they are equal.
+ * @param a The array.
+ * @param b The number.
+ * @param len The length to assume the arrays are. This is always less than the
+ * actual length because of how this is implemented.
+ */
+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;
+}
+
+/**
+ * Extends the two operands of a division by BC_BASE_DIGS minus the number of
+ * digits in the divisor estimate. In other words, it is shifting the numbers in
+ * order to force the divisor estimate to fill the limb.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param divisor The divisor estimate.
+ */
+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);
+}
+
+/**
+ * Actually does division. This is a rewrite of my original code by Stefan Esser
+ * from FreeBSD.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ */
+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);
+
+ // This is a final time to make sure c is big enough and that its array is
+ // properly zeroed.
+ bc_num_expand(c, a->len);
+ memset(c->num, 0, c->cap * sizeof(BcDig));
+
+ // Setup.
+ BC_NUM_RDX_SET(c, BC_NUM_RDX_VAL(a));
+ c->scale = a->scale;
+ c->len = a->len;
+
+ // This is pulling the most significant limb of b in order to establish a
+ // good "estimate" for the actual divisor.
+ divisor = (BcBigDig) b->num[len - 1];
+
+ // The entire bit of code in this if statement is to tighten the estimate of
+ // the divisor. The condition asks if b has any other non-zero limbs.
+ if (len > 1 && bc_num_nonZeroDig(b->num, len - 1)) {
+
+ // This takes a little bit of understanding. The "10*BC_BASE_DIGS/6+1"
+ // results in either 16 for 64-bit 9-digit limbs or 7 for 32-bit 4-digit
+ // limbs. Then it shifts a 1 by that many, which in both cases, puts the
+ // result above *half* of the max value a limb can store. Basically,
+ // this quickly calculates if the divisor is greater than half the max
+ // of a limb.
+ nonzero = (divisor > 1 << ((10 * BC_BASE_DIGS) / 6 + 1));
+
+ // If the divisor is *not* greater than half the limb...
+ if (!nonzero) {
+
+ // Extend the parameters by the number of missing digits in the
+ // divisor.
+ bc_num_divExtend(a, b, divisor);
+
+ // Check bc_num_d(). In there, we grow a again and again. We do it
+ // again here; we *always* want to be sure it is big enough.
+ len = BC_MAX(a->len, b->len);
+ bc_num_expand(a, len + 1);
+
+ // Make a have a zero most significant limb to match the len.
+ if (len + 1 > a->len) a->len = len + 1;
+
+ // Grab the new divisor estimate, new because the shift has made it
+ // different.
+ len = b->len;
+ end = a->len - len;
+ divisor = (BcBigDig) b->num[len - 1];
+
+ nonzero = bc_num_nonZeroDig(b->num, len - 1);
+ }
+ }
+
+ // If b has other nonzero limbs, we want the divisor to be one higher, so
+ // that it is an upper bound.
+ divisor += nonzero;
+
+ // Make sure c can fit the new length.
+ 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;
+
+ // This is the actual division loop.
+ for (i = end - 1; 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);
+
+ // This is true if n is greater than b, which means that division can
+ // proceed, so this inner loop is the part that implements one instance
+ // of the division.
+ while (cmp >= 0) {
+
+ BcBigDig n1, dividend, quotient;
+
+ // These should be named obviously enough. Just imagine that it's a
+ // division of one limb. Because that's what it is.
+ n1 = (BcBigDig) n[len];
+ dividend = n1 * BC_BASE_POW + (BcBigDig) n[len - 1];
+ quotient = (dividend / divisor);
+
+ // If this is true, then we can just subtract. Remember: setting
+ // quotient to 1 is not bad because we already know that n is
+ // greater than b.
+ if (quotient <= 1) {
+ quotient = 1;
+ bc_num_subArrays(n, b->num, len);
+ }
+ else {
+
+ assert(quotient <= BC_BASE_POW);
+
+ // We need to multiply and subtract for a quotient above 1.
+ bc_num_mulArray(b, (BcBigDig) quotient, &cpb);
+ bc_num_subArrays(n, cpb.num, cpb.len);
+ }
+
+ // The result is the *real* quotient, by the way, but it might take
+ // multiple trips around this loop to get it.
+ result += quotient;
+ assert(result <= BC_BASE_POW);
+
+ // And here's why it might take multiple trips: n might *still* be
+ // greater than b. So we have to loop again. That's what this is
+ // setting up for: the condition of the while loop.
+ if (nonzero) cmp = bc_num_divCmp(n, b, len);
+ else cmp = -1;
+ }
+
+ assert(result < BC_BASE_POW);
+
+ // Store the actual limb quotient.
+ c->num[i] = (BcDig) result;
+ }
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&cpb);
+ BC_LONGJMP_CONT;
+}
+
+/**
+ * Implements division. This is a BcNumBinOp function.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ */
+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_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 this is true, we can use bc_num_divArray(), which would be faster.
+ 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;
+
+ // Initialize copies of the parameters. We want the length of the first
+ // operand copy to be as big as the result because of the way the division
+ // is implemented.
+ 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;
+
+ // Like the above comment, we want the copy of the first parameter to be
+ // larger than the second parameter.
+ 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;
+
+ // This is just setting up the scale in preparation for the division.
+ 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;
+
+ // Once again, just setting things up, this time to match scale.
+ if (scale > cpa.scale) {
+ bc_num_extend(&cpa, scale);
+ cpardx = BC_NUM_RDX_VAL_NP(cpa);
+ cpa.scale = cpardx * BC_BASE_DIGS;
+ }
+
+ // Grow if necessary.
+ 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;
+
+ // Still setting things up. Why all of these things are needed is not
+ // something that can be easily explained, but it has to do with making the
+ // actual algorithm easier to understand because it can assume a lot of
+ // things. Thus, you should view all of this setup code as establishing
+ // assumptions for bc_num_d_long(), where the actual division happens.
+ 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;
+}
+
+/**
+ * Implements divmod. This is the actual modulus function; since modulus
+ * requires a division anyway, this returns the quotient and modulus. Either can
+ * be thrown out as desired.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter for the quotient.
+ * @param d The return parameter for the modulus.
+ * @param scale The current scale.
+ * @param ts The scale that the operation should be done to. Yes, it's not
+ * necessarily the same as scale, per the bc spec.
+ */
+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_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;
+
+ // Division.
+ bc_num_d(a, b, c, scale);
+
+ // We want an extra digit so we can safely truncate.
+ if (scale) scale = ts + 1;
+
+ assert(BC_NUM_RDX_VALID(c));
+ assert(BC_NUM_RDX_VALID(b));
+
+ // Implement the rest of the (a - (a / b) * b) formula.
+ bc_num_m(c, b, &temp, scale);
+ bc_num_sub(a, &temp, d, scale);
+
+ // Extend if necessary.
+ 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;
+}
+
+/**
+ * Implements modulus/remainder. (Yes, I know they are different, but not in the
+ * context of bc.) This is a BcNumBinOp function.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ */
+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;
+
+ // Need a temp for the quotient.
+ 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;
+}
+
+/**
+ * Implements power (exponentiation). This is a BcNumBinOp function.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ */
+static void bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcNum copy, btemp;
+ BcBigDig exp;
+ size_t powrdx, resrdx;
+ bool neg;
+
+ if (BC_ERR(bc_num_nonInt(b, &btemp))) bc_err(BC_ERR_MATH_NON_INTEGER);
+
+ if (BC_NUM_ZERO(&btemp)) {
+ bc_num_one(c);
+ return;
+ }
+
+ if (BC_NUM_ZERO(a)) {
+ if (BC_NUM_NEG_NP(btemp)) bc_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
+ bc_num_setToZero(c, scale);
+ return;
+ }
+
+ if (BC_NUM_ONE(&btemp)) {
+ if (!BC_NUM_NEG_NP(btemp)) bc_num_copy(c, a);
+ else bc_num_inv(a, c, scale);
+ return;
+ }
+
+ neg = BC_NUM_NEG_NP(btemp);
+ BC_NUM_NEG_CLR_NP(btemp);
+
+ exp = bc_num_bigdig(&btemp);
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&copy, a);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ // If this is true, then we do not have to do a division, and we need to
+ // set scale accordingly.
+ if (!neg) {
+ size_t max = BC_MAX(scale, a->scale), scalepow;
+ scalepow = bc_num_mulOverflow(a->scale, exp);
+ scale = BC_MIN(scalepow, max);
+ }
+
+ // This is only implementing the first exponentiation by squaring, until it
+ // reaches the first time where the square is actually used.
+ for (powrdx = a->scale; !(exp & 1); exp >>= 1) {
+ powrdx <<= 1;
+ assert(BC_NUM_RDX_VALID_NP(copy));
+ bc_num_mul(&copy, &copy, &copy, powrdx);
+ }
+
+ // Make c a copy of copy for the purpose of saving the squares that should
+ // be saved.
+ bc_num_copy(c, &copy);
+ resrdx = powrdx;
+
+ // Now finish the exponentiation by squaring, this time saving the squares
+ // as necessary.
+ while (exp >>= 1) {
+
+ powrdx <<= 1;
+ assert(BC_NUM_RDX_VALID_NP(copy));
+ bc_num_mul(&copy, &copy, &copy, powrdx);
+
+ // If this is true, we want to save that particular square. This does
+ // that by multiplying c with copy.
+ if (exp & 1) {
+ resrdx += powrdx;
+ assert(BC_NUM_RDX_VALID(c));
+ assert(BC_NUM_RDX_VALID_NP(copy));
+ bc_num_mul(c, &copy, c, resrdx);
+ }
+ }
+
+ // Invert if necessary.
+ if (neg) bc_num_inv(c, c, scale);
+
+ // Truncate if necessary.
+ if (c->scale > scale) bc_num_truncate(c, c->scale - scale);
+
+ bc_num_clean(c);
+
+err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&copy);
+ BC_LONGJMP_CONT;
+}
+
+#if BC_ENABLE_EXTRA_MATH
+/**
+ * Implements the places operator. This is a BcNumBinOp function.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ */
+static void bc_num_place(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcBigDig val;
+
+ BC_UNUSED(scale);
+
+ val = bc_num_intop(a, b, c);
+
+ // Just truncate or extend as appropriate.
+ if (val < c->scale) bc_num_truncate(c, c->scale - val);
+ else if (val > c->scale) bc_num_extend(c, val - c->scale);
+}
+
+/**
+ * Implements the left shift operator. This is a BcNumBinOp function.
+ */
+static void bc_num_left(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcBigDig val;
+
+ BC_UNUSED(scale);
+
+ val = bc_num_intop(a, b, c);
+
+ bc_num_shiftLeft(c, (size_t) val);
+}
+
+/**
+ * Implements the right shift operator. This is a BcNumBinOp function.
+ */
+static void bc_num_right(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) {
+
+ BcBigDig val;
+
+ BC_UNUSED(scale);
+
+ val = bc_num_intop(a, b, c);
+
+ if (BC_NUM_ZERO(c)) return;
+
+ bc_num_shiftRight(c, (size_t) val);
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * Prepares for, and calls, a binary operator function. This is probably the
+ * most important function in the entire file because it establishes assumptions
+ * that make the rest of the code so easy. Those assumptions include:
+ *
+ * - a is not the same pointer as c.
+ * - b is not the same pointer as c.
+ * - there is enough room in c for the result.
+ *
+ * Without these, this whole function would basically have to be duplicated for
+ * *all* binary operators.
+ *
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param c The return parameter.
+ * @param scale The current scale.
+ * @param req The number of limbs needed to fit the result.
+ */
+static void bc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale,
+ BcNumBinOp 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;
+
+ // Reallocate if c == a.
+ if (c == a) {
+
+ ptr_a = &num2;
+
+ memcpy(ptr_a, c, sizeof(BcNum));
+ init = true;
+ }
+ else {
+ ptr_a = a;
+ }
+
+ // Also reallocate if c == b.
+ if (c == b) {
+
+ ptr_b = &num2;
+
+ if (c != a) {
+ memcpy(ptr_b, c, sizeof(BcNum));
+ init = true;
+ }
+ }
+ else {
+ ptr_b = b;
+ }
+
+ // Actually reallocate. If we don't reallocate, we want to expand at the
+ // very least.
+ if (init) {
+
+ bc_num_init(c, req);
+
+ // Must prepare for cleanup. We want this here so that locals that got
+ // set stay set since a longjmp() is not guaranteed to preserve locals.
+ BC_SETJMP_LOCKED(err);
+ BC_SIG_UNLOCK;
+ }
+ else {
+ BC_SIG_UNLOCK;
+ bc_num_expand(c, req);
+ }
+
+ // It is okay for a and b to be the same. If a binary operator function does
+ // need them to be different, the binary operator function is responsible
+ // for that.
+
+ // Call the actual binary operator function.
+ 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:
+ // Cleanup only needed if we initialized c to a new number.
+ if (init) {
+ BC_SIG_MAYLOCK;
+ bc_num_free(&num2);
+ BC_LONGJMP_CONT;
+ }
+}
+
+#if !defined(NDEBUG) || BC_ENABLE_LIBRARY
+
+/**
+ * Tests a number string for validity. This function has a history; I originally
+ * wrote it because I did not trust my parser. Over time, however, I came to
+ * trust it, so I was able to relegate this function to debug builds only, and I
+ * used it in assert()'s. But then I created the library, and well, I can't
+ * trust users, so I reused this for yelling at users.
+ * @param val The string to check to see if it's a valid number string.
+ * @return True if the string is a valid number string, false otherwise.
+ */
+bool bc_num_strValid(const char *restrict val) {
+
+ bool radix = false;
+ size_t i, len = strlen(val);
+
+ // Notice that I don't check if there is a negative sign. That is not part
+ // of a valid number, except in the library. The library-specific code takes
+ // care of that part.
+
+ // Nothing in the string is okay.
+ if (!len) return true;
+
+ // Loop through the characters.
+ for (i = 0; i < len; ++i) {
+
+ BcDig c = val[i];
+
+ // If we have found a radix point...
+ if (c == '.') {
+
+ // We don't allow two radices.
+ if (radix) return false;
+
+ radix = true;
+ continue;
+ }
+
+ // We only allow digits and uppercase letters.
+ if (!(isdigit(c) || isupper(c))) return false;
+ }
+
+ return true;
+}
+#endif // !defined(NDEBUG) || BC_ENABLE_LIBRARY
+
+/**
+ * Parses one character and returns the digit that corresponds to that
+ * character according to the base.
+ * @param c The character to parse.
+ * @param base The base.
+ * @return The character as a digit.
+ */
+static BcBigDig bc_num_parseChar(char c, size_t base) {
+
+ assert(isupper(c) || isdigit(c));
+
+ // If a letter...
+ if (isupper(c)) {
+
+ // This returns the digit that directly corresponds with the letter.
+ c = BC_NUM_NUM_LETTER(c);
+
+ // If the digit is greater than the base, we clamp.
+ c = ((size_t) c) >= base ? (char) base - 1 : c;
+ }
+ // Straight convert the digit to a number.
+ else c -= '0';
+
+ return (BcBigDig) (uchar) c;
+}
+
+/**
+ * Parses a string as a decimal number. This is separate because it's going to
+ * be the most used, and it can be heavily optimized for decimal only.
+ * @param n The number to parse into and return. Must be preallocated.
+ * @param val The string to parse.
+ */
+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;
+
+ // Eat leading zeroes.
+ 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;
+
+ // The length of the string is the length of the number, except it might be
+ // one bigger because of a decimal point.
+ len = strlen(val);
+
+ // Find the location of the decimal point.
+ ptr = strchr(val, '.');
+ rdx = (ptr != NULL);
+
+ // We eat leading zeroes again. These leading zeroes are different because
+ // they will come after the decimal point if they exist, and since that's
+ // the case, they must be preserved.
+ for (i = 0; i < len && (zero = (val[i] == '0' || val[i] == '.')); ++i);
+
+ // Set the scale of the number based on the location of the decimal point.
+ // The casts to uintptr_t is to ensure that bc does not hit undefined
+ // behavior when doing math on the values.
+ n->scale = (size_t) (rdx * (((uintptr_t) (val + len)) -
+ (((uintptr_t) ptr) + 1)));
+
+ // Set rdx.
+ BC_NUM_RDX_SET(n, BC_NUM_RDX(n->scale));
+
+ // Calculate length. First, the length of the integer, then the number of
+ // digits in the last limb, then the length.
+ 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);
+
+ // Expand and zero.
+ 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 {
+
+ // There is actually stuff to parse if we make it here. Yay...
+ BcBigDig exp, pow;
+
+ assert(i <= BC_NUM_BIGDIG_MAX);
+
+ // The exponent and power.
+ exp = (BcBigDig) i;
+ pow = bc_num_pow10[exp];
+
+ // Parse loop. We parse backwards because numbers are stored little
+ // endian.
+ for (i = len - 1; i < len; --i, ++exp) {
+
+ char c = val[i];
+
+ // Skip the decimal point.
+ if (c == '.') exp -= 1;
+ else {
+
+ // The index of the limb.
+ size_t idx = exp / BC_BASE_DIGS;
+
+ // Clamp for the base.
+ if (isupper(c)) c = '9';
+
+ // Add the digit to the limb.
+ n->num[idx] += (((BcBigDig) c) - '0') * pow;
+
+ // Adjust the power and exponent.
+ if ((exp + 1) % BC_BASE_DIGS == 0) pow = 1;
+ else pow *= BC_BASE;
+ }
+ }
+ }
+}
+
+/**
+ * Parse a number in any base (besides decimal).
+ * @param n The number to parse into and return. Must be preallocated.
+ * @param val The string to parse.
+ * @param base The base to parse as.
+ */
+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);
+
+ // If zero, just return because the number should be virgin (already 0).
+ 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;
+
+ // We split parsing into parsing the integer and parsing the fractional
+ // part.
+
+ // Parse the integer part. This is the easy part because we just multiply
+ // the number by the base, then add the digit.
+ for (i = 0; i < len && (c = val[i]) && c != '.'; ++i) {
+
+ // Convert the character to a digit.
+ v = bc_num_parseChar(c, base);
+
+ // Multiply the number.
+ bc_num_mulArray(n, base, &mult1);
+
+ // Convert the digit to a number and add.
+ bc_num_bigdig2num(&temp, v);
+ bc_num_add(&mult1, &temp, n, 0);
+ }
+
+ // If this condition is true, then we are done. We still need to do cleanup
+ // though.
+ if (i == len && !val[i]) goto int_err;
+
+ // If we get here, we *must* be at the radix point.
+ assert(val[i] == '.');
+
+ BC_SIG_LOCK;
+
+ // Unset the jump to reset in for these new initializations.
+ 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;
+
+ // Pointers for easy switching.
+ m1 = &mult1;
+ m2 = &mult2;
+
+ // Parse the fractional part. This is the hard part.
+ for (i += 1, digs = 0; i < len && (c = val[i]); ++i, ++digs) {
+
+ size_t rdx;
+
+ // Convert the character to a digit.
+ v = bc_num_parseChar(c, base);
+
+ // We keep growing result2 according to the base because the more digits
+ // after the radix, the more significant the digits close to the radix
+ // should be.
+ bc_num_mulArray(&result1, base, &result2);
+
+ // Convert the digit to a number.
+ bc_num_bigdig2num(&temp, v);
+
+ // Add the digit into the fraction part.
+ bc_num_add(&result2, &temp, &result1, 0);
+
+ // Keep growing m1 and m2 for use after the loop.
+ bc_num_mulArray(m1, base, m2);
+
+ rdx = BC_NUM_RDX_VAL(m2);
+
+ if (m2->len < rdx) m2->len = rdx;
+
+ // Switch.
+ 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. And this
+ // is the reason we keep growing m1 and m2; this division is what converts
+ // the parsed fractional part from an integer to a fractional part.
+ bc_num_div(&result1, m1, &result2, digs * 2);
+
+ // Pretruncate.
+ bc_num_truncate(&result2, digs);
+
+ // The final add of the integer part to the fractional part.
+ bc_num_add(n, &result2, n, digs);
+
+ // Basic cleanup.
+ 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;
+}
+
+/**
+ * Prints a backslash+newline combo if the number of characters needs it. This
+ * is really a convenience function.
+ */
+static inline void bc_num_printNewline(void) {
+#if !BC_ENABLE_LIBRARY
+ if (vm.nchars >= vm.line_len - 1 && vm.line_len) {
+ bc_vm_putchar('\\', bc_flush_none);
+ bc_vm_putchar('\n', bc_flush_err);
+ }
+#endif // !BC_ENABLE_LIBRARY
+}
+
+/**
+ * Prints a character after a backslash+newline, if needed.
+ * @param c The character to print.
+ * @param bslash Whether to print a backslash+newline.
+ */
+static void bc_num_putchar(int c, bool bslash) {
+ if (c != '\n' && bslash) bc_num_printNewline();
+ bc_vm_putchar(c, bc_flush_save);
+}
+
+#if !BC_ENABLE_LIBRARY
+
+/**
+ * Prints a character for a number's digit. This is for printing for dc's P
+ * command. This function does not need to worry about radix points. This is a
+ * BcNumDigitOp.
+ * @param n The "digit" to print.
+ * @param len The "length" of the digit, or number of characters that will
+ * need to be printed for the digit.
+ * @param rdx True if a decimal (radix) point should be printed.
+ * @param bslash True if a backslash+newline should be printed if the character
+ * limit for the line is reached, false otherwise.
+ */
+static void bc_num_printChar(size_t n, size_t len, bool rdx, bool bslash) {
+ BC_UNUSED(rdx);
+ BC_UNUSED(len);
+ BC_UNUSED(bslash);
+ assert(len == 1);
+ bc_vm_putchar((uchar) n, bc_flush_save);
+}
+
+#endif // !BC_ENABLE_LIBRARY
+
+/**
+ * Prints a series of characters for large bases. This is for printing in bases
+ * above hexadecimal. This is a BcNumDigitOp.
+ * @param n The "digit" to print.
+ * @param len The "length" of the digit, or number of characters that will
+ * need to be printed for the digit.
+ * @param rdx True if a decimal (radix) point should be printed.
+ * @param bslash True if a backslash+newline should be printed if the character
+ * limit for the line is reached, false otherwise.
+ */
+static void bc_num_printDigits(size_t n, size_t len, bool rdx, bool bslash) {
+
+ size_t exp, pow;
+
+ // If needed, print the radix; otherwise, print a space to separate digits.
+ bc_num_putchar(rdx ? '.' : ' ', true);
+
+ // Calculate the exponent and power.
+ for (exp = 0, pow = 1; exp < len - 1; ++exp, pow *= BC_BASE);
+
+ // Print each character individually.
+ for (exp = 0; exp < len; pow /= BC_BASE, ++exp) {
+
+ // The individual subdigit.
+ size_t dig = n / pow;
+
+ // Take the subdigit away.
+ n -= dig * pow;
+
+ // Print the subdigit.
+ bc_num_putchar(((uchar) dig) + '0', bslash || exp != len - 1);
+ }
+}
+
+/**
+ * Prints a character for a number's digit. This is for printing in bases for
+ * hexadecimal and below because they always print only one character at a time.
+ * This is a BcNumDigitOp.
+ * @param n The "digit" to print.
+ * @param len The "length" of the digit, or number of characters that will
+ * need to be printed for the digit.
+ * @param rdx True if a decimal (radix) point should be printed.
+ * @param bslash True if a backslash+newline should be printed if the character
+ * limit for the line is reached, false otherwise.
+ */
+static void bc_num_printHex(size_t n, size_t len, bool rdx, bool bslash) {
+
+ BC_UNUSED(len);
+ BC_UNUSED(bslash);
+
+ assert(len == 1);
+
+ if (rdx) bc_num_putchar('.', true);
+
+ bc_num_putchar(bc_num_hex_digits[n], bslash);
+}
+
+/**
+ * Prints a decimal number. This is specially written for optimization since
+ * this will be used the most and because bc's numbers are already in decimal.
+ * @param n The number to print.
+ * @param newline Whether to print backslash+newlines on long enough lines.
+ */
+static void bc_num_printDecimal(const BcNum *restrict n, bool newline) {
+
+ size_t i, j, rdx = BC_NUM_RDX_VAL(n);
+ bool zero = true;
+ size_t buffer[BC_BASE_DIGS];
+
+ // Print loop.
+ for (i = n->len - 1; i < n->len; --i) {
+
+ BcDig n9 = n->num[i];
+ size_t temp;
+ bool irdx = (i == rdx - 1);
+
+ // Calculate the number of digits in the limb.
+ 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));
+
+ // Fill the buffer with individual digits.
+ for (j = 0; n9 && j < BC_BASE_DIGS; ++j) {
+ buffer[j] = ((size_t) n9) % BC_BASE;
+ n9 /= BC_BASE;
+ }
+
+ // Print the digits in the buffer.
+ for (j = BC_BASE_DIGS - 1; j < BC_BASE_DIGS && j >= temp; --j) {
+
+ // Figure out whether to print the decimal point.
+ bool print_rdx = (irdx & (j == BC_BASE_DIGS - 1));
+
+ // The zero variable helps us skip leading zero digits in the limb.
+ zero = (zero && buffer[j] == 0);
+
+ if (!zero) {
+
+ // While the first three arguments should be self-explanatory,
+ // the last needs explaining. I don't want to print a newline
+ // when the last digit to be printed could take the place of the
+ // backslash rather than being pushed, as a single character, to
+ // the next line. That's what that last argument does for bc.
+ bc_num_printHex(buffer[j], 1, print_rdx,
+ !newline || (j > temp || i != 0));
+ }
+ }
+ }
+}
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * Prints a number in scientific or engineering format. When doing this, we are
+ * always printing in decimal.
+ * @param n The number to print.
+ * @param eng True if we are in engineering mode.
+ * @param newline Whether to print backslash+newlines on long enough lines.
+ */
+static void bc_num_printExponent(const BcNum *restrict n,
+ bool eng, bool newline)
+{
+ 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;
+
+ // We need to calculate the exponents, and they change based on whether the
+ // number is all fractional or not, obviously.
+ if (neg) {
+
+ // Figure out how many limbs after the decimal point is zero.
+ size_t i, idx = bc_num_nonZeroLen(n) - 1;
+
+ places = 1;
+
+ // Figure out how much in the last limb is zero.
+ for (i = BC_BASE_DIGS - 1; i < BC_BASE_DIGS; --i) {
+ if (bc_num_pow10[i] > (BcBigDig) n->num[idx]) places += 1;
+ else break;
+ }
+
+ // Calculate the combination of zero limbs and zero digits in the last
+ // limb.
+ places += (nrdx - (idx + 1)) * BC_BASE_DIGS;
+ mod = places % 3;
+
+ // Calculate places if we are in engineering mode.
+ if (eng && mod != 0) places += 3 - mod;
+
+ // Shift the temp to the right place.
+ bc_num_shiftLeft(&temp, places);
+ }
+ else {
+
+ // This is the number of digits that we are supposed to put behind the
+ // decimal point.
+ places = bc_num_intDigits(n) - 1;
+
+ // Calculate the true number based on whether engineering mode is
+ // activated.
+ mod = places % 3;
+ if (eng && mod != 0) places -= 3 - (3 - mod);
+
+ // Shift the temp to the right place.
+ bc_num_shiftRight(&temp, places);
+ }
+
+ // Print the shifted number.
+ bc_num_printDecimal(&temp, newline);
+
+ // Print the e.
+ bc_num_putchar('e', !newline);
+
+ // Need to explicitly print a zero exponent.
+ if (!places) {
+ bc_num_printHex(0, 1, false, !newline);
+ goto exit;
+ }
+
+ // Need to print sign for the exponent.
+ if (neg) bc_num_putchar('-', true);
+
+ // Create a temporary for the exponent...
+ bc_num_setup(&exp, digs, BC_NUM_BIGDIG_LOG10);
+ bc_num_bigdig2num(&exp, (BcBigDig) places);
+
+ /// ..and print it.
+ bc_num_printDecimal(&exp, newline);
+
+exit:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&temp);
+ BC_LONGJMP_CONT;
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * Converts a number from limbs with base BC_BASE_POW to base @a pow, where
+ * @a pow is obase^N.
+ * @param n The number to convert.
+ * @param rem BC_BASE_POW - @a pow.
+ * @param pow The power of obase we will convert the number to.
+ * @param idx The index of the number to start converting at. Doing the
+ * conversion is O(n^2); we have to sweep through starting at the
+ * least significant limb
+ */
+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;
+
+ // Ignore if there's just one limb left. This is the part that requires the
+ // extra loop after the one calling this function in bc_num_printPrepare().
+ if (len < 2) return;
+
+ // Loop through the remaining limbs and convert. We start at the second limb
+ // because we pull the value from the previous one as well.
+ for (i = len - 1; i > 0; --i) {
+
+ // Get the limb and add it to the previous, along with multiplying by
+ // the remainder because that's the proper overflow. "acc" means
+ // "accumulator," by the way.
+ acc = ((BcBigDig) a[i]) * rem + ((BcBigDig) a[i - 1]);
+
+ // Store a value in base pow in the previous limb.
+ a[i - 1] = (BcDig) (acc % pow);
+
+ // Divide by the base and accumulate the remaining value in the limb.
+ acc /= pow;
+ acc += (BcBigDig) a[i];
+
+ // If the accumulator is greater than the base...
+ if (acc >= BC_BASE_POW) {
+
+ // Do we need to grow?
+ if (i == len - 1) {
+
+ // Grow.
+ len = bc_vm_growSize(len, 1);
+ bc_num_expand(n, bc_vm_growSize(len, idx));
+
+ // Update the pointer because it may have moved.
+ a = n->num + idx;
+
+ // Zero out the last limb.
+ a[len - 1] = 0;
+ }
+
+ // Overflow into the next limb since we are over the base.
+ a[i + 1] += acc / BC_BASE_POW;
+ acc %= BC_BASE_POW;
+ }
+
+ assert(acc < BC_BASE_POW);
+
+ // Set the limb.
+ a[i] = (BcDig) acc;
+ }
+
+ // We may have grown the number, so adjust the length.
+ n->len = len + idx;
+}
+
+/**
+ * Prepares a number for printing in a base that is not a divisor of
+ * BC_BASE_POW. This basically converts the number from having limbs of base
+ * BC_BASE_POW to limbs of pow, where pow is obase^N.
+ * @param n The number to prepare for printing.
+ * @param rem The remainder of BC_BASE_POW when divided by a power of the base.
+ * @param pow The power of the base.
+ */
+static void bc_num_printPrepare(BcNum *restrict n, BcBigDig rem, BcBigDig pow) {
+
+ size_t i;
+
+ // Loop from the least significant limb to the most significant limb and
+ // convert limbs in each pass.
+ for (i = 0; i < n->len; ++i) bc_num_printFixup(n, rem, pow, i);
+
+ // bc_num_printFixup() does not do everything it is supposed to, so we do
+ // the last bit of cleanup here. That cleanup is to ensure that each limb
+ // is less than pow and to expand the number to fit new limbs as necessary.
+ for (i = 0; i < n->len; ++i) {
+
+ assert(pow == ((BcBigDig) ((BcDig) pow)));
+
+ // If the limb needs fixing...
+ if (n->num[i] >= (BcDig) pow) {
+
+ // Do we need to grow?
+ if (i + 1 == n->len) {
+
+ // Grow the number.
+ n->len = bc_vm_growSize(n->len, 1);
+ bc_num_expand(n, n->len);
+
+ // Without this, we might use uninitialized data.
+ n->num[i + 1] = 0;
+ }
+
+ assert(pow < BC_BASE_POW);
+
+ // Overflow into the next limb.
+ 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, bool newline)
+{
+ BcVec stack;
+ BcNum intp, fracp1, fracp2, digit, flen1, flen2, *n1, *n2, *temp;
+ BcBigDig dig = 0, *ptr, acc, exp;
+ size_t i, j, nrdx, idigits;
+ bool radix;
+ BcDig digit_digs[BC_NUM_BIGDIG_LOG10 + 1];
+
+ assert(base > 1);
+
+ // Easy case. Even with scale, we just print this.
+ if (BC_NUM_ZERO(n)) {
+ print(0, len, false, !newline);
+ 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 limb (after intp has
+ // been converted to an integer) and the next to least significant limb, and
+ // it converts the least significant limb into one of the specified base,
+ // putting any overflow into the next to least significant limb. It iterates
+ // through the whole number, from least significant to most significant,
+ // doing this conversion. At the end of that iteration, the least
+ // significant limb is converted, but the others are not, so it iterates
+ // again, starting at the next to least significant limb. It keeps doing
+ // that conversion, skipping one more limb than the last time, until all
+ // limbs 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 limbs 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. In other words, bc_num_printPrepare() is where the
+ // loop that starts at the least significant limb and goes to the most
+ // significant limb. Then, on every iteration of its loop, it calls
+ // bc_num_printFixup(), which has the inner loop of actually converting
+ // the limbs it passes into limbs of base obase^N rather than base
+ // BC_BASE_POW.
+
+ nrdx = BC_NUM_RDX_VAL(n);
+
+ BC_SIG_LOCK;
+
+ // The stack is what allows us to reverse the digits for printing.
+ bc_vec_init(&stack, sizeof(BcBigDig), BC_DTOR_NONE);
+ bc_num_init(&fracp1, nrdx);
+
+ // intp will be the "integer part" of the number, so copy it.
+ bc_num_createCopy(&intp, n);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ // Make intp an integer.
+ bc_num_truncate(&intp, intp.scale);
+
+ // Get the fractional part out.
+ bc_num_sub(n, &intp, &fracp1, 0);
+
+ // If the base is not the same as the last base used for printing, we need
+ // to update the cached exponent and power. Yes, we cache the values of the
+ // exponent and power. That is to prevent us from calculating them every
+ // time because printing will probably happen multiple times on the same
+ // base.
+ if (base != vm.last_base) {
+
+ vm.last_pow = 1;
+ vm.last_exp = 0;
+
+ // Calculate the exponent and power.
+ while (vm.last_pow * base <= BC_BASE_POW) {
+ vm.last_pow *= base;
+ vm.last_exp += 1;
+ }
+
+ // Also, the remainder and base itself.
+ vm.last_rem = BC_BASE_POW - vm.last_pow;
+ vm.last_base = base;
+ }
+
+ exp = vm.last_exp;
+
+ // If vm.last_rem is 0, then the base we are printing in is a divisor of
+ // BC_BASE_POW, which is the easy case because it means that BC_BASE_POW is
+ // a power of obase, and no conversion is needed. If it *is* 0, then we have
+ // the hard case, and we have to prepare the number for the base.
+ if (vm.last_rem != 0) bc_num_printPrepare(&intp, vm.last_rem, vm.last_pow);
+
+ // After the conversion comes the surprisingly easy part. From here on out,
+ // this is basically naive code that I wrote, adjusted for the larger bases.
+
+ // Fill the stack of digits for the integer part.
+ for (i = 0; i < intp.len; ++i) {
+
+ // Get the limb.
+ acc = (BcBigDig) intp.num[i];
+
+ // Turn the limb into digits of base obase.
+ for (j = 0; j < exp && (i < intp.len - 1 || acc != 0); ++j)
+ {
+ // This condition is true if we are not at the last digit.
+ if (j != exp - 1) {
+ dig = acc % base;
+ acc /= base;
+ }
+ else {
+ dig = acc;
+ acc = 0;
+ }
+
+ assert(dig < base);
+
+ // Push the digit onto the stack.
+ bc_vec_push(&stack, &dig);
+ }
+
+ assert(acc == 0);
+ }
+
+ // Go through the stack backwards and print each digit.
+ for (i = 0; i < stack.len; ++i) {
+
+ ptr = bc_vec_item_rev(&stack, i);
+
+ assert(ptr != NULL);
+
+ // While the first three arguments should be self-explanatory, the last
+ // needs explaining. I don't want to print a newline when the last digit
+ // to be printed could take the place of the backslash rather than being
+ // pushed, as a single character, to the next line. That's what that
+ // last argument does for bc.
+ print(*ptr, len, false, !newline ||
+ (n->scale != 0 || i == stack.len - 1));
+ }
+
+ // We are done if there is no fractional part.
+ if (!n->scale) goto err;
+
+ BC_SIG_LOCK;
+
+ // Reset the jump because some locals are changing.
+ 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;
+
+ // Pointers for easy switching.
+ n1 = &flen1;
+ n2 = &flen2;
+
+ fracp2.scale = n->scale;
+ BC_NUM_RDX_SET_NP(fracp2, BC_NUM_RDX(fracp2.scale));
+
+ // As long as we have not reached the scale of the number, keep printing.
+ while ((idigits = bc_num_intDigits(n1)) <= n->scale) {
+
+ // These numbers will keep growing.
+ bc_num_expand(&fracp2, fracp1.len + 1);
+ bc_num_mulArray(&fracp1, base, &fracp2);
+
+ nrdx = BC_NUM_RDX_VAL_NP(fracp2);
+
+ // Ensure an invariant.
+ if (fracp2.len < nrdx) fracp2.len = nrdx;
+
+ // fracp is guaranteed to be non-negative and small enough.
+ dig = bc_num_bigdig2(&fracp2);
+
+ // Convert the digit to a number and subtract it from the number.
+ bc_num_bigdig2num(&digit, dig);
+ bc_num_sub(&fracp2, &digit, &fracp1, 0);
+
+ // While the first three arguments should be self-explanatory, the last
+ // needs explaining. I don't want to print a newline when the last digit
+ // to be printed could take the place of the backslash rather than being
+ // pushed, as a single character, to the next line. That's what that
+ // last argument does for bc.
+ print(dig, len, radix, !newline || idigits != n->scale);
+
+ // Update the multipliers.
+ bc_num_mulArray(n1, base, n2);
+
+ radix = false;
+
+ // Switch.
+ 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;
+}
+
+/**
+ * Prints a number in the specified base, or rather, figures out which function
+ * to call to print the number in the specified base and calls it.
+ * @param n The number to print.
+ * @param base The base to print in.
+ * @param newline Whether to print backslash+newlines on long enough lines.
+ */
+static void bc_num_printBase(BcNum *restrict n, BcBigDig base, bool newline) {
+
+ size_t width;
+ BcNumDigitOp print;
+ bool neg = BC_NUM_NEG(n);
+
+ // Clear the sign because it makes the actual printing easier when we have
+ // to do math.
+ BC_NUM_NEG_CLR(n);
+
+ // Bases at hexadecimal and below are printed as one character, larger bases
+ // are printed as a series of digits separated by spaces.
+ 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;
+ }
+
+ // Print.
+ bc_num_printNum(n, base, width, print, newline);
+
+ // Reset the sign.
+ n->rdx = BC_NUM_NEG_VAL(n, neg);
+}
+
+#if !BC_ENABLE_LIBRARY
+
+void bc_num_stream(BcNum *restrict n) {
+ bc_num_printNum(n, BC_NUM_STREAM_BASE, 1, bc_num_printChar, false);
+}
+
+#endif // !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);
+
+ // BC_NUM_DEF_SIZE is set to be about the smallest allocation size that
+ // malloc() returns in practice, so just use it.
+ req = req >= BC_NUM_DEF_SIZE ? req : BC_NUM_DEF_SIZE;
+
+ // If we can't use a temp, allocate.
+ if (req != BC_NUM_DEF_SIZE || (num = bc_vm_takeTemp()) == NULL)
+ 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_vm_addTemp(n->num);
+ 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 because the sign *and* rdx will be
+ // properly preserved.
+ 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 *restrict 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;
+
+ // Always return at least 1.
+ if (BC_NUM_ZERO(n)) return n->scale ? n->scale : 1;
+
+ // If this is true, there is no integer portion of the number.
+ if (BC_NUM_RDX_VAL(n) == len) {
+
+ // We have to take into account the fact that some of the digits right
+ // after the decimal could be zero. If that is the case, we need to
+ // ignore them until we hit the first non-zero digit.
+
+ size_t zero, scale;
+
+ // The number of limbs with non-zero digits.
+ len = bc_num_nonZeroLen(n);
+
+ // Get the number of digits in the last limb.
+ scale = n->scale % BC_BASE_DIGS;
+ scale = scale ? scale : BC_BASE_DIGS;
+
+ // Get the number of zero digits.
+ zero = bc_num_zeroDigits(n->num + len - 1);
+
+ // Calculate the true length.
+ len = len * BC_BASE_DIGS - zero - (BC_BASE_DIGS - scale);
+ }
+ // Otherwise, count the number of int digits and return that plus the 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));
+
+ // A one character number is *always* parsed as though the base was the
+ // maximum allowed ibase, per the bc spec.
+ 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);
+
+ // We may need a newline, just to start.
+ bc_num_printNewline();
+
+ if (BC_NUM_NONZERO(n)) {
+
+ // Print the sign.
+ if (BC_NUM_NEG(n)) bc_num_putchar('-', true);
+
+ // Print the leading zero if necessary.
+ if (BC_Z && BC_NUM_RDX_VAL(n) == n->len)
+ bc_num_printHex(0, 1, false, !newline);
+ }
+
+ // Short-circuit 0.
+ if (BC_NUM_ZERO(n)) bc_num_printHex(0, 1, false, !newline);
+ else if (base == BC_BASE) bc_num_printDecimal(n, newline);
+#if BC_ENABLE_EXTRA_MATH
+ else if (base == 0 || base == 1)
+ bc_num_printExponent(n, base != 0, newline);
+#endif // BC_ENABLE_EXTRA_MATH
+ else bc_num_printBase(n, base, newline);
+
+ if (newline) bc_num_putchar('\n', false);
+}
+
+BcBigDig bc_num_bigdig2(const BcNum *restrict n) {
+
+ // This function returns no errors because it's guaranteed to succeed if
+ // its preconditions are met. Those preconditions include both n needs to
+ // be 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);
+ 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];
+ }
+ }
+
+ return r;
+}
+
+BcBigDig bc_num_bigdig(const BcNum *restrict n) {
+
+ assert(n != NULL);
+
+ // This error checking is extremely important, and if you do not have a
+ // guarantee that converting a number will always succeed in a particular
+ // case, you *must* call this function to get these error checks. This
+ // includes all instances of numbers inputted by the user or calculated by
+ // the user. Otherwise, you can call the faster bc_num_bigdig2().
+ if (BC_ERR(BC_NUM_NEG(n))) bc_err(BC_ERR_MATH_NEGATIVE);
+ if (BC_ERR(bc_num_cmp(n, &vm.max) >= 0)) bc_err(BC_ERR_MATH_OVERFLOW);
+
+ return bc_num_bigdig2(n);
+}
+
+void bc_num_bigdig2num(BcNum *restrict n, BcBigDig val) {
+
+ BcDig *ptr;
+ size_t i;
+
+ assert(n != NULL);
+
+ bc_num_zero(n);
+
+ // Already 0.
+ if (!val) return;
+
+ // Expand first. This is the only way this function can fail, and it's a
+ // fatal error.
+ bc_num_expand(n, BC_NUM_BIGDIG_LOG10);
+
+ // The conversion is easy because numbers are laid out in little-endian
+ // order.
+ 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
+
+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);
+
+ // This function holds the secret of how I interpret a seed number for the
+ // PRNG. Well, it's actually in the development manual
+ // (manuals/development.md#pseudo-random-number-generator), so look there
+ // before you try to understand this.
+
+ 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));
+
+ // Multiply the fraction and truncate so that it's an integer. The
+ // truncation is what clamps it, by the way.
+ bc_num_mul(&frac, &vm.max2, &temp, 0);
+ bc_num_truncate(&temp, temp.scale);
+ bc_num_copy(&frac, &temp);
+
+ // Get the integer.
+ 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
+ // some optimizations.
+ assert(BC_NUM_NONZERO(&vm.max));
+
+ // If there *was* a fractional part...
+ if (BC_NUM_NONZERO(&frac)) {
+
+ // This divmod splits frac into the two state parts.
+ 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.
+ state1 = (BcRand) bc_num_bigdig2(&temp2);
+ state2 = (BcRand) bc_num_bigdig2(&temp);
+ }
+ else state1 = state2 = 0;
+
+ // If there *was* an integer part...
+ if (BC_NUM_NONZERO(&intn)) {
+
+ // This divmod splits intn into the two inc parts.
+ 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().
+ inc1 = (BcRand) bc_num_bigdig2(&temp2);
+
+ // Clamp the second inc part.
+ 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.
+ inc2 = (BcRand) bc_num_bigdig2(&temp);
+ }
+ 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.max is not zero.
+ assert(BC_NUM_NONZERO(&vm.max));
+
+ // Because this is true, we can just ignore math errors that would happen
+ // otherwise.
+ assert(BC_NUM_NONZERO(&vm.max2));
+
+ bc_rand_getRands(rng, &s1, &s2, &i1, &i2);
+
+ // Put the second piece of state into a number.
+ bc_num_bigdig2num(&conv, (BcBigDig) s2);
+
+ assert(BC_NUM_RDX_VALID_NP(conv));
+
+ // Multiply by max to make room for the first piece of state.
+ bc_num_mul(&conv, &vm.max, &temp1, 0);
+
+ // Add in the first piece of state.
+ bc_num_bigdig2num(&conv, (BcBigDig) s1);
+ bc_num_add(&conv, &temp1, &temp2, 0);
+
+ // Divide to make it an entirely fractional part.
+ bc_num_div(&temp2, &vm.max2, &temp3, BC_RAND_STATE_BITS);
+
+ // Now start on the increment parts. It's the same process without the
+ // divide, so put the second piece of increment into a number.
+ bc_num_bigdig2num(&conv, (BcBigDig) i2);
+
+ assert(BC_NUM_RDX_VALID_NP(conv));
+
+ // Multiply by max to make room for the first piece of increment.
+ bc_num_mul(&conv, &vm.max, &temp1, 0);
+
+ // Add in the first piece of increment.
+ bc_num_bigdig2num(&conv, (BcBigDig) i1);
+ bc_num_add(&conv, &temp1, &temp2, 0);
+
+ // Now add the two together.
+ 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(BcNum *restrict a, BcNum *restrict b, BcRNG *restrict rng) {
+
+ BcNum atemp;
+ size_t i, len;
+
+ assert(a != b);
+
+ if (BC_ERR(BC_NUM_NEG(a))) bc_err(BC_ERR_MATH_NEGATIVE);
+
+ // If either of these are true, then the numbers are integers.
+ if (BC_NUM_ZERO(a) || BC_NUM_ONE(a)) return;
+
+ if (BC_ERR(bc_num_nonInt(a, &atemp))) bc_err(BC_ERR_MATH_NON_INTEGER);
+
+ assert(atemp.len);
+
+ len = atemp.len - 1;
+
+ // Just generate a random number for each limb.
+ for (i = 0; i < len; ++i)
+ b->num[i] = (BcDig) bc_rand_bounded(rng, BC_BASE_POW);
+
+ // Do the last digit explicitly because the bound must be right. But only
+ // do it if the limb does not equal 1. If it does, we have already hit the
+ // limit.
+ if (atemp.num[i] != 1) {
+ b->num[i] = (BcDig) bc_rand_bounded(rng, (BcRand) atemp.num[i]);
+ b->len = atemp.len;
+ }
+ // We want 1 less len in the case where we skip the last limb.
+ else b->len = len;
+
+ bc_num_clean(b);
+
+ assert(BC_NUM_RDX_VALID(b));
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+size_t bc_num_addReq(const BcNum *a, const BcNum *b, size_t scale) {
+
+ size_t aint, bint, ardx, brdx;
+
+ // Addition and subtraction require the max of the length of the two numbers
+ // plus 1.
+
+ 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;
+
+ // Multiplication requires the sum of the lengths of the numbers.
+
+ 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;
+
+ // Division requires the length of the dividend plus the scale.
+
+ 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, resscale;
+ BcDig half_digs[1];
+
+ assert(a != NULL && b != NULL && a != b);
+
+ if (BC_ERR(BC_NUM_NEG(a))) bc_err(BC_ERR_MATH_NEGATIVE);
+
+ // We want to calculate to a's scale if it is bigger so that the result will
+ // truncate properly.
+ if (a->scale > scale) scale = a->scale;
+
+ // Set parameters for the result.
+ len = bc_vm_growSize(bc_num_intDigits(a), 1);
+ rdx = BC_NUM_RDX(scale);
+
+ // Square root needs half of the length of the parameter.
+ req = bc_vm_growSize(BC_MAX(rdx, BC_NUM_RDX_VAL(a)), len >> 1);
+
+ BC_SIG_LOCK;
+
+ // Unlike the binary operators, this function is the only single parameter
+ // function and is expected to initialize the result. This means that it
+ // expects that b is *NOT* preallocated. We allocate it here.
+ 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);
+
+ // Easy case.
+ if (BC_NUM_ZERO(a)) {
+ bc_num_setToZero(b, scale);
+ return;
+ }
+
+ // Another easy case.
+ if (BC_NUM_ONE(a)) {
+ bc_num_one(b);
+ bc_num_extend(b, scale);
+ return;
+ }
+
+ // Set the parameters again.
+ 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));
+
+ // There is a division by two in the formula. We setup a number that's 1/2
+ // so that we can use multiplication instead of heavy division.
+ 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;
+
+ // Pointers for easy switching.
+ x0 = &num1;
+ x1 = &num2;
+
+ // Start with 1.
+ bc_num_one(x0);
+
+ // The power of the operand is needed for the estimate.
+ pow = bc_num_intDigits(a);
+
+ // The code in this if statement calculates the initial estimate. First, if
+ // a is less than 0, then 0 is a good estimate. Otherwise, we want something
+ // in the same ballpark. That ballpark is pow.
+ if (pow) {
+
+ // An odd number is served by starting with 2^((pow-1)/2), and an even
+ // number is served by starting with 6^((pow-2)/2). Why? Because math.
+ 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 = 0;
+ resscale = (scale + BC_BASE_DIGS) + 2;
+
+ // This is the calculation loop. This compare goes to 0 eventually as the
+ // difference between the two numbers gets smaller than resscale.
+ while (bc_num_cmp(x1, x0)) {
+
+ assert(BC_NUM_NONZERO(x0));
+
+ // This loop directly corresponds to the iteration in Newton's method.
+ // If you know the formula, this loop makes sense. Go study the formula.
+
+ 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);
+
+ // Switch.
+ temp = x0;
+ x0 = x1;
+ x1 = temp;
+ }
+
+ // Copy to the result and truncate.
+ 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;
+
+ // The bulk of this function is just doing what bc_num_binary() does for the
+ // binary operators. However, it assumes that only c and a can be equal.
+
+ // Set up the parameters.
+ 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);
+
+ // Initialize or expand as necessary.
+ 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);
+ }
+
+ // Do the quick version if possible.
+ 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);
+ }
+ // Do the slow method.
+ 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:
+ // Only cleanup if we initialized.
+ if (init) {
+ BC_SIG_MAYLOCK;
+ bc_num_free(&num2);
+ BC_LONGJMP_CONT;
+ }
+}
+
+void bc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d) {
+
+ BcNum base, exp, two, temp, atemp, btemp, ctemp;
+ 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_err(BC_ERR_MATH_DIVIDE_BY_ZERO);
+
+ if (BC_ERR(BC_NUM_NEG(b))) bc_err(BC_ERR_MATH_NEGATIVE);
+
+#ifndef NDEBUG
+ // This is entirely for quieting a useless scan-build error.
+ btemp.len = 0;
+ ctemp.len = 0;
+#endif // NDEBUG
+
+ // Eliminate fractional parts that are zero or error if they are not zero.
+ if (BC_ERR(bc_num_nonInt(a, &atemp) || bc_num_nonInt(b, &btemp) ||
+ bc_num_nonInt(c, &ctemp)))
+ {
+ bc_err(BC_ERR_MATH_NON_INTEGER);
+ }
+
+ bc_num_expand(d, ctemp.len);
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&base, ctemp.len);
+ bc_num_setup(&two, two_digs, sizeof(two_digs) / sizeof(BcDig));
+ bc_num_init(&temp, btemp.len + 1);
+ bc_num_createCopy(&exp, &btemp);
+
+ 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(&atemp, &ctemp, &base, 0);
+
+ // If you know the algorithm I used, the memory-efficient method, then this
+ // loop should be self-explanatory because it is the calculation loop.
+ 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, &ctemp, 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, &ctemp, &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);
+}
+
+#if BC_DEBUG_CODE
+void bc_num_printDebug(const BcNum *n, const char *name, bool emptyline) {
+ bc_file_puts(&vm.fout, bc_flush_none, name);
+ bc_file_puts(&vm.fout, bc_flush_none, ": ");
+ bc_num_printDecimal(n, true);
+ bc_file_putchar(&vm.fout, bc_flush_err, '\n');
+ if (emptyline) bc_file_putchar(&vm.fout, bc_flush_err, '\n');
+ vm.nchars = 0;
+}
+
+void bc_num_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, bc_flush_err, '\n');
+ if (emptyline) bc_file_putchar(&vm.fout, bc_flush_err, '\n');
+ vm.nchars = 0;
+}
+
+void bc_num_printWithDigs(const BcNum *n, const char *name, bool emptyline) {
+ bc_file_puts(&vm.fout, bc_flush_none, name);
+ bc_file_printf(&vm.fout, " len: %zu, rdx: %zu, scale: %zu\n",
+ name, n->len, BC_NUM_RDX_VAL(n), n->scale);
+ bc_num_printDigs(n->num, n->len, emptyline);
+}
+
+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, bc_flush_none, ". ");
+
+ if (scale / BC_BASE_DIGS != BC_NUM_RDX_VAL(n) - i - 1)
+ bc_file_printf(&vm.ferr, "%lu ", (unsigned long) n->num[i]);
+ 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);
+
+ bc_file_flush(&vm.ferr, bc_flush_err);
+}
+#endif // BC_DEBUG_CODE
diff --git a/contrib/bc/src/opt.c b/contrib/bc/src/opt.c
new file mode 100644
index 000000000000..ddc78362e7b1
--- /dev/null
+++ b/contrib/bc/src/opt.c
@@ -0,0 +1,359 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+/**
+ * Returns true if index @a i is the end of the longopts array.
+ * @param longopts The long options array.
+ * @param i The index to test.
+ * @return True if @a i is the last index, false otherwise.
+ */
+static inline bool bc_opt_longoptsEnd(const BcOptLong *longopts, size_t i) {
+ return !longopts[i].name && !longopts[i].val;
+}
+
+/**
+ * Returns the name of the long option that matches the character @a c.
+ * @param longopts The long options array.
+ * @param c The character to match against.
+ * @return The name of the long option that matches @a c, or "NULL".
+ */
+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;
+ }
+
+ BC_UNREACHABLE
+
+ return "NULL";
+}
+
+/**
+ * Issues a fatal error for an option parsing failure.
+ * @param err The error.
+ * @param c The character for the failing option.
+ * @param str Either the string for the failing option, or the invalid
+ * option.
+ * @param use_short True if the short option should be used for error printing,
+ * false otherwise.
+ */
+static void bc_opt_error(BcErr err, int c, const char *str, bool use_short) {
+
+ if (err == BC_ERR_FATAL_OPTION) {
+
+ if (use_short) {
+
+ char short_str[2];
+
+ short_str[0] = (char) c;
+ short_str[1] = '\0';
+
+ bc_error(err, 0, short_str);
+ }
+ else bc_error(err, 0, str);
+ }
+ else bc_error(err, 0, (int) c, str);
+}
+
+/**
+ * Returns the type of the long option that matches @a c.
+ * @param longopts The long options array.
+ * @param c The character to match against.
+ * @return The type of the long option as an integer, or -1 if none.
+ */
+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;
+}
+
+/**
+ * Parses a short option.
+ * @param o The option parser.
+ * @param longopts The long options array.
+ * @return The character for the short option, or -1 if none left.
+ */
+static int bc_opt_parseShort(BcOpt *o, const BcOptLong *longopts) {
+
+ int type;
+ char *next;
+ char *option = o->argv[o->optind];
+ int ret = -1;
+
+ // Make sure to clear these.
+ o->optopt = 0;
+ o->optarg = NULL;
+
+ // Get the next option.
+ option += o->subopt + 1;
+ o->optopt = option[0];
+
+ // Get the type and the next data.
+ 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:
+ {
+ // Check for invalid option and barf if so.
+ 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, true);
+ }
+ }
+ // Fallthrough.
+ BC_FALLTHROUGH
+
+ case BC_OPT_NONE:
+ {
+ // If there is something else, update the suboption.
+ if (option[1]) o->subopt += 1;
+ else {
+
+ // Go to the next argument.
+ o->subopt = 0;
+ o->optind += 1;
+ }
+
+ ret = (int) option[0];
+
+ break;
+ }
+
+ case BC_OPT_REQUIRED_BC_ONLY:
+ {
+ if (BC_IS_DC)
+ bc_opt_error(BC_ERR_FATAL_OPTION, option[0],
+ bc_opt_longopt(longopts, option[0]), true);
+ }
+ // Fallthrough
+ BC_FALLTHROUGH
+
+ case BC_OPT_REQUIRED:
+ {
+ // Always go to the next argument.
+ o->subopt = 0;
+ o->optind += 1;
+
+ // Use the next characters, if they exist.
+ if (option[1]) o->optarg = option + 1;
+ else if (next != NULL) {
+
+ // USe the next.
+ o->optarg = next;
+ o->optind += 1;
+ }
+ // No argument, barf.
+ else bc_opt_error(BC_ERR_FATAL_OPTION_NO_ARG, option[0],
+ bc_opt_longopt(longopts, option[0]), true);
+
+
+ ret = (int) option[0];
+
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * Ensures that a long option argument matches a long option name, regardless of
+ * "=<data>" at the end.
+ * @param name The name to match.
+ * @param option The command-line argument.
+ * @return True if @a option matches @a name, false otherwise.
+ */
+static bool bc_opt_longoptsMatch(const char *name, const char *option) {
+
+ const char *a = option, *n = name;
+
+ // Can never match a NULL name.
+ if (name == NULL) return false;
+
+ // Loop through
+ for (; *a && *n && *a != '='; ++a, ++n) {
+ if (*a != *n) return false;
+ }
+
+ // Ensure they both end at the same place.
+ return (*n == '\0' && (*a == '\0' || *a == '='));
+}
+
+/**
+ * Returns a pointer to the argument of a long option, or NULL if it not in the
+ * same argument.
+ * @param option The option to find the argument of.
+ * @return A pointer to the argument of the option, or NULL if none.
+ */
+static char* bc_opt_longoptsArg(char *option) {
+
+ // Find the end or equals sign.
+ 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;
+
+ // This just eats empty options.
+ do {
+
+ option = o->argv[o->optind];
+ if (option == NULL) return -1;
+
+ empty = !strcmp(option, "");
+ o->optind += empty;
+
+ } while (empty);
+
+ // If the option is just a "--".
+ if (BC_OPT_ISDASHDASH(option)) {
+
+ // Consume "--".
+ o->optind += 1;
+ return -1;
+ }
+ // Parse a short option.
+ else if (BC_OPT_ISSHORTOPT(option)) return bc_opt_parseShort(o, longopts);
+ // If the option is not long at this point, we are done.
+ else if (!BC_OPT_ISLONGOPT(option)) return -1;
+
+ // Clear these.
+ o->optopt = 0;
+ o->optarg = NULL;
+
+ // Skip "--" at beginning of the option.
+ option += 2;
+ o->optind += 1;
+
+ // Loop through the valid long options.
+ for (i = 0; !bc_opt_longoptsEnd(longopts, i); i++) {
+
+ const char *name = longopts[i].name;
+
+ // If we have a match...
+ if (bc_opt_longoptsMatch(name, option)) {
+
+ char *arg;
+
+ // Get the option char and the argument.
+ o->optopt = longopts[i].val;
+ arg = bc_opt_longoptsArg(option);
+
+ // Error if the option is invalid..
+ if ((longopts[i].type == BC_OPT_BC_ONLY && BC_IS_DC) ||
+ (longopts[i].type == BC_OPT_REQUIRED_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, false);
+ }
+
+ // Error if we have an argument and should not.
+ if (longopts[i].type == BC_OPT_NONE && arg != NULL)
+ {
+ bc_opt_error(BC_ERR_FATAL_OPTION_ARG, o->optopt, name, false);
+ }
+
+ // Set the argument, or check the next argument if we don't have
+ // one.
+ if (arg != NULL) o->optarg = arg;
+ else if (longopts[i].type == BC_OPT_REQUIRED ||
+ longopts[i].type == BC_OPT_REQUIRED_BC_ONLY)
+ {
+ // Get the next argument.
+ o->optarg = o->argv[o->optind];
+
+ // All's good if it exists; otherwise, barf.
+ if (o->optarg != NULL) o->optind += 1;
+ else bc_opt_error(BC_ERR_FATAL_OPTION_NO_ARG,
+ o->optopt, name, false);
+ }
+
+ return o->optopt;
+ }
+ }
+
+ // If we reach this point, the option is invalid.
+ bc_opt_error(BC_ERR_FATAL_OPTION, 0, option, false);
+
+ BC_UNREACHABLE
+
+ 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..ea4c25e8ba10
--- /dev/null
+++ b/contrib/bc/src/parse.c
@@ -0,0 +1,251 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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));
+}
+
+/**
+ * Updates the function, then pushes the instruction and the index. This is a
+ * convenience function.
+ * @param p The parser.
+ * @param inst The instruction to push.
+ * @param idx The index to push.
+ */
+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) {
+
+ size_t idx;
+
+ BC_SIG_LOCK;
+
+ idx = bc_program_addString(p->prog, p->l.str.v, p->fidx);
+
+ // Push the string info.
+ bc_parse_update(p, BC_INST_STR, p->fidx);
+ bc_parse_pushIndex(p, idx);
+
+ BC_SIG_UNLOCK;
+}
+
+static void bc_parse_addNum(BcParse *p, const char *string) {
+
+ BcVec *consts = &p->func->consts;
+ size_t idx;
+ BcConst *c;
+ BcVec *slabs;
+
+ // Special case 0.
+ if (bc_parse_zero[0] == string[0] && bc_parse_zero[1] == string[1]) {
+ bc_parse_push(p, BC_INST_ZERO);
+ return;
+ }
+
+ // Special case 1.
+ if (bc_parse_one[0] == string[0] && bc_parse_one[1] == string[1]) {
+ bc_parse_push(p, BC_INST_ONE);
+ return;
+ }
+
+ // Get the index.
+ idx = consts->len;
+
+ BC_SIG_LOCK;
+
+ // Get the right slab.
+ slabs = p->fidx == BC_PROG_MAIN || p->fidx == BC_PROG_READ ?
+ &vm.main_const_slab : &vm.other_slabs;
+
+ // Push an empty constant.
+ c = bc_vec_pushEmpty(consts);
+
+ // Set the fields.
+ c->val = bc_slabvec_strdup(slabs, string);
+ c->base = BC_NUM_BIGDIG_MAX;
+
+ // We need this to be able to tell that the number has not been allocated.
+ bc_num_clear(&c->num);
+
+ 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;
+
+ // Do we have a number in scientific notation? If so, add a nul byte where
+ // the e is.
+ 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 we have a number in scientific notation...
+ if (exp != NULL) {
+
+ bool neg;
+
+ // Figure out if the exponent is negative.
+ neg = (*((char*) bc_vec_item(&p->l.str, idx + 1)) == BC_LEX_NEG_CHAR);
+
+ // Add the number and instruction.
+ 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, bool is_stdin) {
+
+ // Make sure the pointer isn't invalidated.
+ p->func = bc_vec_item(&p->prog->fns, p->fidx);
+ bc_lex_text(&p->l, text, is_stdin);
+}
+
+void bc_parse_reset(BcParse *p) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ // Reset the function if it isn't main and switch to main.
+ if (p->fidx != BC_PROG_MAIN) {
+ bc_func_reset(p->func);
+ bc_parse_updateFunc(p, BC_PROG_MAIN);
+ }
+
+ // Reset the lexer.
+ p->l.i = p->l.len;
+ p->l.t = BC_LEX_EOF;
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+
+ // Get rid of the bc parser state.
+ p->auto_part = false;
+ bc_vec_npop(&p->flags, p->flags.len - 1);
+ bc_vec_popAll(&p->exits);
+ bc_vec_popAll(&p->conds);
+ bc_vec_popAll(&p->ops);
+ }
+#endif // BC_ENABLED
+
+ // Reset the program. This might clear the error.
+ bc_program_reset(p->prog);
+
+ // Jump if there is an error.
+ if (BC_ERR(vm.status)) BC_JMP;
+}
+
+#ifndef NDEBUG
+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);
+}
+#endif // NDEBUG
+
+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) {
+
+ // We always want at least one flag set on the flags stack.
+ bc_vec_init(&p->flags, sizeof(uint16_t), BC_DTOR_NONE);
+ bc_vec_push(&p->flags, &flag);
+
+ bc_vec_init(&p->exits, sizeof(BcInstPtr), BC_DTOR_NONE);
+ bc_vec_init(&p->conds, sizeof(size_t), BC_DTOR_NONE);
+ bc_vec_init(&p->ops, sizeof(BcLexType), BC_DTOR_NONE);
+ bc_vec_init(&p->buf, sizeof(char), BC_DTOR_NONE);
+
+ p->auto_part = false;
+ }
+#endif // BC_ENABLED
+
+ bc_lex_init(&p->l);
+
+ // Set up the function.
+ p->prog = prog;
+ 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..1ff9c24f323b
--- /dev/null
+++ b/contrib/bc/src/program.c
@@ -0,0 +1,3307 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+/**
+ * Quickly sets the const and strs vector pointers in the program. This is a
+ * convenience function.
+ * @param p The program.
+ * @param f The new function.
+ */
+static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) {
+ p->consts = &f->consts;
+ p->strs = &f->strs;
+}
+
+/**
+ * Does a type check for something that expects a number.
+ * @param r The result that will be checked.
+ * @param n The result's number.
+ */
+static inline void bc_program_type_num(BcResult *r, BcNum *n) {
+
+#if BC_ENABLED
+
+ // This should have already been taken care of.
+ assert(r->t != BC_RESULT_VOID);
+
+#endif // BC_ENABLED
+
+ if (BC_ERR(!BC_PROG_NUM(r, n))) bc_err(BC_ERR_EXEC_TYPE);
+}
+
+#if BC_ENABLED
+
+/**
+ * Does a type check.
+ * @param r The result to check.
+ * @param t The type that the result should be.
+ */
+static void bc_program_type_match(BcResult *r, BcType t) {
+ if (BC_ERR((r->t != BC_RESULT_ARRAY) != (!t))) bc_err(BC_ERR_EXEC_TYPE);
+}
+#endif // BC_ENABLED
+
+/**
+ * Pulls an index out of a bytecode vector and updates the index into the vector
+ * to point to the spot after the index. For more details on bytecode indices,
+ * see the development manual (manuals/development.md#bytecode-indices).
+ * @param code The bytecode vector.
+ * @param bgn An in/out parameter; the index into the vector that will be
+ * updated.
+ * @return The index at @a bgn in the bytecode vector.
+ */
+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;
+}
+
+/**
+ * Returns a string from a result and its number.
+ * @param p The program.
+ * @param n The number tied to the result.
+ * @return The string corresponding to the result and number.
+ */
+static char* bc_program_string(BcProgram *p, const BcNum *n) {
+ BcFunc *f = bc_vec_item(&p->fns, n->rdx);
+ return *((char**) bc_vec_item(&f->strs, n->scale));
+}
+
+#if BC_ENABLED
+
+/**
+ * Prepares the globals for a function call. This is only called when global
+ * stacks are on because it pushes a copy of the current globals onto each of
+ * their respective stacks.
+ * @param p The program.
+ */
+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_rand_push(&p->rng);
+#endif // BC_ENABLE_EXTRA_MATH
+}
+
+/**
+ * Pops globals stacks on returning from a function, or in the case of reset,
+ * pops all but one item on each global stack.
+ * @param p The program.
+ * @param reset True if all but one item on each stack should be popped, false
+ * otherwise.
+ */
+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_rand_pop(&p->rng, reset);
+#endif // BC_ENABLE_EXTRA_MATH
+}
+
+/**
+ * Derefeneces an array reference and returns a pointer to the real array.
+ * @param p The program.
+ * @param vec The reference vector.
+ * @return A pointer to the desired array.
+ */
+static BcVec* bc_program_dereference(const BcProgram *p, BcVec *vec) {
+
+ BcVec *v;
+ size_t vidx, nidx, i = 0;
+
+ // We want to be sure we have a reference vector.
+ assert(vec->size == sizeof(uchar));
+
+ // Get the index of the vector in arrs, then the index of the original
+ // referenced vector.
+ 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);
+
+ // We want to be sure we do *not* have a reference vector.
+ assert(v->size != sizeof(uchar));
+
+ return v;
+}
+#endif // BC_ENABLED
+
+/**
+ * Creates a BcNum from a BcBigDig and pushes onto the results stack. This is a
+ * convenience function.
+ * @param p The program.
+ * @param dig The BcBigDig to push onto the results stack.
+ * @param type The type that the pushed result should be.
+ */
+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;
+}
+
+size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx) {
+
+ BcFunc *f;
+ char **str_ptr;
+ BcVec *slabs;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ // Push an empty string on the proper vector.
+ f = bc_vec_item(&p->fns, fidx);
+ str_ptr = bc_vec_pushEmpty(&f->strs);
+
+ // Figure out which slab vector to use.
+ slabs = fidx == BC_PROG_MAIN || fidx == BC_PROG_READ ?
+ &vm.main_slabs : &vm.other_slabs;
+
+ *str_ptr = bc_slabvec_strdup(slabs, str);
+
+ return f->strs.len - 1;
+}
+
+size_t bc_program_search(BcProgram *p, const char *id, bool var) {
+
+ BcVec *v, *map;
+ size_t i;
+
+ // Grab the right vector and map.
+ v = var ? &p->vars : &p->arrs;
+ map = var ? &p->var_map : &p->arr_map;
+
+ BC_SIG_LOCK;
+
+ // We do an insert because the variable might not exist yet. This is because
+ // the parser calls this function. If the insert succeeds, we create a stack
+ // for the variable/array. But regardless, bc_map_insert() gives us the
+ // index of the item in i.
+ if (bc_map_insert(map, id, v->len, &i)) {
+ BcVec *temp = bc_vec_pushEmpty(v);
+ bc_array_init(temp, var);
+ }
+
+ BC_SIG_UNLOCK;
+
+ return ((BcId*) bc_vec_item(map, i))->idx;
+}
+
+/**
+ * Returns the correct variable or array stack for the type.
+ * @param p The program.
+ * @param idx The index of the variable or array in the variable or array
+ * vector.
+ * @param type The type of vector to return.
+ * @return A pointer to the variable or array stack.
+ */
+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);
+}
+
+/**
+ * Returns a pointer to the BcNum corresponding to the result. There is one
+ * case, however, where this returns a pointer to a BcVec: if the type of the
+ * result is array. In that case, the pointer is casted to a pointer to BcNum,
+ * but is never used. The function that calls this expecting an array casts the
+ * pointer back. This function is called a lot and needs to be as fast as
+ * possible.
+ * @param p The program.
+ * @param r The result whose number will be returned.
+ * @return The BcNum corresponding to the result.
+ */
+static BcNum* bc_program_num(BcProgram *p, BcResult *r) {
+
+ BcNum *n;
+
+#ifdef _WIN32
+ // Windows made it an error to not initialize this, so shut it up.
+ // I don't want to do this on other platforms because this procedure
+ // is one of the most heavily-used, and eliminating the initialization
+ // is a performance win.
+ n = NULL;
+#endif // _WIN32
+
+ 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:
+ case BC_RESULT_ARRAY:
+ case BC_RESULT_ARRAY_ELEM:
+ {
+ BcVec *v;
+ BcType type = (r->t == BC_RESULT_VAR) ? BC_TYPE_VAR : BC_TYPE_ARRAY;
+
+ // Get the correct variable or array vector.
+ v = bc_program_vec(p, r->d.loc.loc, type);
+
+ // Surprisingly enough, the hard case is *not* returning an array;
+ // it's returning an array element. This is because we have to dig
+ // deeper to get *to* the element. That's what the code inside this
+ // if statement does.
+ if (r->t == BC_RESULT_ARRAY_ELEM) {
+
+ size_t idx = r->d.loc.idx;
+
+ v = bc_vec_top(v);
+
+#if BC_ENABLED
+ // If this is true, we have a reference vector, so dereference
+ // it. The reason we don't need to worry about it for returning
+ // a straight array is because we only care about references
+ // when we access elements of an array that is a reference. That
+ // is this code, so in essence, this line takes care of arrays
+ // as well.
+ if (v->size == sizeof(uchar)) v = bc_program_dereference(p, v);
+#endif // BC_ENABLED
+
+ // We want to be sure we got a valid array of numbers.
+ assert(v->size == sizeof(BcNum));
+
+ // The bc spec says that if an element is accessed that does not
+ // exist, it should be preinitialized to 0. Well, if we access
+ // an element *way* out there, we have to preinitialize all
+ // elements between the current last element and the actual
+ // accessed element.
+ 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);
+ }
+ // This is either a number (for a var) or an array (for an array).
+ // Because bc_vec_top() returns a void*, we don't need to cast.
+ else n = bc_vec_top(v);
+
+ break;
+ }
+
+ case BC_RESULT_ZERO:
+ {
+ n = &vm.zero;
+ break;
+ }
+
+ case BC_RESULT_ONE:
+ {
+ n = &vm.one;
+ break;
+ }
+
+#if BC_ENABLED
+ // We should never get here; this is taken care of earlier because a
+ // result is expected.
+ case BC_RESULT_VOID:
+#ifndef NDEBUG
+ {
+ abort();
+ }
+#endif // NDEBUG
+ // Fallthrough
+ case BC_RESULT_LAST:
+ {
+ n = &p->last;
+ break;
+ }
+#endif // BC_ENABLED
+ }
+
+ return n;
+}
+
+/**
+ * Prepares an operand for use.
+ * @param p The program.
+ * @param r An out parameter; this is set to the pointer to the result that
+ * we care about.
+ * @param n An out parameter; this is set to the pointer to the number that
+ * we care about.
+ * @param idx The index of the result from the top of the results stack.
+ */
+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_err(BC_ERR_EXEC_VOID_VAL);
+#endif // BC_ENABLED
+
+ *n = bc_program_num(p, *r);
+}
+
+/**
+ * Prepares the operands of a binary operator.
+ * @param p The program.
+ * @param l An out parameter; this is set to the pointer to the result for
+ * the left operand.
+ * @param ln An out parameter; this is set to the pointer to the number for
+ * the left operand.
+ * @param r An out parameter; this is set to the pointer to the result for
+ * the right operand.
+ * @param rn An out parameter; this is set to the pointer to the number for
+ * the right operand.
+ * @param idx The starting index where the operands are in the results stack,
+ * starting from the top.
+ */
+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
+ // Check the stack for dc.
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 2)))
+ bc_err(BC_ERR_EXEC_STACK);
+ }
+#endif // BC_PROG_NO_STACK_CHECK
+
+ assert(BC_PROG_STACK(&p->results, idx + 2));
+
+ // Get the operands.
+ bc_program_operand(p, l, ln, idx + 1);
+ bc_program_operand(p, r, rn, idx);
+
+ lt = (*l)->t;
+
+#if BC_ENABLED
+ // bc_program_operand() checked these for us.
+ 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. In other words,
+ // this is to fix pointer invalidation.
+ 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_err(BC_ERR_EXEC_TYPE);
+}
+
+/**
+ * Prepares the operands of a binary operator and type checks them. This is
+ * separate from bc_program_binPrep() because some places want this, others want
+ * bc_program_binPrep().
+ * @param p The program.
+ * @param l An out parameter; this is set to the pointer to the result for
+ * the left operand.
+ * @param ln An out parameter; this is set to the pointer to the number for
+ * the left operand.
+ * @param r An out parameter; this is set to the pointer to the result for
+ * the right operand.
+ * @param rn An out parameter; this is set to the pointer to the number for
+ * the right operand.
+ * @param idx The starting index where the operands are in the results stack,
+ * starting from the top.
+ */
+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);
+}
+
+/**
+ * Prepares the operands of an assignment operator.
+ * @param p The program.
+ * @param l An out parameter; this is set to the pointer to the result for the
+ * left operand.
+ * @param ln An out parameter; this is set to the pointer to the number for the
+ * left operand.
+ * @param r An out parameter; this is set to the pointer to the result for the
+ * right operand.
+ * @param rn An out parameter; this is set to the pointer to the number for the
+ * right operand.
+ */
+static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln,
+ BcResult **r, BcNum **rn)
+{
+ BcResultType lt, min;
+
+ // This is the min non-allowable result type. dc allows strings.
+ min = BC_RESULT_TEMP - ((unsigned int) (BC_IS_BC));
+
+ // Prepare the operands.
+ bc_program_binPrep(p, l, ln, r, rn, 0);
+
+ lt = (*l)->t;
+
+ // Typecheck the left.
+ if (BC_ERR(lt >= min && lt <= BC_RESULT_ONE)) bc_err(BC_ERR_EXEC_TYPE);
+
+ // Strings can be assigned to variables. We are already good if we are
+ // assigning a string.
+ bool good = ((*r)->t == BC_RESULT_STR && lt <= BC_RESULT_ARRAY_ELEM);
+
+ assert(BC_PROG_STR(*rn) || (*r)->t != BC_RESULT_STR);
+
+ // If not, type check for a number.
+ if (!good) bc_program_type_num(*r, *rn);
+}
+
+/**
+ * Prepares a single operand and type checks it. This is separate from
+ * bc_program_operand() because different places want one or the other.
+ * @param p The program.
+ * @param r An out parameter; this is set to the pointer to the result that
+ * we care about.
+ * @param n An out parameter; this is set to the pointer to the number that
+ * we care about.
+ * @param idx The index of the result from the top of the results stack.
+ */
+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
+ // Check the stack for dc.
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1)))
+ bc_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);
+
+ // dc does not allow strings in this case.
+ bc_program_type_num(*r, *n);
+}
+
+/**
+ * Prepares and returns a clean result for the result of an operation.
+ * @param p The program.
+ * @return A clean result.
+ */
+static BcResult* bc_program_prepResult(BcProgram *p) {
+
+ BcResult *res = bc_vec_pushEmpty(&p->results);
+
+ bc_result_clear(res);
+
+ return res;
+}
+
+/**
+ * Prepares a constant for use. This parses the constant into a number and then
+ * pushes that number onto the results stack.
+ * @param p The program.
+ * @param code The bytecode vector that we will pull the index of the constant
+ * from.
+ * @param bgn An in/out parameter; marks the start of the index in the
+ * bytecode vector and will be updated to point to after the index.
+ */
+static void bc_program_const(BcProgram *p, const char *code, size_t *bgn) {
+
+ // I lied. I actually push the result first. I can do this because the
+ // result will be popped on error. I also get the constant itself.
+ BcResult *r = bc_program_prepResult(p);
+ BcConst *c = bc_vec_item(p->consts, bc_program_index(code, bgn));
+ BcBigDig base = BC_PROG_IBASE(p);
+
+ // Only reparse if the base changed.
+ if (c->base != base) {
+
+ // Allocate if we haven't yet.
+ 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;
+}
+
+/**
+ * Executes a binary operator operation.
+ * @param p The program.
+ * @param inst The instruction corresponding to the binary operator to execute.
+ */
+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;
+
+ // Initialize the number with enough space, using the correct
+ // BcNumBinaryOpReq function. This looks weird because it is executing an
+ // item of an array. Rest assured that item is a function.
+ 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));
+
+ // Run the operation. This also executes an item of an array.
+ bc_program_ops[idx](n1, n2, &res->d.n, BC_PROG_SCALE(p));
+
+ bc_program_retire(p, 1, 2);
+}
+
+/**
+ * Executes a read() or ? command.
+ * @param p The program.
+ */
+static void bc_program_read(BcProgram *p) {
+
+ BcStatus s;
+ BcInstPtr ip;
+ size_t i;
+ const char* file;
+ bool is_stdin;
+ BcFunc *f = bc_vec_item(&p->fns, BC_PROG_READ);
+
+ // If we are already executing a read, that is an error. So look for a read
+ // and barf.
+ 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_err(BC_ERR_EXEC_REC_READ);
+ }
+
+ BC_SIG_LOCK;
+
+ // Save the filename because we are going to overwrite it.
+ file = vm.file;
+ is_stdin = vm.is_stdin;
+
+ // It is a parse error if there needs to be more than one line, so we unset
+ // this to tell the lexer to not request more. We set it back later.
+ vm.is_stdin = false;
+
+ if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) {
+
+ // We need to parse, but we don't want to use the existing parser
+ // because it has state it needs to keep. (It could have a partial parse
+ // state.) So we create a new parser. This parser is in the BcVm struct
+ // so that it is not local, which means that a longjmp() could change
+ // it.
+ bc_parse_init(&vm.read_prs, p, BC_PROG_READ);
+
+ // We need a separate input buffer; that's why it is also in the BcVm
+ // struct.
+ bc_vec_init(&vm.read_buf, sizeof(char), BC_DTOR_NONE);
+ }
+ // This needs to be updated because the parser could have been used
+ // somewhere else
+ else bc_parse_updateFunc(&vm.read_prs, BC_PROG_READ);
+
+ BC_SETJMP_LOCKED(exec_err);
+
+ BC_SIG_UNLOCK;
+
+ // Set up the lexer and the read function.
+ bc_lex_file(&vm.read_prs.l, bc_program_stdin_name);
+ bc_vec_popAll(&f->code);
+
+ // Read a line.
+ if (!BC_R) s = bc_read_line(&vm.read_buf, "");
+ else s = bc_read_line(&vm.read_buf, BC_IS_BC ? "read> " : "?> ");
+
+ // We should *not* have run into EOF.
+ if (s == BC_STATUS_EOF) bc_err(BC_ERR_EXEC_READ_EXPR);
+
+ // Parse *one* expression.
+ bc_parse_text(&vm.read_prs, vm.read_buf.v, false);
+ vm.expr(&vm.read_prs, BC_PARSE_NOREAD | BC_PARSE_NEEDVAL);
+
+ // We *must* have a valid expression. A semicolon cannot end an expression,
+ // although EOF can.
+ if (BC_ERR(vm.read_prs.l.t != BC_LEX_NLINE &&
+ vm.read_prs.l.t != BC_LEX_EOF))
+ {
+ bc_err(BC_ERR_EXEC_READ_EXPR);
+ }
+
+#if BC_ENABLED
+ // Push on the globals stack if necessary.
+ if (BC_G) bc_program_prepGlobals(p);
+#endif // BC_ENABLED
+
+ // Set up a new BcInstPtr.
+ 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);
+
+ // We want a return instruction to simplify things.
+ bc_vec_pushByte(&f->code, vm.read_ret);
+ bc_vec_push(&p->stack, &ip);
+
+#if DC_ENABLED
+ // We need a new tail call entry for dc.
+ if (BC_IS_DC) {
+ size_t temp = 0;
+ bc_vec_push(&p->tail_calls, &temp);
+ }
+#endif // DC_ENABLED
+
+exec_err:
+ BC_SIG_MAYLOCK;
+ vm.is_stdin = is_stdin;
+ vm.file = file;
+ BC_LONGJMP_CONT;
+}
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * Execute a rand().
+ * @param p The program.
+ */
+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
+ // This is just to ensure that the generated number is correct. I also use
+ // braces because I declare every local at the top of the scope.
+ {
+ BcResult *r = bc_vec_top(&p->results);
+ assert(BC_NUM_RDX_VALID_NP(r->d.n));
+ }
+#endif // NDEBUG
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+/**
+ * Prints a series of characters, without escapes.
+ * @param str The string (series of characters).
+ */
+static void bc_program_printChars(const char *str) {
+
+ const char *nl;
+ size_t len = vm.nchars + strlen(str);
+
+ bc_file_puts(&vm.fout, bc_flush_save, str);
+
+ // We need to update the number of characters, so we find the last newline
+ // and set the characters accordingly.
+ nl = strrchr(str, '\n');
+
+ if (nl != NULL) len = strlen(nl + 1);
+
+ vm.nchars = len > UINT16_MAX ? UINT16_MAX : (uint16_t) len;
+}
+
+/**
+ * Prints a string with escapes.
+ * @param str The string.
+ */
+static void bc_program_printString(const char *restrict str) {
+
+ size_t i, len = strlen(str);
+
+#if DC_ENABLED
+ // This is to ensure a nul byte is printed for dc's stream operation.
+ if (!len && BC_IS_DC) {
+ bc_vm_putchar('\0', bc_flush_save);
+ return;
+ }
+#endif // DC_ENABLED
+
+ // Loop over the characters, processing escapes and printing the rest.
+ for (i = 0; i < len; ++i) {
+
+ int c = str[i];
+
+ // If we have an escape...
+ if (c == '\\' && i != len - 1) {
+
+ const char *ptr;
+
+ // Get the escape character and its companion.
+ c = str[++i];
+ ptr = strchr(bc_program_esc_chars, c);
+
+ // If we have a companion character...
+ if (ptr != NULL) {
+
+ // We need to specially handle a newline.
+ if (c == 'n') vm.nchars = UINT16_MAX;
+
+ // Grab the actual character.
+ c = bc_program_esc_seqs[(size_t) (ptr - bc_program_esc_chars)];
+ }
+ else {
+ // Just print the backslash if there is no companion character.
+ // The following character will be printed later after the outer
+ // if statement.
+ bc_vm_putchar('\\', bc_flush_save);
+ }
+ }
+
+ bc_vm_putchar(c, bc_flush_save);
+ }
+}
+
+/**
+ * Executes a print. This function handles all printing except streaming.
+ * @param p The program.
+ * @param inst The instruction for the type of print we are doing.
+ * @param idx The index of the result that we are printing.
+ */
+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_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 we have a void value, that's not necessarily an error. It is if pop is
+ // true because that means that we are executing a print statement, but
+ // attempting to do a print on a lone void value is allowed because that's
+ // exactly how we want void values used.
+ if (r->t == BC_RESULT_VOID) {
+ if (BC_ERR(pop)) bc_err(BC_ERR_EXEC_VOID_VAL);
+ bc_vec_pop(&p->results);
+ return;
+ }
+#endif // BC_ENABLED
+
+ n = bc_program_num(p, r);
+
+ // If we have a number...
+ if (BC_PROG_NUM(r, n)) {
+
+#if BC_ENABLED
+ assert(inst != BC_INST_PRINT_STR);
+#endif // BC_ENABLED
+
+ // Print the number.
+ bc_num_print(n, BC_PROG_OBASE(p), !pop);
+
+#if BC_ENABLED
+ // Need to store the number in last.
+ if (BC_IS_BC) bc_num_copy(&p->last, n);
+#endif // BC_ENABLED
+ }
+ else {
+
+ // We want to flush any stuff in the stdout buffer first.
+ bc_file_flush(&vm.fout, bc_flush_save);
+ str = bc_program_string(p, n);
+
+#if BC_ENABLED
+ if (inst == BC_INST_PRINT_STR) bc_program_printChars(str);
+ else
+#endif // BC_ENABLED
+ {
+ bc_program_printString(str);
+
+ // Need to print a newline only in this case.
+ if (inst == BC_INST_PRINT)
+ bc_vm_putchar('\n', bc_flush_err);
+ }
+ }
+
+ // bc always pops.
+ 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
+
+/**
+ * Runs a unary operation.
+ * @param p The program.
+ * @param inst The unary operation.
+ */
+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;
+
+ // This calls a function that is in an array.
+ bc_program_unarys[inst - BC_INST_NEG](res, num);
+ bc_program_retire(p, 1, 1);
+}
+
+/**
+ * Executes a logical operator.
+ * @param p The program.
+ * @param inst The operator.
+ */
+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);
+
+ // All logical operators (except boolean not, which is taken care of by
+ // bc_program_unary()), are binary operators.
+ bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 1);
+
+ // Boolean and and or are not short circuiting. This is why; they can be
+ // implemented much easier this way.
+ 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 {
+
+ // We have a relational operator, so do a comparison.
+ 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:
+ {
+ // There is a bug if we get here.
+ 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);
+}
+
+/**
+ * Assigns a string to a variable.
+ * @param p The program.
+ * @param num The location of the string as a BcNum.
+ * @param v The stack for the variable.
+ * @param push Whether to push the string or not. To push means to move the
+ * string from the results stack and push it onto the variable
+ * stack.
+ */
+static void bc_program_assignStr(BcProgram *p, BcNum *num, BcVec *v, bool push)
+{
+ BcNum *n;
+
+ assert(BC_PROG_STACK(&p->results, 1 + !push));
+ assert(num != NULL && num->num == NULL && num->cap == 0);
+
+ // If we are not pushing onto the variable stack, we need to replace the
+ // top of the variable stack.
+ if (!push) bc_vec_pop(v);
+
+ bc_vec_npop(&p->results, 1 + !push);
+
+ n = bc_vec_pushEmpty(v);
+
+ // We can just copy because the num should not have allocated anything.
+ memcpy(n, num, sizeof(BcNum));
+}
+
+/**
+ * Copies a value to a variable. This is used for storing in dc as well as to
+ * set function parameters to arguments in bc.
+ * @param p The program.
+ * @param idx The index of the variable or array to copy to.
+ * @param t The type to copy to. This could be a variable or an array.
+ * @param last Whether to grab the last item on the variable stack or not (for
+ * bc function parameters). This is important because if a new
+ * value has been pushed to the variable already, we need to grab
+ * the value pushed before. This happens when you have a parameter
+ * named something like "x", and a variable "x" is passed to
+ * another parameter.
+ */
+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
+ // Check the stack for dc.
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
+ }
+#endif
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ bc_program_operand(p, &ptr, &n, 0);
+
+#if BC_ENABLED
+ // Get the variable for a bc function call.
+ if (BC_IS_BC)
+ {
+ // Type match the result.
+ bc_program_type_match(ptr, t);
+
+ // Get the variable or array, taking care to get the real item. We take
+ // care of last with arrays later.
+ if (!last && 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);
+
+ // We can shortcut in dc if it's assigning a string by using
+ // bc_program_assignStr().
+ if (ptr->t == BC_RESULT_STR) {
+
+ assert(BC_PROG_STR(n));
+
+ if (BC_ERR(!var)) bc_err(BC_ERR_EXEC_TYPE);
+
+ bc_program_assignStr(p, n, vec, true);
+
+ return;
+ }
+
+ BC_SIG_LOCK;
+
+ // Just create and copy for a normal variable.
+ if (var) {
+ if (BC_PROG_STR(n)) memcpy(&r.d.n, n, sizeof(BcNum));
+ else bc_num_createCopy(&r.d.n, n);
+ }
+ else {
+
+ // If we get here, we are handling an array. This is one place we need
+ // to cast the number from bc_program_num() to a vector.
+ BcVec *v = (BcVec*) n, *rv = &r.d.v;
+
+#if BC_ENABLED
+
+ if (BC_IS_BC) {
+
+ BcVec *parent;
+ bool ref, ref_size;
+
+ // We need to figure out if the parameter is a reference or not and
+ // construct the reference vector, if necessary. So this gets the
+ // parent stack for the array.
+ parent = bc_program_vec(p, ptr->d.loc.loc, t);
+ assert(parent != NULL);
+
+ // This takes care of last for arrays. Mostly.
+ if (!last) v = bc_vec_item_rev(parent, !last);
+ assert(v != NULL);
+
+ // True if we are using a reference.
+ ref = (v->size == sizeof(BcNum) && t == BC_TYPE_REF);
+
+ // True if we already have a reference vector. This is slightly
+ // (okay, a lot; it just doesn't look that way) different from
+ // above. The above means that we need to construct a reference
+ // vector, whereas this means that we have one and we might have to
+ // *dereference* it.
+ ref_size = (v->size == sizeof(uchar));
+
+ // If we *should* have a reference.
+ if (ref || (ref_size && t == BC_TYPE_REF)) {
+
+ // Create a new reference vector.
+ bc_vec_init(rv, sizeof(uchar), BC_DTOR_NONE);
+
+ // If this is true, then we need to construct a reference.
+ if (ref) {
+
+ assert(parent->len >= (size_t) (!last + 1));
+
+ // Make sure the pointer was not invalidated.
+ vec = bc_program_vec(p, idx, t);
+
+ // Push the indices onto the reference vector. This takes
+ // care of last; it ensures the reference goes to the right
+ // place.
+ 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. Just push a
+ // copy of all of the bytes.
+ else bc_vec_npush(rv, v->len * sizeof(uchar), v->v);
+
+ // Push the reference vector onto the array stack and pop the
+ // source.
+ bc_vec_push(vec, &r.d);
+ bc_vec_pop(&p->results);
+
+ // We need to return early to avoid executing code that we must
+ // not touch.
+ BC_SIG_UNLOCK;
+ return;
+ }
+ // If we get here, we have a reference, but we need an array, so
+ // dereference the array.
+ else if (ref_size && t != BC_TYPE_REF)
+ v = bc_program_dereference(p, v);
+ }
+#endif // BC_ENABLED
+
+ // If we get here, we need to copy the array because in bc, all
+ // arguments are passed by value. Yes, this is expensive.
+ bc_array_init(rv, true);
+ bc_array_copy(rv, v);
+ }
+
+ // Push the vector onto the array stack and pop the source.
+ bc_vec_push(vec, &r.d);
+ bc_vec_pop(&p->results);
+
+ BC_SIG_UNLOCK;
+}
+
+/**
+ * Executes an assignment operator.
+ * @param p The program.
+ * @param inst The assignment operator to execute.
+ */
+static void bc_program_assign(BcProgram *p, uchar inst) {
+
+ // The local use_val is true when the assigned value needs to be copied.
+ 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);
+
+ // Assigning to a string should be impossible simply because of the parse.
+ assert(left->t != BC_RESULT_STR);
+
+ // If we are assigning a string...
+ if (right->t == BC_RESULT_STR) {
+
+ assert(BC_PROG_STR(r));
+
+#if BC_ENABLED
+ if (inst != BC_INST_ASSIGN && inst != BC_INST_ASSIGN_NO_VAL)
+ bc_err(BC_ERR_EXEC_TYPE);
+#endif // BC_ENABLED
+
+ // If we are assigning to an array element...
+ if (left->t == BC_RESULT_ARRAY_ELEM) {
+
+ BC_SIG_LOCK;
+
+ // We need to free the number and clear it.
+ bc_num_free(l);
+
+ memcpy(l, r, sizeof(BcNum));
+
+ // Now we can pop the results.
+ bc_vec_npop(&p->results, 2);
+
+ BC_SIG_UNLOCK;
+ }
+ else {
+
+ // If we get here, we are assigning to a variable, which we can use
+ // bc_program_assignStr() for.
+ BcVec *v = bc_program_vec(p, left->d.loc.loc, BC_TYPE_VAR);
+ bc_program_assignStr(p, r, v, false);
+ }
+
+#if BC_ENABLED
+
+ // If this is true, the value is going to be used again, so we want to
+ // push a temporary with the string.
+ if (inst == BC_INST_ASSIGN) {
+ res.t = BC_RESULT_STR;
+ memcpy(&res.d.n, r, sizeof(BcNum));
+ bc_vec_push(&p->results, &res);
+ }
+
+#endif // BC_ENABLED
+
+ // By using bc_program_assignStr(), we short-circuited this, so return.
+ return;
+ }
+
+ // If we have a normal assignment operator, not a math one...
+ if (BC_INST_IS_ASSIGN(inst)) {
+
+ // Assigning to a variable that has a string here is fine because there
+ // is no math done on it.
+
+ // BC_RESULT_TEMP, BC_RESULT_IBASE, BC_RESULT_OBASE, BC_RESULT_SCALE,
+ // and BC_RESULT_SEED all have temporary copies. Because that's the
+ // case, we can free the left and just move the value over. We set the
+ // type of right to BC_RESULT_ZERO in order to prevent it from being
+ // freed. We also don't have to worry about BC_RESULT_STR because it's
+ // take care of above.
+ if (right->t == BC_RESULT_TEMP || right->t >= BC_RESULT_IBASE) {
+
+ BC_SIG_LOCK;
+
+ bc_num_free(l);
+ memcpy(l, r, sizeof(BcNum));
+ right->t = BC_RESULT_ZERO;
+
+ BC_SIG_UNLOCK;
+ }
+ // Copy over.
+ else bc_num_copy(l, r);
+ }
+#if BC_ENABLED
+ else {
+
+ // If we get here, we are doing a math assignment (+=, -=, etc.). So
+ // we need to prepare for a binary operator.
+ BcBigDig scale = BC_PROG_SCALE(p);
+
+ // At this point, the left side could still be a string because it could
+ // be a variable that has the string. If that's the case, we have a type
+ // error.
+ if (BC_PROG_STR(l)) bc_err(BC_ERR_EXEC_TYPE);
+
+ // Get the right type of assignment operator, whether val is used or
+ // NO_VAL for performance.
+ 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));
+
+ // Run the actual operation. We do not need worry about reallocating l
+ // because bc_num_binary() does that behind the scenes for us.
+ 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);
+
+ // The globals need special handling, especially the non-seed ones. The
+ // first part of the if statement handles them.
+ if (ob || sc || left->t == BC_RESULT_IBASE) {
+
+ BcVec *v;
+ BcBigDig *ptr, *ptr_t, val, max, min;
+
+ // Get the actual value.
+ val = bc_num_bigdig(l);
+
+ // Scale needs handling separate from ibase and obase.
+ if (sc) {
+
+ // Set the min and max.
+ min = 0;
+ max = vm.maxes[BC_PROG_GLOBALS_SCALE];
+
+ // Get a pointer to the stack and to the current value.
+ v = p->globals_v + BC_PROG_GLOBALS_SCALE;
+ ptr_t = p->globals + BC_PROG_GLOBALS_SCALE;
+ }
+ else {
+
+ // Set the min and max.
+ 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];
+
+ // Get a pointer to the stack and to the current value.
+ v = p->globals_v + BC_PROG_GLOBALS_IBASE + ob;
+ ptr_t = p->globals + BC_PROG_GLOBALS_IBASE + ob;
+ }
+
+ // Check for error.
+ if (BC_ERR(val > max || val < min)) {
+
+ // This grabs the right error.
+ BcErr e = left->t - BC_RESULT_IBASE + BC_ERR_EXEC_IBASE;
+
+ bc_verr(e, min, max);
+ }
+
+ // Set the top of the stack and the actual global value.
+ ptr = bc_vec_top(v);
+ *ptr = val;
+ *ptr_t = val;
+ }
+#if BC_ENABLE_EXTRA_MATH
+ // To assign to steed, let bc_num_rng() do its magic.
+ else if (left->t == BC_RESULT_SEED) bc_num_rng(l, &p->rng);
+#endif // BC_ENABLE_EXTRA_MATH
+
+ BC_SIG_LOCK;
+
+ // If we needed to use the value, then we need to copy it. Otherwise, we can
+ // pop indiscriminately. Oh, and the copy should be a BC_RESULT_TEMP.
+ 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;
+}
+
+/**
+ * Pushes a variable's value onto the results stack.
+ * @param p The program.
+ * @param code The bytecode vector to pull the variable's index out of.
+ * @param bgn An in/out parameter; the start of the index in the bytecode
+ * vector, and will be updated to point after the index on return.
+ * @param pop True if the variable's value should be popped off its stack.
+ * This is only used in dc.
+ * @param copy True if the variable's value should be copied to the results
+ * stack. This is only used in dc.
+ */
+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);
+
+ // Set the result appropriately.
+ r.t = BC_RESULT_VAR;
+ r.d.loc.loc = idx;
+
+#if DC_ENABLED
+ // If this condition is true, then we have the hard case, where we have to
+ // adjust dc registers.
+ if (BC_IS_DC && (pop || copy)) {
+
+ // Get the stack for the variable and the number at the top.
+ BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR);
+ BcNum *num = bc_vec_top(v);
+
+ // Ensure there are enough elements on the stack.
+ if (BC_ERR(!BC_PROG_STACK(v, 2 - copy))) {
+ const char *name = bc_map_name(&p->var_map, idx);
+ bc_verr(BC_ERR_EXEC_STACK_REGISTER, name);
+ }
+
+ assert(BC_PROG_STACK(v, 2 - copy));
+
+ // If the top of the stack is actually a number...
+ if (!BC_PROG_STR(num)) {
+
+ BC_SIG_LOCK;
+
+ // Create a copy to go onto the results stack as appropriate.
+ r.t = BC_RESULT_TEMP;
+ bc_num_createCopy(&r.d.n, num);
+
+ // If we are not actually copying, we need to do a replace, so pop.
+ if (!copy) bc_vec_pop(v);
+
+ bc_vec_push(&p->results, &r);
+
+ BC_SIG_UNLOCK;
+
+ return;
+ }
+ else {
+ // Set the string result. We can just memcpy because all of the
+ // fields in the num should be cleared.
+ memcpy(&r.d.n, num, sizeof(BcNum));
+ r.t = BC_RESULT_STR;
+ }
+
+ // If we are not actually copying, we need to do a replace, so pop.
+ if (!copy) bc_vec_pop(v);
+ }
+#endif // DC_ENABLED
+
+ bc_vec_push(&p->results, &r);
+}
+
+/**
+ * Pushes an array or an array element onto the results stack.
+ * @param p The program.
+ * @param code The bytecode vector to pull the variable's index out of.
+ * @param bgn An in/out parameter; the start of the index in the bytecode
+ * vector, and will be updated to point after the index on return.
+ * @param inst The instruction; whether to push an array or an array element.
+ */
+static void bc_program_pushArray(BcProgram *p, const char *restrict code,
+ size_t *restrict bgn, uchar inst)
+{
+ BcResult r, *operand;
+ BcNum *num;
+ BcBigDig temp;
+
+ // Get the index of the array.
+ r.d.loc.loc = bc_program_index(code, bgn);
+
+ // Doing an array is easy; just set the result type and finish.
+ if (inst == BC_INST_ARRAY) {
+ r.t = BC_RESULT_ARRAY;
+ bc_vec_push(&p->results, &r);
+ return;
+ }
+
+ // Grab the top element of the results stack for the array index.
+ bc_program_prep(p, &operand, &num, 0);
+ temp = bc_num_bigdig(num);
+
+ // Set the result.
+ r.t = BC_RESULT_ARRAY_ELEM;
+ r.d.loc.idx = (size_t) temp;
+
+ BC_SIG_LOCK;
+
+ // Pop the index and push the element.
+ bc_vec_pop(&p->results);
+ bc_vec_push(&p->results, &r);
+
+ BC_SIG_UNLOCK;
+}
+
+#if BC_ENABLED
+
+/**
+ * Executes an increment or decrement operator. This only handles postfix
+ * inc/dec because the parser translates prefix inc/dec into an assignment where
+ * the value is used.
+ * @param p The program.
+ * @param inst The instruction; whether to do an increment or decrement.
+ */
+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;
+
+ // We need a copy from *before* the operation.
+ copy.t = BC_RESULT_TEMP;
+ bc_num_createCopy(&copy.d.n, num);
+
+ BC_SETJMP_LOCKED(exit);
+
+ BC_SIG_UNLOCK;
+
+ // Create the proper assignment.
+ res.t = BC_RESULT_ONE;
+ inst2 = BC_INST_ASSIGN_PLUS_NO_VAL + (inst & 0x01);
+
+ bc_vec_push(&p->results, &res);
+ bc_program_assign(p, inst2);
+
+ BC_SIG_LOCK;
+
+ bc_vec_push(&p->results, &copy);
+
+ BC_UNSETJMP;
+
+ BC_SIG_UNLOCK;
+
+ // No need to free the copy here because we pushed it onto the stack.
+ return;
+
+exit:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&copy.d.n);
+ BC_LONGJMP_CONT;
+}
+
+/**
+ * Executes a function call for bc.
+ * @param p The program.
+ * @param code The bytecode vector to pull the number of arguments and the
+ * function index out of.
+ * @param bgn An in/out parameter; the start of the indices in the bytecode
+ * vector, and will be updated to point after the indices on
+ * return.
+ */
+static void bc_program_call(BcProgram *p, const char *restrict code,
+ size_t *restrict bgn)
+{
+ BcInstPtr ip;
+ size_t i, nargs;
+ BcFunc *f;
+ BcVec *v;
+ BcAuto *a;
+ BcResult *arg;
+
+ // Pull the number of arguments out of the bytecode vector.
+ nargs = bc_program_index(code, bgn);
+
+ // Set up instruction pointer.
+ ip.idx = 0;
+ ip.func = bc_program_index(code, bgn);
+ f = bc_vec_item(&p->fns, ip.func);
+
+ // Error checking.
+ if (BC_ERR(!f->code.len)) bc_verr(BC_ERR_EXEC_UNDEF_FUNC, f->name);
+ if (BC_ERR(nargs != f->nparams))
+ bc_verr(BC_ERR_EXEC_PARAMS, f->nparams, nargs);
+
+ // Set the length of the results stack. We discount the argument, of course.
+ ip.len = p->results.len - nargs;
+
+ assert(BC_PROG_STACK(&p->results, nargs));
+
+ // Prepare the globals' stacks.
+ if (BC_G) bc_program_prepGlobals(p);
+
+ // Push the arguments onto the stacks of their respective parameters.
+ for (i = 0; i < nargs; ++i) {
+
+ size_t j;
+ bool last = true;
+
+ arg = bc_vec_top(&p->results);
+ if (BC_ERR(arg->t == BC_RESULT_VOID)) bc_err(BC_ERR_EXEC_VOID_VAL);
+
+ // Get the corresponding parameter.
+ a = bc_vec_item(&f->autos, nargs - 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. This condition
+ // must be true for that to even be possible.
+ if (arg->t == BC_RESULT_VAR || arg->t == BC_RESULT_ARRAY) {
+
+ // Loop through all of the previous parameters.
+ for (j = 0; j < i && last; ++j) {
+
+ BcAuto *aptr = bc_vec_item(&f->autos, nargs - 1 - j);
+
+ // This condition is true if there is a previous parameter with
+ // the same name *and* type because variables and arrays do not
+ // interfere with each other.
+ last = (arg->d.loc.loc != aptr->idx ||
+ (!aptr->type) != (arg->t == BC_RESULT_VAR));
+ }
+ }
+
+ // Actually push the value onto the parameter's stack.
+ bc_program_copyToVar(p, a->idx, a->type, last);
+ }
+
+ BC_SIG_LOCK;
+
+ // Push zeroes onto the stacks of the auto variables.
+ for (; i < f->autos.len; ++i) {
+
+ // Get the auto and its stack.
+ a = bc_vec_item(&f->autos, i);
+ v = bc_program_vec(p, a->idx, a->type);
+
+ // If a variable, just push a 0; otherwise, push an array.
+ if (a->type == BC_TYPE_VAR) {
+ BcNum *n = bc_vec_pushEmpty(v);
+ bc_num_init(n, BC_NUM_DEF_SIZE);
+ }
+ else {
+
+ BcVec *v2;
+
+ assert(a->type == BC_TYPE_ARRAY);
+
+ v2 = bc_vec_pushEmpty(v);
+ bc_array_init(v2, true);
+ }
+ }
+
+ // Push the instruction pointer onto the execution stack.
+ bc_vec_push(&p->stack, &ip);
+
+ BC_SIG_UNLOCK;
+}
+
+/**
+ * Executes a return instruction.
+ * @param p The program.
+ * @param inst The return instruction. bc can return void, and we need to know
+ * if it is.
+ */
+static void bc_program_return(BcProgram *p, uchar inst) {
+
+ BcResult *res;
+ BcFunc *f;
+ BcInstPtr *ip;
+ size_t i, nresults;
+
+ // Get the instruction pointer.
+ ip = bc_vec_top(&p->stack);
+
+ // Get the difference between the actual number of results and the number of
+ // results the caller expects.
+ nresults = p->results.len - ip->len;
+
+ // If this isn't true, there was a missing call somewhere.
+ assert(BC_PROG_STACK(&p->stack, 2));
+
+ // If this isn't true, the parser screwed by giving us no value when we
+ // expected one, or giving us a value when we expected none.
+ assert(BC_PROG_STACK(&p->results, ip->len + (inst == BC_INST_RET)));
+
+ // Get the function we are returning from.
+ f = bc_vec_item(&p->fns, ip->func);
+
+ res = bc_program_prepResult(p);
+
+ // If we are returning normally...
+ if (inst == BC_INST_RET) {
+
+ BcNum *num;
+ BcResult *operand;
+
+ // Prepare and copy the return value.
+ bc_program_operand(p, &operand, &num, 1);
+
+ if (BC_PROG_STR(num)) {
+
+ // We need to set this because otherwise, it will be a
+ // BC_RESULT_TEMP, and BC_RESULT_TEMP needs an actual number to make
+ // it easier to do type checking.
+ res->t = BC_RESULT_STR;
+
+ memcpy(&res->d.n, num, sizeof(BcNum));
+ }
+ else {
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&res->d.n, num);
+ }
+ }
+ // Void is easy; set the result.
+ else if (inst == BC_INST_RET_VOID) res->t = BC_RESULT_VOID;
+ else {
+
+ BC_SIG_LOCK;
+
+ // If we get here, the instruction is for returning a zero, so do that.
+ bc_num_init(&res->d.n, BC_NUM_DEF_SIZE);
+ }
+
+ BC_SIG_MAYUNLOCK;
+
+ // We need to pop items off of the stacks of arguments and autos as well.
+ for (i = 0; i < f->autos.len; ++i) {
+
+ BcAuto *a = bc_vec_item(&f->autos, i);
+ BcVec *v = bc_program_vec(p, a->idx, a->type);
+
+ bc_vec_pop(v);
+ }
+
+ // When we retire, pop all of the unused results.
+ bc_program_retire(p, 1, nresults);
+
+ // Pop the globals, if necessary.
+ if (BC_G) bc_program_popGlobals(p, false);
+
+ // Pop the stack. This is what causes the function to actually "return."
+ bc_vec_pop(&p->stack);
+}
+#endif // BC_ENABLED
+
+/**
+ * Executes a builtin function.
+ * @param p The program.
+ * @param inst The builtin to execute.
+ */
+static void bc_program_builtin(BcProgram *p, uchar inst) {
+
+ BcResult *opd, *res;
+ BcNum *num;
+ bool len = (inst == BC_INST_LENGTH);
+
+ // Ensure we have a valid builtin.
+#if BC_ENABLE_EXTRA_MATH
+ assert(inst >= BC_INST_LENGTH && inst <= BC_INST_IRAND);
+#else // BC_ENABLE_EXTRA_MATH
+ assert(inst >= BC_INST_LENGTH && inst <= BC_INST_ABS);
+#endif // BC_ENABLE_EXTRA_MATH
+
+#ifndef BC_PROG_NO_STACK_CHECK
+ // Check stack for dc.
+ if (BC_IS_DC && BC_ERR(!BC_PROG_STACK(&p->results, 1)))
+ bc_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);
+
+ // We need to ensure that strings and arrays aren't passed to most builtins.
+ // The scale function can take strings in dc.
+ if (!len && (inst != BC_INST_SCALE_FUNC || BC_IS_BC))
+ bc_program_type_num(opd, num);
+
+ // Square root is easy.
+ if (inst == BC_INST_SQRT) bc_num_sqrt(num, &res->d.n, BC_PROG_SCALE(p));
+
+ // Absolute value is easy.
+ 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
+ // irand() is easy.
+ else if (inst == BC_INST_IRAND) {
+
+ BC_SIG_LOCK;
+
+ bc_num_init(&res->d.n, num->len - BC_NUM_RDX_VAL(num));
+
+ BC_SIG_UNLOCK;
+
+ bc_num_irand(num, &res->d.n, &p->rng);
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+
+ // Everything else is...not easy.
+ else {
+
+ BcBigDig val = 0;
+
+ // Well, scale() is easy, but length() is not.
+ if (len) {
+
+ // If we are bc and we have an array...
+ if (opd->t == BC_RESULT_ARRAY) {
+
+ // Yes, this is one place where we need to cast the number from
+ // bc_program_num() to a vector.
+ BcVec *v = (BcVec*) num;
+
+#if BC_ENABLED
+ // Dereference the array, if necessary.
+ if (BC_IS_BC && v->size == sizeof(uchar))
+ v = bc_program_dereference(p, v);
+#endif // BC_ENABLED
+
+ assert(v->size == sizeof(BcNum));
+
+ val = (BcBigDig) v->len;
+ }
+ else {
+
+ // If the item is a string...
+ if (!BC_PROG_NUM(opd, num)) {
+
+ char *str;
+
+ // Get the string, then get the length.
+ str = bc_program_string(p, num);
+ val = (BcBigDig) strlen(str);
+ }
+ else
+ {
+ // Calculate the length of the number.
+ val = (BcBigDig) bc_num_len(num);
+ }
+ }
+ }
+ // Like I said; scale() is actually easy. It just also needs the integer
+ // conversion that length() does.
+ else if (BC_IS_BC || BC_PROG_NUM(opd, num))
+ val = (BcBigDig) bc_num_scale(num);
+
+ BC_SIG_LOCK;
+
+ // Create the result.
+ bc_num_createFromBigdig(&res->d.n, val);
+
+ BC_SIG_UNLOCK;
+ }
+
+ bc_program_retire(p, 1, 1);
+}
+
+/**
+ * Executes a divmod.
+ * @param p The program.
+ */
+static void bc_program_divmod(BcProgram *p) {
+
+ BcResult *opd1, *opd2, *res, *res2;
+ BcNum *n1, *n2;
+ size_t req;
+
+ // We grow first to avoid pointer invalidation.
+ 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);
+
+ // Prepare the operands.
+ bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 2);
+
+ req = bc_num_mulReq(n1, n2, BC_PROG_SCALE(p));
+
+ BC_SIG_LOCK;
+
+ // Initialize the results.
+ bc_num_init(&res->d.n, req);
+ bc_num_init(&res2->d.n, req);
+
+ BC_SIG_UNLOCK;
+
+ // Execute.
+ bc_num_divmod(n1, n2, &res2->d.n, &res->d.n, BC_PROG_SCALE(p));
+
+ bc_program_retire(p, 2, 2);
+}
+
+/**
+ * Executes modular exponentiation.
+ * @param p The program.
+ */
+static void bc_program_modexp(BcProgram *p) {
+
+ BcResult *r1, *r2, *r3, *res;
+ BcNum *n1, *n2, *n3;
+
+#if DC_ENABLED
+
+ // Check the stack.
+ if (BC_IS_DC && BC_ERR(!BC_PROG_STACK(&p->results, 3)))
+ bc_err(BC_ERR_EXEC_STACK);
+
+#endif // DC_ENABLED
+
+ assert(BC_PROG_STACK(&p->results, 3));
+
+ res = bc_program_prepResult(p);
+
+ // Get the first operand and typecheck.
+ bc_program_operand(p, &r1, &n1, 3);
+ bc_program_type_num(r1, n1);
+
+ // Get the last two operands.
+ 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 because this is dc.
+ 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);
+}
+
+/**
+ * Asciifies a number for dc. This is a helper for bc_program_asciify().
+ * @param p The program.
+ * @param n The number to asciify.
+ */
+static uchar bc_program_asciifyNum(BcProgram *p, BcNum *n) {
+
+ BcNum num;
+ BcBigDig val;
+
+#ifndef NDEBUG
+ // This is entirely to satisfy a useless scan-build error.
+ val = 0;
+#endif // NDEBUG
+
+ bc_num_clear(&num);
+
+ BC_SETJMP(num_err);
+
+ BC_SIG_LOCK;
+
+ bc_num_createCopy(&num, n);
+
+ BC_SIG_UNLOCK;
+
+ // We want to clear the scale and sign for easy mod later.
+ 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 256.
+ 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.
+ val = bc_num_bigdig2(&num);
+
+num_err:
+ BC_SIG_MAYLOCK;
+ bc_num_free(&num);
+ BC_LONGJMP_CONT;
+ return (uchar) val;
+}
+
+/**
+ * Executes the "asciify" command in dc.
+ * @param p The program.
+ * @param fidx The index of the current function.
+ */
+static void bc_program_asciify(BcProgram *p, size_t fidx) {
+
+ BcResult *r, res;
+ BcNum *n;
+ char str[2], *str2;
+ uchar c;
+ size_t idx;
+
+ // Check the stack.
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ // Get the top of the results stack.
+ bc_program_operand(p, &r, &n, 0);
+
+ assert(n != NULL);
+
+ // Asciify.
+ if (BC_PROG_NUM(r, n)) c = bc_program_asciifyNum(p, n);
+ else {
+
+ // Get the string itself, then the first character.
+ str2 = bc_program_string(p, n);
+ c = (uchar) str2[0];
+ }
+
+ // Fill the resulting string.
+ str[0] = (char) c;
+ str[1] = '\0';
+
+ // Add the string to the data structures.
+ BC_SIG_LOCK;
+ idx = bc_program_addString(p, str, fidx);
+ BC_SIG_UNLOCK;
+
+ // Set the result
+ res.t = BC_RESULT_STR;
+ bc_num_clear(&res.d.n);
+ res.d.n.rdx = fidx;
+ res.d.n.scale = idx;
+
+ // Pop and push.
+ bc_vec_pop(&p->results);
+ bc_vec_push(&p->results, &res);
+}
+
+/**
+ * Streams a number or a string to stdout.
+ * @param p The program.
+ */
+static void bc_program_printStream(BcProgram *p) {
+
+ BcResult *r;
+ BcNum *n;
+
+ // Check the stack.
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ // Get the top of the results stack.
+ bc_program_operand(p, &r, &n, 0);
+
+ assert(n != NULL);
+
+ // Stream appropriately.
+ if (BC_PROG_NUM(r, n)) bc_num_stream(n);
+ else bc_program_printChars(bc_program_string(p, n));
+
+ // Pop the operand.
+ bc_vec_pop(&p->results);
+}
+
+#if DC_ENABLED
+
+/**
+ * Gets the length of a register in dc and pushes it onto the results stack.
+ * @param p The program.
+ * @param code The bytecode vector to pull the register's index out of.
+ * @param bgn An in/out parameter; the start of the index in the bytecode
+ * vector, and will be updated to point after the index on return.
+ */
+static void bc_program_regStackLen(BcProgram *p, const char *restrict code,
+ size_t *restrict bgn)
+{
+ size_t idx = bc_program_index(code, bgn);
+ BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR);
+
+ bc_program_pushBigdig(p, (BcBigDig) v->len, BC_RESULT_TEMP);
+}
+
+/**
+ * Pushes the length of the results stack onto the results stack.
+ * @param p The program.
+ */
+static void bc_program_stackLen(BcProgram *p) {
+ bc_program_pushBigdig(p, (BcBigDig) p->results.len, BC_RESULT_TEMP);
+}
+
+/**
+ * Pops a certain number of elements off the execution stack.
+ * @param p The program.
+ * @param inst The instruction to tell us how many. There is one to pop up to
+ * 2, and one to pop the amount equal to the number at the top of
+ * the results stack.
+ */
+static void bc_program_nquit(BcProgram *p, uchar inst) {
+
+ BcResult *opnd;
+ BcNum *num;
+ BcBigDig val;
+ size_t i;
+
+ // Ensure that the tail calls stack is correct.
+ assert(p->stack.len == p->tail_calls.len);
+
+ // Get the number of executions to pop.
+ if (inst == BC_INST_QUIT) val = 2;
+ else {
+
+ bc_program_prep(p, &opnd, &num, 0);
+ val = bc_num_bigdig(num);
+
+ bc_vec_pop(&p->results);
+ }
+
+ // Loop over the tail call stack and adjust the quit value appropriately.
+ for (i = 0; val && i < p->tail_calls.len; ++i) {
+
+ // Get the number of tail calls for this one.
+ size_t calls = *((size_t*) bc_vec_item_rev(&p->tail_calls, i)) + 1;
+
+ // Adjust the value.
+ if (calls >= val) val = 0;
+ else val -= (BcBigDig) calls;
+ }
+
+ // If we don't have enough executions, just quit.
+ if (i == p->stack.len) {
+ vm.status = BC_STATUS_QUIT;
+ BC_JMP;
+ }
+ else {
+ // We can always pop the last item we reached on the tail call stack
+ // because these are for tail calls. That means that any executions that
+ // we would not have quit in that position on the stack would have quit
+ // anyway.
+ bc_vec_npop(&p->stack, i);
+ bc_vec_npop(&p->tail_calls, i);
+ }
+}
+
+/**
+ * Pushes the depth of the execution stack onto the stack.
+ * @param p The program.
+ */
+static void bc_program_execStackLen(BcProgram *p) {
+
+ size_t i, amt, len = p->tail_calls.len;
+
+ amt = len;
+
+ for (i = 0; i < len; ++i)
+ amt += *((size_t*) bc_vec_item(&p->tail_calls, i));
+
+ bc_program_pushBigdig(p, (BcBigDig) amt, BC_RESULT_TEMP);
+}
+
+/**
+ *
+ * @param p The program.
+ * @param code The bytecode vector to pull the register's index out of.
+ * @param bgn An in/out parameter; the start of the index in the bytecode
+ * vector, and will be updated to point after the index on return.
+ * @param cond True if the execution is conditional, false otherwise.
+ * @param len The number of bytes in the bytecode vector.
+ */
+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;
+ BcInstPtr ip;
+ size_t fidx;
+ BcNum *n;
+
+ assert(p->stack.len == p->tail_calls.len);
+
+ // Check the stack.
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ // Get the operand.
+ bc_program_operand(p, &r, &n, 0);
+
+ // If execution is conditional...
+ if (cond) {
+
+ bool exec;
+ size_t idx, then_idx, else_idx;
+
+ // Get the index of the "then" var and "else" var.
+ then_idx = bc_program_index(code, bgn);
+ else_idx = bc_program_index(code, bgn);
+
+ // Figure out if we should execute.
+ exec = (r->d.n.len != 0);
+
+ idx = exec ? then_idx : else_idx;
+
+ BC_SIG_LOCK;
+ BC_SETJMP_LOCKED(exit);
+
+ // If we are supposed to execute, execute. If else_idx == SIZE_MAX, that
+ // means there was no else clause, so if execute is false and else does
+ // not exist, we don't execute. The goto skips all of the setup for the
+ // execution.
+ 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_err(BC_ERR_EXEC_TYPE);
+
+ BC_UNSETJMP;
+ BC_SIG_UNLOCK;
+ }
+ 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) return;
+ }
+
+ assert(BC_PROG_STR(n));
+
+ // Get the string.
+ str = bc_program_string(p, n);
+
+ // Get the function index and function.
+ BC_SIG_LOCK;
+ fidx = bc_program_insertFunc(p, str);
+ BC_SIG_UNLOCK;
+ f = bc_vec_item(&p->fns, fidx);
+
+ // If the function has not been parsed yet...
+ if (!f->code.len) {
+
+ BC_SIG_LOCK;
+
+ if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) {
+
+ bc_parse_init(&vm.read_prs, p, fidx);
+
+ // Initialize this too because bc_vm_shutdown() expects them to be
+ // initialized togther.
+ bc_vec_init(&vm.read_buf, sizeof(char), BC_DTOR_NONE);
+ }
+ // This needs to be updated because the parser could have been used
+ // somewhere else
+ else bc_parse_updateFunc(&vm.read_prs, fidx);
+
+ bc_lex_file(&vm.read_prs.l, vm.file);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ // Parse.
+ bc_parse_text(&vm.read_prs, str, false);
+ vm.expr(&vm.read_prs, BC_PARSE_NOCALL);
+
+ BC_SIG_LOCK;
+
+ BC_UNSETJMP;
+
+ // We can just assert this here because
+ // dc should parse everything until EOF.
+ assert(vm.read_prs.l.t == BC_LEX_EOF);
+
+ BC_SIG_UNLOCK;
+ }
+
+ // Set the instruction pointer.
+ ip.idx = 0;
+ ip.len = p->results.len;
+ ip.func = fidx;
+
+ // Pop the operand.
+ bc_vec_pop(&p->results);
+
+ // Tail call processing. This condition means that there is more on the
+ // execution stack, and we are at the end of the bytecode vector, and the
+ // last instruction is just a BC_INST_POP_EXEC, which would return.
+ if (p->stack.len > 1 && *bgn == len - 1 && code[*bgn] == BC_INST_POP_EXEC) {
+
+ size_t *call_ptr = bc_vec_top(&p->tail_calls);
+
+ // Add one to the tail call.
+ *call_ptr += 1;
+
+ // Pop the execution stack before pushing the new instruction pointer
+ // on.
+ bc_vec_pop(&p->stack);
+ }
+ // If not a tail call, just push a new one.
+ else bc_vec_push(&p->tail_calls, &ip.idx);
+
+ // Push the new function onto the execution stack and return.
+ bc_vec_push(&p->stack, &ip);
+
+ return;
+
+err:
+ BC_SIG_MAYLOCK;
+
+ f = bc_vec_item(&p->fns, fidx);
+
+ // Make sure to erase the bytecode vector so dc knows it is not parsed.
+ bc_vec_popAll(&f->code);
+
+exit:
+ bc_vec_pop(&p->results);
+ BC_LONGJMP_CONT;
+}
+
+/**
+ * Prints every item on the results stack, one per line.
+ * @param p The program.
+ */
+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
+
+/**
+ * Pushes the value of a global onto the results stack.
+ * @param p The program.
+ * @param inst Which global to push, as an instruction.
+ */
+static void bc_program_pushGlobal(BcProgram *p, uchar inst) {
+
+ BcResultType t;
+
+ // Make sure the instruction is valid.
+ assert(inst >= BC_INST_IBASE && inst <= BC_INST_SCALE);
+
+ // Push the global.
+ t = inst - BC_INST_IBASE + BC_RESULT_IBASE;
+ bc_program_pushBigdig(p, p->globals[inst - BC_INST_IBASE], t);
+}
+
+/**
+ * Pushes the value of a global setting onto the stack.
+ * @param p The program.
+ * @param inst Which global setting to push, as an instruction.
+ */
+static void bc_program_globalSetting(BcProgram *p, uchar inst) {
+
+ BcBigDig val;
+
+ // Make sure the instruction is valid.
+ assert(inst >= BC_INST_LINE_LENGTH && inst <= BC_INST_LEADING_ZERO);
+
+ if (inst == BC_INST_LINE_LENGTH) val = (BcBigDig) vm.line_len;
+#if BC_ENABLED
+ else if (inst == BC_INST_GLOBAL_STACKS) val = (BC_G != 0);
+#endif // BC_ENABLED
+ else val = (BC_Z != 0);
+
+ // Push the global.
+ bc_program_pushBigdig(p, val, BC_RESULT_TEMP);
+}
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * Pushes the value of seed on the stack.
+ * @param p The program.
+ */
+static void bc_program_pushSeed(BcProgram *p) {
+
+ BcResult *res;
+
+ res = bc_program_prepResult(p);
+ res->t = BC_RESULT_SEED;
+
+ BC_SIG_LOCK;
+
+ // We need 2*BC_RAND_NUM_SIZE because of the size of the state.
+ 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
+
+/**
+ * Adds a function to the fns array. The function's ID must have already been
+ * inserted into the map.
+ * @param p The program.
+ * @param id_ptr The ID of the function as inserted into the map.
+ */
+static void bc_program_addFunc(BcProgram *p, BcId *id_ptr) {
+
+ BcInstPtr *ip;
+ BcFunc *f;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ // Push and init.
+ f = bc_vec_pushEmpty(&p->fns);
+ bc_func_init(f, id_ptr->name);
+
+ // 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;
+ bool new;
+ size_t idx;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL && name != NULL);
+
+ // Insert into the map and get the resulting ID.
+ 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 the function is new...
+ if (new) {
+
+ // Add the function to the fns array.
+ bc_program_addFunc(p, id_ptr);
+ }
+#if BC_ENABLED
+ // bc has to reset the function because it's about to be redefined.
+ else if (BC_IS_BC) {
+ BcFunc *func = bc_vec_item(&p->fns, idx);
+ bc_func_reset(func);
+ }
+#endif // BC_ENABLED
+
+ return idx;
+}
+
+#ifndef NDEBUG
+void bc_program_free(BcProgram *p) {
+
+ size_t i;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL);
+
+ // Free the globals stacks.
+ 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_rand_free(&p->rng);
+#endif // BC_ENABLE_EXTRA_MATH
+
+#if DC_ENABLED
+ if (BC_IS_DC) bc_vec_free(&p->tail_calls);
+#endif // DC_ENABLED
+}
+#endif // NDEBUG
+
+void bc_program_init(BcProgram *p) {
+
+ BcInstPtr ip;
+ size_t i;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(p != NULL);
+
+ // We want this clear.
+ memset(&ip, 0, sizeof(BcInstPtr));
+
+ // Setup the globals stacks and the current values.
+ for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) {
+
+ BcBigDig val = i == BC_PROG_GLOBALS_SCALE ? 0 : BC_BASE;
+
+ bc_vec_init(p->globals_v + i, sizeof(BcBigDig), BC_DTOR_NONE);
+ bc_vec_push(p->globals_v + i, &val);
+
+ p->globals[i] = val;
+ }
+
+#if DC_ENABLED
+ // dc-only setup.
+ if (BC_IS_DC) {
+
+ bc_vec_init(&p->tail_calls, sizeof(size_t), BC_DTOR_NONE);
+
+ // We want an item for the main function on the tail call stack.
+ i = 0;
+ bc_vec_push(&p->tail_calls, &i);
+ }
+#endif // DC_ENABLED
+
+ bc_num_setup(&p->strmb, p->strmb_num, BC_NUM_BIGDIG_LOG10);
+ bc_num_bigdig2num(&p->strmb, BC_NUM_STREAM_BASE);
+
+#if BC_ENABLE_EXTRA_MATH
+ // We need to initialize srand() just in case /dev/urandom and /dev/random
+ // are not available.
+ srand((unsigned int) time(NULL));
+ bc_rand_init(&p->rng);
+#endif // BC_ENABLE_EXTRA_MATH
+
+#if BC_ENABLED
+ if (BC_IS_BC) bc_num_init(&p->last, BC_NUM_DEF_SIZE);
+#endif // BC_ENABLED
+
+#ifndef NDEBUG
+ bc_vec_init(&p->fns, sizeof(BcFunc), BC_DTOR_FUNC);
+#else // NDEBUG
+ bc_vec_init(&p->fns, sizeof(BcFunc), BC_DTOR_NONE);
+#endif // NDEBUG
+ 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_DTOR_VEC);
+ bc_map_init(&p->var_map);
+
+ bc_vec_init(&p->arrs, sizeof(BcVec), BC_DTOR_VEC);
+ bc_map_init(&p->arr_map);
+
+ bc_vec_init(&p->results, sizeof(BcResult), BC_DTOR_RESULT);
+
+ // Push the first instruction pointer onto the execution stack.
+ bc_vec_init(&p->stack, sizeof(BcInstPtr), BC_DTOR_NONE);
+ bc_vec_push(&p->stack, &ip);
+
+ // Make sure the pointers are properly set up.
+ 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;
+
+ // Pop all but the last execution and all results.
+ bc_vec_npop(&p->stack, p->stack.len - 1);
+ bc_vec_popAll(&p->results);
+
+#if BC_ENABLED
+ // Clear the globals' stacks.
+ if (BC_G) bc_program_popGlobals(p, true);
+#endif // BC_ENABLED
+
+ // Clear the bytecode vector of the main function.
+ f = bc_vec_item(&p->fns, BC_PROG_MAIN);
+ bc_vec_npop(&f->code, f->code.len);
+
+ // Reset the instruction pointer.
+ ip = bc_vec_top(&p->stack);
+ bc_program_setVecs(p, f);
+ memset(ip, 0, sizeof(BcInstPtr));
+
+ // Write the ready message for a signal, and clear the signal.
+ if (vm.sig) {
+ bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg,
+ bc_program_ready_msg_len);
+ bc_file_flush(&vm.fout, bc_flush_err);
+ vm.sig = 0;
+ }
+}
+
+void bc_program_exec(BcProgram *p) {
+
+ size_t idx;
+ BcResult r, *ptr;
+ BcInstPtr *ip;
+ BcFunc *func;
+ char *code;
+ bool cond = false;
+ uchar inst;
+#if BC_ENABLED
+ BcNum *num;
+#endif // BC_ENABLED
+#if !BC_HAS_COMPUTED_GOTO
+#ifndef NDEBUG
+ size_t jmp_bufs_len;
+#endif // NDEBUG
+#endif // !BC_HAS_COMPUTED_GOTO
+
+#if BC_HAS_COMPUTED_GOTO
+ BC_PROG_LBLS;
+ BC_PROG_LBLS_ASSERT;
+
+ // BC_INST_INVALID is a marker for the end so that we don't have to have an
+ // execution loop.
+ func = (BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN);
+ bc_vec_pushByte(&func->code, BC_INST_INVALID);
+#endif // BC_HAS_COMPUTED_GOTO
+
+ ip = bc_vec_top(&p->stack);
+ func = (BcFunc*) bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+
+ // Ensure the pointers are correct.
+ bc_program_setVecs(p, func);
+
+#if !BC_HAS_COMPUTED_GOTO
+
+#ifndef NDEBUG
+ jmp_bufs_len = vm.jmp_bufs.len;
+#endif // NDEBUG
+
+ // This loop is the heart of the execution engine. It *is* the engine. For
+ // computed goto, it is ignored.
+ while (ip->idx < func->code.len)
+#endif // !BC_HAS_COMPUTED_GOTO
+ {
+
+ BC_SIG_ASSERT_NOT_LOCKED;
+
+#if BC_HAS_COMPUTED_GOTO
+
+ BC_PROG_JUMP(inst, code, ip);
+
+#else // BC_HAS_COMPUTED_GOTO
+
+ // Get the next instruction and increment the index.
+ inst = (uchar) code[(ip->idx)++];
+
+#endif // BC_HAS_COMPUTED_GOTO
+
+#if BC_DEBUG_CODE
+ bc_file_printf(&vm.ferr, "inst: %s\n", bc_inst_names[inst]);
+ bc_file_flush(&vm.ferr, bc_flush_none);
+#endif // BC_DEBUG_CODE
+
+#if !BC_HAS_COMPUTED_GOTO
+ switch (inst)
+#endif // !BC_HAS_COMPUTED_GOTO
+ {
+
+#if BC_ENABLED
+ // This just sets up the condition for the unconditional jump below,
+ // which checks the condition, if necessary.
+ BC_PROG_LBL(BC_INST_JUMP_ZERO):
+ {
+ bc_program_prep(p, &ptr, &num, 0);
+
+ cond = !bc_num_cmpZero(num);
+ bc_vec_pop(&p->results);
+
+ BC_PROG_DIRECT_JUMP(BC_INST_JUMP)
+ }
+ // Fallthrough.
+ BC_PROG_FALLTHROUGH
+
+ BC_PROG_LBL(BC_INST_JUMP):
+ {
+ idx = bc_program_index(code, &ip->idx);
+
+ // If a jump is required...
+ if (inst == BC_INST_JUMP || cond) {
+
+ // Get the address to jump to.
+ size_t *addr = bc_vec_item(&func->labels, idx);
+
+ // If this fails, then the parser failed to set up the
+ // labels correctly.
+ assert(*addr != SIZE_MAX);
+
+ // Set the new address.
+ ip->idx = *addr;
+ }
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_CALL):
+ {
+ assert(BC_IS_BC);
+
+ bc_program_call(p, code, &ip->idx);
+
+ // Because we changed the execution stack and where we are
+ // executing, we have to update all of this.
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_INC):
+ BC_PROG_LBL(BC_INST_DEC):
+ {
+ bc_program_incdec(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_HALT):
+ {
+ vm.status = BC_STATUS_QUIT;
+
+ // Just jump out. The jump series will take care of everything.
+ BC_JMP;
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_RET):
+ BC_PROG_LBL(BC_INST_RET0):
+ BC_PROG_LBL(BC_INST_RET_VOID):
+ {
+ bc_program_return(p, inst);
+
+ // Because we changed the execution stack and where we are
+ // executing, we have to update all of this.
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+#endif // BC_ENABLED
+
+ BC_PROG_LBL(BC_INST_BOOL_OR):
+ BC_PROG_LBL(BC_INST_BOOL_AND):
+ BC_PROG_LBL(BC_INST_REL_EQ):
+ BC_PROG_LBL(BC_INST_REL_LE):
+ BC_PROG_LBL(BC_INST_REL_GE):
+ BC_PROG_LBL(BC_INST_REL_NE):
+ BC_PROG_LBL(BC_INST_REL_LT):
+ BC_PROG_LBL(BC_INST_REL_GT):
+ {
+ bc_program_logical(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_READ):
+ {
+ // We want to flush output before
+ // this in case there is a prompt.
+ bc_file_flush(&vm.fout, bc_flush_save);
+
+ bc_program_read(p);
+
+ // Because we changed the execution stack and where we are
+ // executing, we have to update all of this.
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_RAND):
+ {
+ bc_program_rand(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+
+ BC_PROG_LBL(BC_INST_MAXIBASE):
+ BC_PROG_LBL(BC_INST_MAXOBASE):
+ BC_PROG_LBL(BC_INST_MAXSCALE):
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_MAXRAND):
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ BcBigDig dig = vm.maxes[inst - BC_INST_MAXIBASE];
+ bc_program_pushBigdig(p, dig, BC_RESULT_TEMP);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_LINE_LENGTH):
+#if BC_ENABLED
+ BC_PROG_LBL(BC_INST_GLOBAL_STACKS):
+#endif // BC_ENABLED
+ BC_PROG_LBL(BC_INST_LEADING_ZERO):
+ {
+ bc_program_globalSetting(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_VAR):
+ {
+ bc_program_pushVar(p, code, &ip->idx, false, false);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_ARRAY_ELEM):
+ BC_PROG_LBL(BC_INST_ARRAY):
+ {
+ bc_program_pushArray(p, code, &ip->idx, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_IBASE):
+ BC_PROG_LBL(BC_INST_SCALE):
+ BC_PROG_LBL(BC_INST_OBASE):
+ {
+ bc_program_pushGlobal(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_SEED):
+ {
+ bc_program_pushSeed(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+#endif // BC_ENABLE_EXTRA_MATH
+
+ BC_PROG_LBL(BC_INST_LENGTH):
+ BC_PROG_LBL(BC_INST_SCALE_FUNC):
+ BC_PROG_LBL(BC_INST_SQRT):
+ BC_PROG_LBL(BC_INST_ABS):
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_IRAND):
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ bc_program_builtin(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_ASCIIFY):
+ {
+ bc_program_asciify(p, ip->func);
+
+ // Because we changed the execution stack and where we are
+ // executing, we have to update all of this.
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_NUM):
+ {
+ bc_program_const(p, code, &ip->idx);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_ZERO):
+ BC_PROG_LBL(BC_INST_ONE):
+#if BC_ENABLED
+ BC_PROG_LBL(BC_INST_LAST):
+#endif // BC_ENABLED
+ {
+ r.t = BC_RESULT_ZERO + (inst - BC_INST_ZERO);
+ bc_vec_push(&p->results, &r);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_PRINT):
+ BC_PROG_LBL(BC_INST_PRINT_POP):
+#if BC_ENABLED
+ BC_PROG_LBL(BC_INST_PRINT_STR):
+#endif // BC_ENABLED
+ {
+ bc_program_print(p, inst, 0);
+
+ // We want to flush right away to save the output for history,
+ // if history must preserve it when taking input.
+ bc_file_flush(&vm.fout, bc_flush_save);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_STR):
+ {
+ // Set up the result and push.
+ r.t = BC_RESULT_STR;
+ bc_num_clear(&r.d.n);
+ r.d.n.rdx = bc_program_index(code, &ip->idx);
+ r.d.n.scale = bc_program_index(code, &ip->idx);
+ bc_vec_push(&p->results, &r);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_POWER):
+ BC_PROG_LBL(BC_INST_MULTIPLY):
+ BC_PROG_LBL(BC_INST_DIVIDE):
+ BC_PROG_LBL(BC_INST_MODULUS):
+ BC_PROG_LBL(BC_INST_PLUS):
+ BC_PROG_LBL(BC_INST_MINUS):
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_PLACES):
+ BC_PROG_LBL(BC_INST_LSHIFT):
+ BC_PROG_LBL(BC_INST_RSHIFT):
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ bc_program_op(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_NEG):
+ BC_PROG_LBL(BC_INST_BOOL_NOT):
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_TRUNC):
+#endif // BC_ENABLE_EXTRA_MATH
+ {
+ bc_program_unary(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+#if BC_ENABLED
+ BC_PROG_LBL(BC_INST_ASSIGN_POWER):
+ BC_PROG_LBL(BC_INST_ASSIGN_MULTIPLY):
+ BC_PROG_LBL(BC_INST_ASSIGN_DIVIDE):
+ BC_PROG_LBL(BC_INST_ASSIGN_MODULUS):
+ BC_PROG_LBL(BC_INST_ASSIGN_PLUS):
+ BC_PROG_LBL(BC_INST_ASSIGN_MINUS):
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_ASSIGN_PLACES):
+ BC_PROG_LBL(BC_INST_ASSIGN_LSHIFT):
+ BC_PROG_LBL(BC_INST_ASSIGN_RSHIFT):
+#endif // BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_ASSIGN):
+ BC_PROG_LBL(BC_INST_ASSIGN_POWER_NO_VAL):
+ BC_PROG_LBL(BC_INST_ASSIGN_MULTIPLY_NO_VAL):
+ BC_PROG_LBL(BC_INST_ASSIGN_DIVIDE_NO_VAL):
+ BC_PROG_LBL(BC_INST_ASSIGN_MODULUS_NO_VAL):
+ BC_PROG_LBL(BC_INST_ASSIGN_PLUS_NO_VAL):
+ BC_PROG_LBL(BC_INST_ASSIGN_MINUS_NO_VAL):
+#if BC_ENABLE_EXTRA_MATH
+ BC_PROG_LBL(BC_INST_ASSIGN_PLACES_NO_VAL):
+ BC_PROG_LBL(BC_INST_ASSIGN_LSHIFT_NO_VAL):
+ BC_PROG_LBL(BC_INST_ASSIGN_RSHIFT_NO_VAL):
+#endif // BC_ENABLE_EXTRA_MATH
+#endif // BC_ENABLED
+ BC_PROG_LBL(BC_INST_ASSIGN_NO_VAL):
+ {
+ bc_program_assign(p, inst);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_POP):
+ {
+#ifndef BC_PROG_NO_STACK_CHECK
+ // dc must do a stack check, but bc does not.
+ if (BC_IS_DC) {
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
+ bc_err(BC_ERR_EXEC_STACK);
+ }
+#endif // BC_PROG_NO_STACK_CHECK
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ bc_vec_pop(&p->results);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_SWAP):
+ {
+ BcResult *ptr2;
+
+ // Check the stack.
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 2)))
+ bc_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 2));
+
+ // Get the two items.
+ ptr = bc_vec_item_rev(&p->results, 0);
+ ptr2 = bc_vec_item_rev(&p->results, 1);
+
+ // Swap. It's just easiest to do it this way.
+ memcpy(&r, ptr, sizeof(BcResult));
+ memcpy(ptr, ptr2, sizeof(BcResult));
+ memcpy(ptr2, &r, sizeof(BcResult));
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_MODEXP):
+ {
+ bc_program_modexp(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_DIVMOD):
+ {
+ bc_program_divmod(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_PRINT_STREAM):
+ {
+ bc_program_printStream(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+#if DC_ENABLED
+ BC_PROG_LBL(BC_INST_POP_EXEC):
+ {
+ // If this fails, the dc parser got something wrong.
+ assert(BC_PROG_STACK(&p->stack, 2));
+
+ // Pop the execution stack and tail call stack.
+ bc_vec_pop(&p->stack);
+ bc_vec_pop(&p->tail_calls);
+
+ // Because we changed the execution stack and where we are
+ // executing, we have to update all of this.
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_EXECUTE):
+ BC_PROG_LBL(BC_INST_EXEC_COND):
+ {
+ cond = (inst == BC_INST_EXEC_COND);
+
+ bc_program_execStr(p, code, &ip->idx, cond, func->code.len);
+
+ // Because we changed the execution stack and where we are
+ // executing, we have to update all of this.
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_PRINT_STACK):
+ {
+ bc_program_printStack(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_CLEAR_STACK):
+ {
+ bc_vec_popAll(&p->results);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_REG_STACK_LEN):
+ {
+ bc_program_regStackLen(p, code, &ip->idx);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_STACK_LEN):
+ {
+ bc_program_stackLen(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_DUPLICATE):
+ {
+ // Check the stack.
+ if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
+ bc_err(BC_ERR_EXEC_STACK);
+
+ assert(BC_PROG_STACK(&p->results, 1));
+
+ // Get the top of the stack.
+ ptr = bc_vec_top(&p->results);
+
+ BC_SIG_LOCK;
+
+ // Copy and push.
+ bc_result_copy(&r, ptr);
+ bc_vec_push(&p->results, &r);
+
+ BC_SIG_UNLOCK;
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_LOAD):
+ BC_PROG_LBL(BC_INST_PUSH_VAR):
+ {
+ bool copy = (inst == BC_INST_LOAD);
+ bc_program_pushVar(p, code, &ip->idx, true, copy);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_PUSH_TO_VAR):
+ {
+ idx = bc_program_index(code, &ip->idx);
+ bc_program_copyToVar(p, idx, BC_TYPE_VAR, true);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_QUIT):
+ BC_PROG_LBL(BC_INST_NQUIT):
+ {
+ bc_program_nquit(p, inst);
+
+ // Because we changed the execution stack and where we are
+ // executing, we have to update all of this.
+ ip = bc_vec_top(&p->stack);
+ func = bc_vec_item(&p->fns, ip->func);
+ code = func->code.v;
+ bc_program_setVecs(p, func);
+
+ BC_PROG_JUMP(inst, code, ip);
+ }
+
+ BC_PROG_LBL(BC_INST_EXEC_STACK_LEN):
+ {
+ bc_program_execStackLen(p);
+ BC_PROG_JUMP(inst, code, ip);
+ }
+#endif // DC_ENABLED
+
+#if BC_HAS_COMPUTED_GOTO
+ BC_PROG_LBL(BC_INST_INVALID):
+ {
+ return;
+ }
+#else // BC_HAS_COMPUTED_GOTO
+ default:
+ {
+ BC_UNREACHABLE
+#ifndef NDEBUG
+ abort();
+#endif // NDEBUG
+ }
+#endif // BC_HAS_COMPUTED_GOTO
+ }
+
+#if !BC_HAS_COMPUTED_GOTO
+#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. But it's also a
+ // good smoke test for error handling changes.
+ assert(jmp_bufs_len == vm.jmp_bufs.len);
+#endif // NDEBUG
+#endif // !BC_HAS_COMPUTED_GOTO
+ }
+}
+
+#if BC_DEBUG_CODE
+#if BC_ENABLED && DC_ENABLED
+void bc_program_printStackDebug(BcProgram *p) {
+ bc_file_puts(&vm.fout, bc_flush_err, "-------------- Stack ----------\n");
+ bc_program_printStack(p);
+ bc_file_puts(&vm.fout, bc_flush_err, "-------------- 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', bc_flush_err);
+}
+
+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, bc_flush_err, "\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..bfc79be7cfb9
--- /dev/null
+++ b/contrib/bc/src/rand.c
@@ -0,0 +1,581 @@
+/*
+ * *****************************************************************************
+ *
+ * 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
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * This code is under the following license:
+ *
+ * Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
+ * Copyright (c) 2018-2021 Gavin D. Howard and 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>
+
+#ifndef _WIN32
+#include <unistd.h>
+#else // _WIN32
+#include <Windows.h>
+#include <bcrypt.h>
+#endif // _WIN32
+
+#include <status.h>
+#include <rand.h>
+#include <vm.h>
+
+#if BC_ENABLE_EXTRA_MATH
+
+#if !BC_RAND_BUILTIN
+
+/**
+ * Adds two 64-bit values and preserves the overflow.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @return The sum, including overflow.
+ */
+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;
+}
+
+/**
+ * Adds two 128-bit values and discards the overflow.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @return The sum, without overflow.
+ */
+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;
+}
+
+/**
+ * Multiplies two 64-bit values and preserves the overflow.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @return The product, including overflow.
+ */
+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;
+}
+
+/**
+ * Multiplies two 128-bit values and discards the overflow.
+ * @param a The first operand.
+ * @param b The second operand.
+ * @return The product, without overflow.
+ */
+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
+
+/**
+ * Marks a PRNG as modified. This is important for properly maintaining the
+ * stack of PRNG's.
+ * @param r The PRNG to mark as modified.
+ */
+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
+}
+
+/**
+ * Marks a PRNG as not modified. This is important for properly maintaining the
+ * stack of PRNG's.
+ * @param r The PRNG to mark as not modified.
+ */
+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
+}
+
+/**
+ * Copies a PRNG to another and marks the copy as modified if it already was or
+ * marks it modified if it already was.
+ * @param d The destination PRNG.
+ * @param s The source PRNG.
+ */
+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);
+}
+
+#ifndef _WIN32
+
+/**
+ * Reads random data from a file.
+ * @param ptr A pointer to the file, as a void pointer.
+ * @return The random data as an unsigned long.
+ */
+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_fatalError(BC_ERR_FATAL_IO_ERR);
+
+ return *((ulong*)buf);
+}
+#else // _WIN32
+
+/**
+ * Reads random data from BCryptGenRandom().
+ * @param ptr An unused parameter.
+ * @return The random data as an unsigned long.
+ */
+static ulong bc_rand_winrand(void *ptr) {
+
+ ulong buf[1];
+ NTSTATUS s;
+
+ BC_UNUSED(ptr);
+
+ buf[0] = 0;
+
+ s = BCryptGenRandom(NULL, (char*) buf, sizeof(ulong),
+ BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+
+ if (BC_ERR(!BCRYPT_SUCCESS(s))) buf[0] = 0;
+
+ return buf[0];
+}
+#endif // _WIN32
+
+/**
+ * Reads random data from rand(), byte-by-byte because rand() is only guaranteed
+ * to return 15 bits of random data. This is the final fallback and is not
+ * preferred as it is possible to access cryptographically-secure PRNG's on most
+ * systems.
+ * @param ptr An unused parameter.
+ * @return The random data as an unsigned long.
+ */
+static ulong bc_rand_rand(void *ptr) {
+
+ size_t i;
+ ulong res = 0;
+
+ BC_UNUSED(ptr);
+
+ // Fill up the unsigned long byte-by-byte.
+ for (i = 0; i < sizeof(ulong); ++i)
+ res |= ((ulong) (rand() & BC_RAND_SRAND_BITS)) << (i * CHAR_BIT);
+
+ return res;
+}
+
+/**
+ * Returns the actual increment of the PRNG, including the required last odd
+ * bit.
+ * @param r The PRNG.
+ * @return The increment of the PRNG, including the last odd bit.
+ */
+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;
+}
+
+/**
+ * Sets up the increment for the PRNG.
+ * @param r The PRNG whose increment will be set up.
+ */
+static void bc_rand_setupInc(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
+}
+
+/**
+ * Seeds the state of a PRNG.
+ * @param state The return parameter; the state to seed.
+ * @param val1 The lower half of the state.
+ * @param val2 The upper half of the state.
+ */
+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
+}
+
+/**
+ * Seeds a PRNG.
+ * @param r The return parameter; the PRNG to seed.
+ * @param state1 The lower half of the state.
+ * @param state2 The upper half of the state.
+ * @param inc1 The lower half of the increment.
+ * @param inc2 The upper half of the increment.
+ */
+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_setupInc(r);
+}
+
+/**
+ * Fills a PRNG with random data to seed it.
+ * @param r The PRNG.
+ * @param fulong The function to fill an unsigned long.
+ * @param ptr The parameter to pass to @a fulong.
+ */
+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);
+}
+
+/**
+ * Executes the "step" portion of a PCG udpate.
+ * @param r The PRNG.
+ */
+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));
+}
+
+/**
+ * Returns the new output of PCG.
+ * @param r The PRNG.
+ * @return The new output from the PRNG.
+ */
+static BcRand bc_rand_output(BcRNGData *r) {
+ return BC_RAND_ROT(BC_RAND_FOLD(r->state), BC_RAND_ROTAMT(r->state));
+}
+
+/**
+ * Seeds every PRNG on the PRNG stack between the top and @a idx that has not
+ * been seeded.
+ * @param r The PRNG stack.
+ * @param rng The PRNG on the top of the stack. Must have been seeded.
+ */
+static void bc_rand_seedZeroes(BcRNG *r, BcRNGData *rng, size_t idx) {
+
+ BcRNGData *rng2;
+
+ // Just return if there are none to do.
+ if (r->v.len <= idx) return;
+
+ // Get the first PRNG that might need to be seeded.
+ rng2 = bc_vec_item_rev(&r->v, idx);
+
+ // Does it need seeding? Then it, and maybe more, do.
+ if (BC_RAND_ZERO(rng2)) {
+
+ size_t i;
+
+ // Seed the ones that need seeding.
+ 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 = 0;
+
+ BC_SIG_LOCK;
+
+#ifndef _WIN32
+
+ // Try /dev/urandom first.
+ fd = open("/dev/urandom", O_RDONLY);
+
+ if (BC_NO_ERR(fd >= 0)) {
+ bc_rand_fill(rng, bc_rand_frand, &fd);
+ close(fd);
+ }
+ else {
+
+ // Try /dev/random second.
+ fd = open("/dev/random", O_RDONLY);
+
+ if (BC_NO_ERR(fd >= 0)) {
+ bc_rand_fill(rng, bc_rand_frand, &fd);
+ close(fd);
+ }
+ }
+#else // _WIN32
+ // Try BCryptGenRandom first.
+ bc_rand_fill(rng, bc_rand_winrand, NULL);
+#endif // _WIN32
+
+ // Fallback to rand() until the thing is seeded.
+ while (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_fill(rng, bc_rand_rand, NULL);
+
+ BC_SIG_UNLOCK;
+}
+
+/**
+ * Propagates a change to the PRNG to all PRNG's in the stack that should have
+ * it. The ones that should have it are laid out in the manpages.
+ * @param r The PRNG stack.
+ * @param rng The PRNG that will be used to seed the others.
+ */
+static void bc_rand_propagate(BcRNG *r, BcRNGData *rng) {
+
+ // Just return if there are none to do.
+ if (r->v.len <= 1) return;
+
+ // If the PRNG has not been modified...
+ if (BC_RAND_NOTMODIFIED(rng)) {
+
+ size_t i;
+ bool go = true;
+
+ // Find the first PRNG that is modified and seed the others.
+ 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);
+ }
+
+ // Seed everything else.
+ bc_rand_seedZeroes(r, rng, i);
+ }
+ // Seed everything.
+ else bc_rand_seedZeroes(r, rng, 1);
+}
+
+BcRand bc_rand_int(BcRNG *r) {
+
+ // Get the actual PRNG.
+ BcRNGData *rng = bc_vec_top(&r->v);
+
+ // Make sure the PRNG is seeded.
+ if (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_srand(rng);
+
+ // This is the important part of the PRNG. This is the stuff from PCG,
+ // including the return statement.
+ bc_rand_step(rng);
+ bc_rand_propagate(r, rng);
+
+ return bc_rand_output(rng);
+}
+
+BcRand bc_rand_bounded(BcRNG *r, BcRand bound) {
+
+ // Calculate the threshold below which we have to try again.
+ 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)
+{
+ // Get the actual PRNG.
+ BcRNGData *rng = bc_vec_top(&r->v);
+
+ // Seed and set up the PRNG's increment.
+ bc_rand_seedState(&rng->inc, inc1, inc2);
+ bc_rand_setupInc(rng);
+ bc_rand_setModified(rng);
+
+ // If the state is 0, use the increment as the state. Otherwise, seed it
+ // with the state.
+ if (!state1 && !state2) {
+ memcpy(&rng->state, &rng->inc, sizeof(BcRandState));
+ bc_rand_step(rng);
+ }
+ else bc_rand_seedState(&rng->state, state1, state2);
+
+ // Propagate the change to PRNG's that need it.
+ bc_rand_propagate(r, rng);
+}
+
+/**
+ * Returns the increment in the PRNG *without* the odd bit and also with being
+ * shifted one bit down.
+ * @param r The PRNG.
+ * @return The increment without the odd bit and with being shifted one bit
+ * down.
+ */
+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);
+
+ // Get the increment.
+ inc = bc_rand_getInc(rng);
+
+ // Chop the state.
+ *s1 = BC_RAND_TRUNC(rng->state);
+ *s2 = BC_RAND_CHOP(rng->state);
+
+ // Chop the increment.
+ *i1 = BC_RAND_TRUNC(inc);
+ *i2 = BC_RAND_CHOP(inc);
+}
+
+void bc_rand_push(BcRNG *r) {
+
+ BcRNGData *rng = bc_vec_pushEmpty(&r->v);
+
+ // Make sure the PRNG is properly zeroed because that marks it as needing to
+ // be seeded.
+ memset(rng, 0, sizeof(BcRNGData));
+
+ // If there is another item, copy it too.
+ if (r->v.len > 1) bc_rand_copy(rng, bc_vec_item_rev(&r->v, 1));
+}
+
+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), BC_DTOR_NONE);
+ bc_rand_push(r);
+}
+
+#if BC_RAND_USE_FREE
+void bc_rand_free(BcRNG *r) {
+ BC_SIG_ASSERT_LOCKED;
+ bc_vec_free(&r->v);
+}
+#endif // BC_RAND_USE_FREE
+
+#endif // BC_ENABLE_EXTRA_MATH
diff --git a/contrib/bc/src/read.c b/contrib/bc/src/read.c
new file mode 100644
index 000000000000..84621ad3acac
--- /dev/null
+++ b/contrib/bc/src/read.c
@@ -0,0 +1,299 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif // _WIN32
+
+#include <read.h>
+#include <history.h>
+#include <program.h>
+#include <vm.h>
+
+/**
+ * A portability file open function.
+ * @param path The path to the file to open.
+ * @param mode The mode to open in.
+ */
+static int bc_read_open(const char* path, int mode) {
+
+ int fd;
+
+#ifndef _WIN32
+ fd = open(path, mode);
+#else // _WIN32
+ fd = -1;
+ open(&fd, path, mode);
+#endif
+
+ return fd;
+}
+
+/**
+ * Returns true if the buffer data is non-text.
+ * @param buf The buffer to test.
+ * @param size The size of the buffer.
+ */
+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 nothing there, return.
+ if (!*buf_len) return false;
+
+ // Find the newline.
+ nl = strchr(buf, '\n');
+
+ // If a newline exists...
+ if (nl != NULL) {
+
+ // Get the size of the data up to, and including, the newline.
+ size_t nllen = (size_t) ((nl + 1) - buf);
+
+ nllen = *buf_len >= nllen ? nllen : *buf_len;
+
+ // Move data into the vector, and move the rest of the data in the
+ // buffer up.
+ bc_vec_npush(vec, nllen, buf);
+ *buf_len -= nllen;
+ memmove(buf, nl + 1, *buf_len + 1);
+
+ return true;
+ }
+
+ // Just put the data into the vector.
+ 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;
+
+ // Clear the vector.
+ bc_vec_popAll(vec);
+
+ // Handle the prompt, if desired.
+ if (BC_PROMPT) {
+ bc_file_puts(&vm.fout, bc_flush_none, prompt);
+ bc_file_flush(&vm.fout, bc_flush_none);
+ }
+
+ // Try reading from the buffer, and if successful, just return.
+ if (bc_read_buf(vec, vm.buf, &vm.buf_len)) {
+ bc_vec_pushByte(vec, '\0');
+ return BC_STATUS_SUCCESS;
+ }
+
+ // Loop until we have something.
+ while (!done) {
+
+ ssize_t r;
+
+ BC_SIG_LOCK;
+
+ // Read data from stdin.
+ r = read(STDIN_FILENO, vm.buf + vm.buf_len,
+ BC_VM_STDIN_BUF_SIZE - vm.buf_len);
+
+ // If there was an error...
+ if (BC_UNLIKELY(r < 0)) {
+
+ // If interupted...
+ if (errno == EINTR) {
+
+ // Jump out if we are supposed to quit, which certain signals
+ // will require.
+ if (vm.status == (sig_atomic_t) BC_STATUS_QUIT) BC_JMP;
+
+ assert(vm.sig);
+
+ // Clear the signal and status.
+ vm.sig = 0;
+ vm.status = (sig_atomic_t) BC_STATUS_SUCCESS;
+
+ // Print the ready message and prompt again.
+ bc_file_puts(&vm.fout, bc_flush_none, bc_program_ready_msg);
+ if (BC_PROMPT) bc_file_puts(&vm.fout, bc_flush_none, prompt);
+ bc_file_flush(&vm.fout, bc_flush_none);
+
+ BC_SIG_UNLOCK;
+
+ continue;
+ }
+
+ BC_SIG_UNLOCK;
+
+ // If we get here, it's bad. Barf.
+ bc_vm_fatalError(BC_ERR_FATAL_IO_ERR);
+ }
+
+ BC_SIG_UNLOCK;
+
+ // If we read nothing, make sure to terminate the string and return EOF.
+ if (r == 0) {
+ bc_vec_pushByte(vec, '\0');
+ return BC_STATUS_EOF;
+ }
+
+ // Add to the buffer.
+ vm.buf_len += (size_t) r;
+ vm.buf[vm.buf_len] = '\0';
+
+ // Read from the buffer.
+ done = bc_read_buf(vec, vm.buf, &vm.buf_len);
+ }
+
+ // Terminate the string.
+ bc_vec_pushByte(vec, '\0');
+
+ return BC_STATUS_SUCCESS;
+}
+
+BcStatus bc_read_line(BcVec *vec, const char *prompt) {
+
+ BcStatus s;
+
+#if BC_ENABLE_HISTORY
+ // Get a line from either history or manual reading.
+ 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_verr(BC_ERR_FATAL_BIN_FILE, bc_program_stdin_name);
+
+ return s;
+}
+
+char* bc_read_file(const char *path) {
+
+ BcErr e = BC_ERR_FATAL_IO_ERR;
+ size_t size, to_read;
+ struct stat pstat;
+ int fd;
+ char* buf;
+ char* buf2;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(path != NULL);
+
+#ifndef NDEBUG
+ // Need this to quiet MSan.
+ memset(&pstat, 0, sizeof(struct stat));
+#endif // NDEBUG
+
+ fd = bc_read_open(path, O_RDONLY);
+
+ // If we can't read a file, we just barf.
+ if (BC_ERR(fd < 0)) bc_verr(BC_ERR_FATAL_FILE_ERR, path);
+
+ // The reason we call fstat is to eliminate TOCTOU race conditions. This
+ // way, we have an open file, so it's not going anywhere.
+ if (BC_ERR(fstat(fd, &pstat) == -1)) goto malloc_err;
+
+ // Make sure it's not a directory.
+ if (BC_ERR(S_ISDIR(pstat.st_mode))) {
+ e = BC_ERR_FATAL_PATH_DIR;
+ goto malloc_err;
+ }
+
+ // Get the size of the file and allocate that much.
+ size = (size_t) pstat.st_size;
+ buf = bc_vm_malloc(size + 1);
+ buf2 = buf;
+ to_read = size;
+
+ do {
+
+ // Read the file. We just bail if a signal interrupts. This is so that
+ // users can interrupt the reading of big files if they want.
+ ssize_t r = read(fd, buf2, to_read);
+ if (BC_ERR(r < 0)) goto read_err;
+ to_read -= (size_t) r;
+ buf2 += (size_t) r;
+ } while (to_read);
+
+ // Got to have a nul byte.
+ buf[size] = '\0';
+
+ if (BC_ERR(bc_read_binary(buf, size))) {
+ e = BC_ERR_FATAL_BIN_FILE;
+ goto read_err;
+ }
+
+ close(fd);
+
+ return buf;
+
+read_err:
+ free(buf);
+malloc_err:
+ close(fd);
+ bc_verr(e, path);
+ return NULL;
+}
diff --git a/contrib/bc/src/vector.c b/contrib/bc/src/vector.c
new file mode 100644
index 000000000000..ebc2e76ca8c8
--- /dev/null
+++ b/contrib/bc/src/vector.c
@@ -0,0 +1,586 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Code to manipulate vectors (resizable arrays).
+ *
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <vector.h>
+#include <lang.h>
+#include <vm.h>
+
+void bc_vec_grow(BcVec *restrict v, size_t n) {
+
+ size_t cap, len;
+ sig_atomic_t lock;
+
+ cap = v->cap;
+ len = v->len + n;
+
+ // If this is true, we might overflow.
+ if (len > SIZE_MAX / 2) cap = len;
+ else {
+ // Keep doubling until larger.
+ while (cap < len) 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, BcDtorType dtor) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(v != NULL && esize);
+
+ v->v = bc_vm_malloc(bc_vm_arraySize(BC_VEC_START_CAP, esize));
+
+ v->size = (BcSize) esize;
+ v->cap = BC_VEC_START_CAP;
+ v->len = 0;
+ v->dtor = (BcSize) dtor;
+}
+
+void bc_vec_expand(BcVec *restrict v, size_t req) {
+
+ assert(v != NULL);
+
+ // Only expand if necessary.
+ 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) v->len -= n;
+ else {
+
+ const BcVecFree d = bc_vec_dtors[v->dtor];
+ size_t esize = v->size;
+ size_t len = v->len - n;
+
+ // Loop through and manually destruct every element.
+ while (v->len > len) d(v->v + (esize * --v->len));
+ }
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx) {
+
+ char* ptr, *data;
+ sig_atomic_t lock;
+
+ assert(v != NULL);
+ assert(idx + n < v->len);
+
+ // Grab start and end pointers.
+ ptr = bc_vec_item(v, idx);
+ data = bc_vec_item(v, idx + n);
+
+ BC_SIG_TRYLOCK(lock);
+
+ if (v->dtor) {
+
+ size_t i;
+ const BcVecFree d = bc_vec_dtors[v->dtor];
+
+ // Destroy every popped item.
+ for (i = 0; i < n; ++i) d(bc_vec_item(v, idx + i));
+ }
+
+ v->len -= n;
+ memmove(ptr, data, (v->len - idx) * v->size);
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+void bc_vec_npush(BcVec *restrict v, size_t n, const void *data) {
+
+ sig_atomic_t lock;
+ size_t esize;
+
+ assert(v != NULL && data != NULL);
+
+ BC_SIG_TRYLOCK(lock);
+
+ // Grow if necessary.
+ if (v->len + n > v->cap) bc_vec_grow(v, n);
+
+ esize = v->size;
+
+ // Copy the elements in.
+ memcpy(v->v + (esize * v->len), data, esize * 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_pushEmpty(BcVec *restrict v) {
+
+ sig_atomic_t lock;
+ void *ptr;
+
+ assert(v != NULL);
+
+ BC_SIG_TRYLOCK(lock);
+
+ // Grow if necessary.
+ if (v->len + 1 > v->cap) bc_vec_grow(v, 1);
+
+ ptr = v->v + v->size * v->len;
+ v->len += 1;
+
+ BC_SIG_TRYUNLOCK(lock);
+
+ return ptr;
+}
+
+inline 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));
+
+ // Encode the index.
+ for (amt = 0; idx; ++amt) {
+ nums[amt + 1] = (uchar) idx;
+ idx &= ((size_t) ~(UCHAR_MAX));
+ idx >>= sizeof(uchar) * CHAR_BIT;
+ }
+
+ nums[0] = amt;
+
+ // Push the index onto the vector.
+ bc_vec_npush(v, amt + 1, nums);
+}
+
+void bc_vec_pushAt(BcVec *restrict v, const void *data, size_t idx) {
+
+ assert(v != NULL && data != NULL && idx <= v->len);
+
+ BC_SIG_ASSERT_LOCKED;
+
+ // Do the easy case.
+ if (idx == v->len) bc_vec_push(v, data);
+ else {
+
+ char *ptr;
+ size_t esize;
+
+ // Grow if necessary.
+ if (v->len == v->cap) bc_vec_grow(v, 1);
+
+ esize = v->size;
+
+ ptr = v->v + esize * idx;
+
+ memmove(ptr + esize, ptr, esize * (v->len++ - idx));
+ memcpy(ptr, data, esize);
+ }
+}
+
+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);
+ assert(!v->len || !v->v[v->len - 1]);
+ assert(v->v != str);
+
+ BC_SIG_TRYLOCK(lock);
+
+ bc_vec_popAll(v);
+ 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);
+ assert(!v->len || !v->v[v->len - 1]);
+ assert(v->v != str);
+
+ BC_SIG_TRYLOCK(lock);
+
+ // If there is already a string, erase its nul byte.
+ 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);
+
+ BC_SIG_TRYLOCK(lock);
+
+ bc_vec_popAll(v);
+ 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) bc_vec_dtors[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 = BC_DTOR_NONE;
+}
+
+void bc_vec_free(void *vec) {
+ BcVec *v = (BcVec*) vec;
+ BC_SIG_ASSERT_LOCKED;
+ bc_vec_popAll(v);
+ free(v->v);
+}
+
+#if !BC_ENABLE_LIBRARY
+
+/**
+ * Finds a name in a map by binary search. Returns the index where the item
+ * *would* be if it doesn't exist. Callers are responsible for checking that the
+ * item exists at the index.
+ * @param v The map.
+ * @param name The name to find.
+ * @return The index of the item with @a name, or where the item would be
+ * if it does not exist.
+ */
+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;
+ BcVec *slabs;
+
+ 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;
+
+#if BC_ENABLED
+ slabs = BC_IS_DC ? &vm.main_slabs : &vm.other_slabs;
+#else // BC_ENABLED
+ slabs = &vm.main_slabs;
+#endif // BC_ENABLED
+
+ id.name = bc_slabvec_strdup(slabs, 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 out of range, return invalid.
+ if (i >= v->len) return BC_VEC_INVALID_IDX;
+
+ // Make sure the item exists.
+ return strcmp(name, ((BcId*) bc_vec_item(v, i))->name) ?
+ BC_VEC_INVALID_IDX : i;
+}
+
+#if DC_ENABLED
+const char* bc_map_name(const BcVec *restrict v, size_t idx) {
+
+ size_t i, len = v->len;
+
+ for (i = 0; i < len; ++i) {
+ BcId* id = (BcId*) bc_vec_item(v, i);
+ if (id->idx == idx) return id->name;
+ }
+
+ BC_UNREACHABLE
+
+ return "";
+}
+#endif // DC_ENABLED
+
+/**
+ * Initializes a single slab.
+ * @param s The slab to initialize.
+ */
+static void bc_slab_init(BcSlab *s) {
+ s->s = bc_vm_malloc(BC_SLAB_SIZE);
+ s->len = 0;
+}
+
+/**
+ * Adds a string to a slab and returns a pointer to it, or NULL if it could not
+ * be added.
+ * @param s The slab to add to.
+ * @param str The string to add.
+ * @param len The length of the string, including its nul byte.
+ * @return A pointer to the new string in the slab, or NULL if it could not
+ * be added.
+ */
+static char* bc_slab_add(BcSlab *s, const char *str, size_t len) {
+
+ char *ptr;
+
+ assert(s != NULL);
+ assert(str != NULL);
+ assert(len == strlen(str) + 1);
+
+ if (s->len + len > BC_SLAB_SIZE) return NULL;
+
+ ptr = (char*) (s->s + s->len);
+
+ bc_strcpy(ptr, len, str);
+
+ s->len += len;
+
+ return ptr;
+}
+
+void bc_slab_free(void *slab) {
+ free(((BcSlab*) slab)->s);
+}
+
+void bc_slabvec_init(BcVec* v) {
+
+ BcSlab *slab;
+
+ assert(v != NULL);
+
+ bc_vec_init(v, sizeof(BcSlab), BC_DTOR_SLAB);
+
+ // We always want to have at least one slab.
+ slab = bc_vec_pushEmpty(v);
+ bc_slab_init(slab);
+}
+
+char* bc_slabvec_strdup(BcVec *v, const char *str) {
+
+ char *s;
+ size_t len;
+ BcSlab slab;
+ BcSlab *slab_ptr;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ assert(v != NULL && v->len);
+
+ assert(str != NULL);
+
+ len = strlen(str) + 1;
+
+ // If the len is greater than 128, then just allocate it with malloc.
+ if (BC_UNLIKELY(len >= BC_SLAB_SIZE)) {
+
+ // SIZE_MAX is a marker for these standalone allocations.
+ slab.len = SIZE_MAX;
+ slab.s = bc_vm_strdup(str);
+
+ // Push the standalone slab.
+ bc_vec_pushAt(v, &slab, v->len - 1);
+
+ return slab.s;
+ }
+
+ // Add to a slab.
+ slab_ptr = bc_vec_top(v);
+ s = bc_slab_add(slab_ptr, str, len);
+
+ // If it couldn't be added, add a slab and try again.
+ if (BC_UNLIKELY(s == NULL)) {
+
+ slab_ptr = bc_vec_pushEmpty(v);
+ bc_slab_init(slab_ptr);
+
+ s = bc_slab_add(slab_ptr, str, len);
+
+ assert(s != NULL);
+ }
+
+ return s;
+}
+
+void bc_slabvec_clear(BcVec *v) {
+
+ BcSlab *s;
+ bool again;
+
+ // This complicated loop exists because of standalone allocations over 128
+ // bytes.
+ do {
+
+ // Get the first slab.
+ s = bc_vec_item(v, 0);
+
+ // Either the slab must be valid (not standalone), or there must be
+ // another slab.
+ assert(s->len != SIZE_MAX || v->len > 1);
+
+ // Do we have to loop again? We do if it's a standalone allocation.
+ again = (s->len == SIZE_MAX);
+
+ // Pop the standalone allocation, not the one after it.
+ if (again) bc_vec_npopAt(v, 1, 0);
+
+ } while(again);
+
+ // If we get here, we know that the first slab is a valid slab. We want to
+ // pop all of the other slabs.
+ if (v->len > 1) bc_vec_npop(v, v->len - 1);
+
+ // Empty the first slab.
+ s->len = 0;
+}
+#endif // !BC_ENABLE_LIBRARY
+
+#if BC_DEBUG_CODE
+
+void bc_slabvec_print(BcVec *v, const char *func) {
+
+ size_t i;
+ BcSlab *s;
+
+ bc_file_printf(&vm.ferr, "%s\n", func);
+
+ for (i = 0; i < v->len; ++i) {
+ s = bc_vec_item(v, i);
+ bc_file_printf(&vm.ferr, "%zu { s = %zu, len = %zu }\n",
+ i, (uintptr_t) s->s, s->len);
+ }
+
+ bc_file_puts(&vm.ferr, bc_flush_none, "\n");
+ bc_file_flush(&vm.ferr, bc_flush_none);
+}
+
+#endif // BC_DEBUG_CODE
diff --git a/contrib/bc/src/vm.c b/contrib/bc/src/vm.c
new file mode 100644
index 000000000000..8f222f8ccf69
--- /dev/null
+++ b/contrib/bc/src/vm.c
@@ -0,0 +1,1468 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * 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 <unistd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#else // _WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <io.h>
+
+#endif // _WIN32
+
+#include <status.h>
+#include <vector.h>
+#include <args.h>
+#include <vm.h>
+#include <read.h>
+#include <bc.h>
+
+// The actual globals.
+static BcDig* temps_buf[BC_VM_MAX_TEMPS];
+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, bc_flush_none, "Longjmp: ");
+ bc_file_puts(&vm.ferr, bc_flush_none, f);
+ bc_file_putchar(&vm.ferr, bc_flush_none, '\n');
+ bc_file_flush(&vm.ferr, bc_flush_none);
+#endif // BC_DEBUG_CODE
+
+#ifndef NDEBUG
+ 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
+
+/**
+ * Handles signals. This is the signal handler.
+ * @param sig The signal to handle.
+ */
+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_I || sig != SIGINT) vm.status = BC_STATUS_QUIT;
+ return;
+ }
+
+ // Only reset under these conditions; otherwise, quit.
+ if (sig == SIGINT && BC_SIGINT && BC_I) {
+
+ int err = errno;
+
+ // Write the message.
+ 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);
+
+ // Only jump if signals are not locked. The jump will happen by whoever
+ // unlocks signals.
+ if (!vm.sig_lock) BC_JMP;
+}
+
+/**
+ * Sets up signal handling.
+ */
+static void bc_vm_sigaction(void) {
+#ifndef _WIN32
+
+ struct sigaction sa;
+
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = bc_vm_sig;
+ sa.sa_flags = SA_NODEFER;
+
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+
+#if BC_ENABLE_HISTORY
+ if (BC_TTY) sigaction(SIGHUP, &sa, NULL);
+#endif // BC_ENABLE_HISTORY
+
+#else // _WIN32
+
+ signal(SIGTERM, bc_vm_sig);
+ signal(SIGINT, bc_vm_sig);
+
+#endif // _WIN32
+}
+
+void bc_vm_info(const char* const help) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+ // Print the banner.
+ bc_file_puts(&vm.fout, bc_flush_none, vm.name);
+ bc_file_putchar(&vm.fout, bc_flush_none, ' ');
+ bc_file_puts(&vm.fout, bc_flush_none, BC_VERSION);
+ bc_file_putchar(&vm.fout, bc_flush_none, '\n');
+ bc_file_puts(&vm.fout, bc_flush_none, bc_copyright);
+
+ // Print the help.
+ if (help) {
+
+ bc_file_putchar(&vm.fout, bc_flush_none, '\n');
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+
+ const char* const banner = BC_DEFAULT_BANNER ? "to" : "to not";
+ const char* const sigint = BC_DEFAULT_SIGINT_RESET ? "to reset" :
+ "to exit";
+ const char* const tty = BC_DEFAULT_TTY_MODE ? "enabled" :
+ "disabled";
+ const char* const prompt = BC_DEFAULT_PROMPT ? "enabled" :
+ "disabled";
+
+ bc_file_printf(&vm.fout, help, vm.name, vm.name, BC_VERSION,
+ BC_BUILD_TYPE, banner, sigint, tty, prompt);
+ }
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+ if (BC_IS_DC)
+ {
+ const char* const sigint = DC_DEFAULT_SIGINT_RESET ? "to reset" :
+ "to exit";
+ const char* const tty = DC_DEFAULT_TTY_MODE ? "enabled" :
+ "disabled";
+ const char* const prompt = DC_DEFAULT_PROMPT ? "enabled" :
+ "disabled";
+
+ bc_file_printf(&vm.fout, help, vm.name, vm.name, BC_VERSION,
+ BC_BUILD_TYPE, sigint, tty, prompt);
+ }
+#endif // DC_ENABLED
+ }
+
+ // Flush.
+ bc_file_flush(&vm.fout, bc_flush_none);
+}
+#endif // !BC_ENABLE_LIBRARY
+
+#if !BC_ENABLE_LIBRARY && !BC_ENABLE_MEMCHECK
+BC_NORETURN
+#endif // !BC_ENABLE_LIBRARY && !BC_ENABLE_MEMCHECK
+void bc_vm_fatalError(BcErr e) {
+ bc_err(e);
+#if !BC_ENABLE_LIBRARY && !BC_ENABLE_MEMCHECK
+ BC_UNREACHABLE
+ abort();
+#endif // !BC_ENABLE_LIBRARY && !BC_ENABLE_MEMCHECK
+}
+
+#if BC_ENABLE_LIBRARY
+void bc_vm_handleError(BcErr e) {
+
+ assert(e < BC_ERR_NELEMS);
+ assert(!vm.sig_pop);
+
+ BC_SIG_LOCK;
+
+ // If we have a normal error...
+ if (e <= BC_ERR_MATH_DIVIDE_BY_ZERO) {
+
+ // Set the error.
+ vm.err = (BclError) (e - BC_ERR_MATH_NEGATIVE +
+ BCL_ERROR_MATH_NEGATIVE);
+ }
+ // Abort if we should.
+ 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_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
+ // Figure out if the POSIX error should be an error, a warning, or nothing.
+ 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, bc_flush_err);
+
+ // Just jump out if the flush failed; there's nothing we can do.
+ if (BC_ERR(s == BC_STATUS_ERROR_FATAL)) {
+ vm.status = (sig_atomic_t) s;
+ BC_JMP;
+ }
+
+ // Print the error message.
+ va_start(args, line);
+ bc_file_putchar(&vm.ferr, bc_flush_none, '\n');
+ bc_file_puts(&vm.ferr, bc_flush_none, err_type);
+ bc_file_putchar(&vm.ferr, bc_flush_none, ' ');
+ bc_file_vprintf(&vm.ferr, vm.err_msgs[e], args);
+ va_end(args);
+
+ // Print the extra information if we have it.
+ if (BC_NO_ERR(vm.file != NULL)) {
+
+ // This is the condition for parsing vs runtime.
+ // If line is not 0, it is parsing.
+ if (line) {
+ bc_file_puts(&vm.ferr, bc_flush_none, "\n ");
+ bc_file_puts(&vm.ferr, bc_flush_none, vm.file);
+ bc_file_printf(&vm.ferr, bc_err_line, line);
+ }
+ else {
+
+ 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, bc_flush_none, "\n ");
+ bc_file_puts(&vm.ferr, bc_flush_none, vm.func_header);
+ bc_file_putchar(&vm.ferr, bc_flush_none, ' ');
+ bc_file_puts(&vm.ferr, bc_flush_none, f->name);
+
+#if BC_ENABLED
+ if (BC_IS_BC && ip->func != BC_PROG_MAIN &&
+ ip->func != BC_PROG_READ)
+ {
+ bc_file_puts(&vm.ferr, bc_flush_none, "()");
+ }
+#endif // BC_ENABLED
+ }
+ }
+
+ bc_file_puts(&vm.ferr, bc_flush_none, "\n\n");
+
+ s = bc_file_flushErr(&vm.ferr, bc_flush_err);
+
+#if !BC_ENABLE_MEMCHECK
+ // Because this function is called by a BC_NORETURN function when fatal
+ // errors happen, we need to make sure to exit on fatal errors. This will
+ // be faster anyway. This function *cannot jump when a fatal error occurs!*
+ if (BC_ERR(id == BC_ERR_IDX_FATAL || s == BC_STATUS_ERROR_FATAL))
+ exit(bc_vm_atexit((int) BC_STATUS_ERROR_FATAL));
+#else // !BC_ENABLE_MEMCHECK
+ if (BC_ERR(s == BC_STATUS_ERROR_FATAL)) vm.status = (sig_atomic_t) s;
+ else
+#endif // !BC_ENABLE_MEMCHECK
+ {
+ vm.status = (sig_atomic_t) (uchar) (id + 1);
+ }
+
+ // Only jump if there is an error.
+ if (BC_ERR(vm.status)) BC_JMP;
+
+ BC_SIG_TRYUNLOCK(lock);
+}
+
+char* bc_vm_getenv(const char* var) {
+
+ char* ret;
+
+#ifndef _WIN32
+ ret = getenv(var);
+#else // _WIN32
+ _dupenv_s(&ret, NULL, var);
+#endif // _WIN32
+
+ return ret;
+}
+
+void bc_vm_getenvFree(char* val) {
+ BC_UNUSED(val);
+#ifdef _WIN32
+ free(val);
+#endif // _WIN32
+}
+
+/**
+ * Sets a flag from an environment variable and the default.
+ * @param var The environment variable.
+ * @param def The default.
+ * @param flag The flag to set.
+ */
+static void bc_vm_setenvFlag(const char* const var, int def, uint16_t flag) {
+
+ // Get the value.
+ char* val = bc_vm_getenv(var);
+
+ // If there is no value...
+ if (val == NULL) {
+
+ // Set the default.
+ if (def) vm.flags |= flag;
+ else vm.flags &= ~(flag);
+ }
+ // Parse the value.
+ else if (strtoul(val, NULL, 0)) vm.flags |= flag;
+ else vm.flags &= ~(flag);
+
+ bc_vm_getenvFree(val);
+}
+
+/**
+ * Parses the arguments in {B,D]C_ENV_ARGS.
+ * @param env_args_name The environment variable to use.
+ */
+static void bc_vm_envArgs(const char* const env_args_name) {
+
+ char *env_args = bc_vm_getenv(env_args_name), *buf, *start;
+ char instr = '\0';
+
+ BC_SIG_ASSERT_LOCKED;
+
+ if (env_args == NULL) return;
+
+ // Windows already allocates, so we don't need to.
+#ifndef _WIN32
+ start = buf = vm.env_args_buffer = bc_vm_strdup(env_args);
+#else // _WIN32
+ start = buf = vm.env_args_buffer = env_args;
+#endif // _WIN32
+
+ assert(buf != NULL);
+
+ // Create two buffers for parsing. These need to stay throughout the entire
+ // execution of bc, unfortunately, because of filenames that might be in
+ // there.
+ bc_vec_init(&vm.env_args, sizeof(char*), BC_DTOR_NONE);
+ bc_vec_push(&vm.env_args, &env_args_name);
+
+ // While we haven't reached the end of the args...
+ while (*buf) {
+
+ // If we don't have whitespace...
+ if (!isspace(*buf)) {
+
+ // If we have the start of a string...
+ if (*buf == '"' || *buf == '\'') {
+
+ // Set stuff appropriately.
+ instr = *buf;
+ buf += 1;
+
+ // Check for the empty string.
+ if (*buf == instr) {
+ instr = '\0';
+ buf += 1;
+ continue;
+ }
+ }
+
+ // Push the pointer to the args buffer.
+ bc_vec_push(&vm.env_args, &buf);
+
+ // Parse the string.
+ while (*buf && ((!instr && !isspace(*buf)) ||
+ (instr && *buf != instr)))
+ {
+ buf += 1;
+ }
+
+ // If we did find the end of the string...
+ if (*buf) {
+
+ if (instr) instr = '\0';
+
+ // Reset stuff.
+ *buf = '\0';
+ buf += 1;
+ start = buf;
+ }
+ else if (instr) bc_error(BC_ERR_FATAL_OPTION, 0, start);
+ }
+ // If we have whitespace, eat it.
+ else buf += 1;
+ }
+
+ // Make sure to push a NULL pointer at the end.
+ buf = NULL;
+ bc_vec_push(&vm.env_args, &buf);
+
+ // Parse the arguments.
+ bc_args((int) vm.env_args.len - 1, bc_vec_item(&vm.env_args, 0), false);
+}
+
+/**
+ * Gets the {B,D}C_LINE_LENGTH.
+ * @param var The environment variable to pull it from.
+ * @return The line length.
+ */
+static size_t bc_vm_envLen(const char *var) {
+
+ char *lenv = bc_vm_getenv(var);
+ size_t i, len = BC_NUM_PRINT_WIDTH;
+ int num;
+
+ // Return the default with none.
+ if (lenv == NULL) return len;
+
+ len = strlen(lenv);
+
+ // Figure out if it's a number.
+ for (num = 1, i = 0; num && i < len; ++i) num = isdigit(lenv[i]);
+
+ // If it is a number...
+ if (num) {
+
+ // Parse it and clamp it if needed.
+ len = (size_t) atoi(lenv) - 1;
+ if (len == 1 || len >= UINT16_MAX) len = BC_NUM_PRINT_WIDTH;
+ }
+ // Set the default.
+ else len = BC_NUM_PRINT_WIDTH;
+
+ bc_vm_getenvFree(lenv);
+
+ 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, i.e.,
+ // has raw mode disabled.
+ 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);
+
+ if (BC_PARSE_IS_INITED(&vm.read_prs, &vm.prog)) {
+ bc_vec_free(&vm.read_buf);
+ bc_parse_free(&vm.read_prs);
+ }
+
+ bc_parse_free(&vm.prs);
+ bc_program_free(&vm.prog);
+
+ bc_slabvec_free(&vm.other_slabs);
+ bc_slabvec_free(&vm.main_slabs);
+ bc_slabvec_free(&vm.main_const_slab);
+#endif // !BC_ENABLE_LIBRARY
+
+ bc_vm_freeTemps();
+#endif // NDEBUG
+
+#if !BC_ENABLE_LIBRARY
+ // We always want to flush.
+ bc_file_free(&vm.fout);
+ bc_file_free(&vm.ferr);
+#endif // !BC_ENABLE_LIBRARY
+}
+
+void bc_vm_addTemp(BcDig *num) {
+
+ // If we don't have room, just free.
+ if (vm.temps_len == BC_VM_MAX_TEMPS) free(num);
+ else {
+
+ // Add to the buffer and length.
+ temps_buf[vm.temps_len] = num;
+ vm.temps_len += 1;
+ }
+}
+
+BcDig* bc_vm_takeTemp(void) {
+ if (!vm.temps_len) return NULL;
+ vm.temps_len -= 1;
+ return temps_buf[vm.temps_len];
+}
+
+void bc_vm_freeTemps(void) {
+
+ size_t i;
+
+ BC_SIG_ASSERT_LOCKED;
+
+ if (!vm.temps_len) return;
+
+ // Free them all...
+ for (i = 0; i < vm.temps_len; ++i) free(temps_buf[i]);
+
+ vm.temps_len = 0;
+}
+
+inline size_t bc_vm_arraySize(size_t n, size_t size) {
+ size_t res = n * size;
+ if (BC_ERR(BC_VM_MUL_OVERFLOW(n, size, res)))
+ bc_vm_fatalError(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))
+ bc_vm_fatalError(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_freeTemps();
+
+ ptr = malloc(n);
+
+ if (BC_ERR(ptr == NULL)) bc_vm_fatalError(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_freeTemps();
+
+ temp = realloc(ptr, n);
+
+ if (BC_ERR(temp == NULL)) bc_vm_fatalError(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 == NULL)) {
+
+ bc_vm_freeTemps();
+
+ s = strdup(str);
+
+ if (BC_ERR(s == NULL)) bc_vm_fatalError(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, BcFlushType type) {
+#if BC_ENABLE_LIBRARY
+ bc_vec_pushByte(&vm.out, (uchar) c);
+#else // BC_ENABLE_LIBRARY
+ bc_file_putchar(&vm.fout, type, (uchar) c);
+ vm.nchars = (c == '\n' ? 0 : vm.nchars + 1);
+#endif // BC_ENABLE_LIBRARY
+}
+
+#if !BC_ENABLE_LIBRARY
+
+#ifdef __OpenBSD__
+
+/**
+ * Aborts with a message. This should never be called because I have carefully
+ * made sure that the calls to pledge() and unveil() are correct, but it's here
+ * just in case.
+ * @param msg The message to print.
+ */
+BC_NORETURN static void bc_abortm(const char* msg) {
+ bc_file_puts(&vm.ferr, bc_flush_none, msg);
+ bc_file_puts(&vm.ferr, bc_flush_none, "; this is a bug");
+ bc_file_flush(&vm.ferr, bc_flush_none);
+ abort();
+}
+
+void bc_pledge(const char *promises, const char* execpromises) {
+ int r = pledge(promises, execpromises);
+ if (r) bc_abortm("pledge() failed");
+}
+
+#if BC_ENABLE_EXTRA_MATH
+
+/**
+ * A convenience and portability function for OpenBSD's unveil().
+ * @param path The path.
+ * @param permissions The permissions for the path.
+ */
+static void bc_unveil(const char *path, const char *permissions) {
+ int r = unveil(path, permissions);
+ if (r) bc_abortm("unveil() failed");
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+#else // __OpenBSD__
+
+void bc_pledge(const char *promises, const char *execpromises) {
+ BC_UNUSED(promises);
+ BC_UNUSED(execpromises);
+}
+
+#if BC_ENABLE_EXTRA_MATH
+static void bc_unveil(const char *path, const char *permissions) {
+ BC_UNUSED(path);
+ BC_UNUSED(permissions);
+}
+#endif // BC_ENABLE_EXTRA_MATH
+
+#endif // __OpenBSD__
+
+/**
+ * Cleans unneeded variables, arrays, functions, strings, and constants when
+ * done executing a line of stdin. This is to prevent memory usage growing
+ * without bound. This is an idea from busybox.
+ */
+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 all is good, go ahead and reset.
+ if (good) bc_program_reset(&vm.prog);
+
+#if BC_ENABLED
+ // bc has this extra condition. If it not satisfied, it is in the middle of
+ // a parse.
+ if (good && BC_IS_BC) good = !BC_PARSE_NO_EXEC(&vm.prs);
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+ // For dc, it is safe only when all of the results on the results stack are
+ // safe, which means that they are temporaries or other things that don't
+ // need strings or constants.
+ 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.
+ if (good && vm.prog.stack.len == 1 && ip->idx == f->code.len) {
+
+#if BC_ENABLED
+ if (BC_IS_BC) {
+
+ bc_vec_popAll(&f->labels);
+ bc_vec_popAll(&f->strs);
+ bc_vec_popAll(&f->consts);
+
+ // I can't clear out the other_slabs because it has functions,
+ // consts, strings, vars, and arrays. It has strings from *other*
+ // functions, specifically.
+ bc_slabvec_clear(&vm.main_const_slab);
+ bc_slabvec_clear(&vm.main_slabs);
+ }
+#endif // BC_ENABLED
+
+#if DC_ENABLED
+ // Note to self: you cannot delete strings and functions. Deal with it.
+ if (BC_IS_DC) {
+ bc_vec_popAll(vm.prog.consts);
+ bc_slabvec_clear(&vm.main_const_slab);
+ }
+#endif // DC_ENABLED
+
+ bc_vec_popAll(&f->code);
+
+ ip->idx = 0;
+ }
+}
+
+/**
+ * Process a bunch of text.
+ * @param text The text to process.
+ * @param is_stdin True if the text came from stdin, false otherwise.
+ */
+static void bc_vm_process(const char *text, bool is_stdin) {
+
+ // Set up the parser.
+ bc_parse_text(&vm.prs, text, is_stdin);
+
+ do {
+
+#if BC_ENABLED
+ // If the first token is the keyword define, then we need to do this
+ // specially because bc thinks it may not be able to parse.
+ if (vm.prs.l.t == BC_LEX_KW_DEFINE) vm.parse(&vm.prs);
+#endif // BC_ENABLED
+
+ // Parse it all.
+ while (BC_PARSE_CAN_PARSE(vm.prs)) vm.parse(&vm.prs);
+
+ // Execute if possible.
+ if(BC_IS_DC || !BC_PARSE_NO_EXEC(&vm.prs)) bc_program_exec(&vm.prog);
+
+ assert(BC_IS_DC || vm.prog.results.len == 0);
+
+ // Flush in interactive mode.
+ if (BC_I) bc_file_flush(&vm.fout, bc_flush_save);
+
+ } while (vm.prs.l.t != BC_LEX_EOF);
+}
+
+#if BC_ENABLED
+
+/**
+ * Ends an if statement that ends a file. This is to ensure that full parses
+ * happen when a file finishes. Without this, bc thinks that it cannot parse
+ * any further. But if we reach the end of a file, we know we can add an empty
+ * else clause.
+ */
+static void bc_vm_endif(void) {
+
+ size_t i;
+ bool good;
+
+ // Not a problem if this is true.
+ if (BC_NO_ERR(!BC_PARSE_NO_EXEC(&vm.prs))) return;
+
+ good = true;
+
+ // Find an instance of a body that needs closing, i.e., a statement that did
+ // not have a right brace when it should have.
+ 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 we did not find such an instance...
+ if (good) {
+
+ // We set this to restore it later. We don't want the parser thinking
+ // that we are on stdin for this one because it will want more.
+ bool is_stdin = vm.is_stdin;
+
+ vm.is_stdin = false;
+
+ // Cheat and keep parsing empty else clauses until all of them are
+ // satisfied.
+ while (BC_PARSE_IF_END(&vm.prs)) bc_vm_process("else {}", false);
+
+ vm.is_stdin = is_stdin;
+ }
+ // If we reach here, a block was not properly closed, and we should error.
+ else bc_parse_err(&vm.prs, BC_ERR_PARSE_BLOCK);
+}
+#endif // BC_ENABLED
+
+/**
+ * Processes a file.
+ * @param file The filename.
+ */
+static void bc_vm_file(const char *file) {
+
+ char *data = NULL;
+
+ assert(!vm.sig_pop);
+
+ // Set up the lexer.
+ bc_lex_file(&vm.prs.l, file);
+
+ BC_SIG_LOCK;
+
+ // Read the file.
+ data = bc_read_file(file);
+
+ assert(data != NULL);
+
+ BC_SETJMP_LOCKED(err);
+
+ BC_SIG_UNLOCK;
+
+ // Process it.
+ bc_vm_process(data, false);
+
+#if BC_ENABLED
+ // Make sure to end any open if statements.
+ if (BC_IS_BC) bc_vm_endif();
+#endif // BC_ENABLED
+
+err:
+ BC_SIG_MAYLOCK;
+
+ // Cleanup.
+ 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;
+}
+
+bool bc_vm_readLine(bool clear) {
+
+ BcStatus s;
+ bool good;
+
+ // Clear the buffer if desired.
+ if (clear) bc_vec_empty(&vm.buffer);
+
+ // Empty the line buffer.
+ bc_vec_empty(&vm.line_buf);
+
+ if (vm.eof) return false;
+
+ do {
+ // bc_read_line() must always return either BC_STATUS_SUCCESS or
+ // BC_STATUS_EOF. Everything else, it and whatever it calls, must jump
+ // out instead.
+ s = bc_read_line(&vm.line_buf, ">>> ");
+ vm.eof = (s == BC_STATUS_EOF);
+ } while (!(s) && !vm.eof && vm.line_buf.len < 1);
+
+ good = (vm.line_buf.len > 1);
+
+ // Concat if we found something.
+ if (good) bc_vec_concat(&vm.buffer, vm.line_buf.v);
+
+ return good;
+}
+
+/**
+ * Processes text from stdin.
+ */
+static void bc_vm_stdin(void) {
+
+ bool clear = true;
+
+ vm.is_stdin = true;
+
+ // Set up the lexer.
+ bc_lex_file(&vm.prs.l, bc_program_stdin_name);
+
+ // These are global so that the dc lexer can access them, but they are tied
+ // to this function, really. Well, this and bc_vm_readLine(). These are the
+ // reason that we have vm.is_stdin to tell the dc lexer if we are reading
+ // from stdin. Well, both lexers care. And the reason they care is so that
+ // if a comment or a string goes across multiple lines, the lexer can
+ // request more data from stdin until the comment or string is ended.
+ BC_SIG_LOCK;
+ bc_vec_init(&vm.buffer, sizeof(uchar), BC_DTOR_NONE);
+ bc_vec_init(&vm.line_buf, sizeof(uchar), BC_DTOR_NONE);
+ BC_SETJMP_LOCKED(err);
+ BC_SIG_UNLOCK;
+
+// This label exists because errors can cause jumps to end up at the err label
+// below. If that happens, and the error should be cleared and execution
+// continue, then we need to jump back.
+restart:
+
+ // While we still read data from stdin.
+ while (bc_vm_readLine(clear)) {
+
+ size_t len = vm.buffer.len - 1;
+ const char *str = vm.buffer.v;
+
+ // We don't want to clear the buffer when the line ends with a backslash
+ // because a backslash newline is special in bc.
+ clear = (len < 2 || str[len - 2] != '\\' || str[len - 1] != '\n');
+ if (!clear) continue;
+
+ // Process the data.
+ bc_vm_process(vm.buffer.v, true);
+
+ if (vm.eof) break;
+ else bc_vm_clean();
+ }
+
+#if BC_ENABLED
+ // End the if statements.
+ if (BC_IS_BC) bc_vm_endif();
+#endif // BC_ENABLED
+
+err:
+ BC_SIG_MAYLOCK;
+
+ // Cleanup.
+ bc_vm_clean();
+
+#if !BC_ENABLE_MEMCHECK
+ assert(vm.status != BC_STATUS_ERROR_FATAL);
+
+ vm.status = vm.status == BC_STATUS_QUIT || !BC_I ?
+ vm.status : BC_STATUS_SUCCESS;
+#else // !BC_ENABLE_MEMCHECK
+ vm.status = vm.status == BC_STATUS_ERROR_FATAL ||
+ vm.status == BC_STATUS_QUIT || !BC_I ?
+ vm.status : BC_STATUS_SUCCESS;
+#endif // !BC_ENABLE_MEMCHECK
+
+ if (!vm.status && !vm.eof) {
+ bc_vec_empty(&vm.buffer);
+ BC_LONGJMP_STOP;
+ BC_SIG_UNLOCK;
+ goto restart;
+ }
+
+#ifndef NDEBUG
+ // Since these are tied to this function, free them here.
+ bc_vec_free(&vm.line_buf);
+ bc_vec_free(&vm.buffer);
+#endif // NDEBUG
+
+ BC_LONGJMP_CONT;
+}
+
+#if BC_ENABLED
+
+/**
+ * Loads a math library.
+ * @param name The name of the library.
+ * @param text The text of the source code.
+ */
+static void bc_vm_load(const char *name, const char *text) {
+
+ bc_lex_file(&vm.prs.l, name);
+ bc_parse_text(&vm.prs, text, false);
+
+ while (vm.prs.l.t != BC_LEX_EOF) vm.parse(&vm.prs);
+}
+
+#endif // BC_ENABLED
+
+/**
+ * Loads the default error messages.
+ */
+static void bc_vm_defaultMsgs(void) {
+
+ size_t i;
+
+ vm.func_header = bc_err_func_header;
+
+ // Load the error categories.
+ for (i = 0; i < BC_ERR_IDX_NELEMS + BC_ENABLED; ++i)
+ vm.err_ids[i] = bc_errs[i];
+
+ // Load the error messages.
+ for (i = 0; i < BC_ERR_NELEMS; ++i) vm.err_msgs[i] = bc_err_msgs[i];
+}
+
+/**
+ * Loads the error messages for the locale. If NLS is disabled, this just loads
+ * the default messages.
+ */
+static void bc_vm_gettext(void) {
+
+#if BC_ENABLE_NLS
+ uchar id = 0;
+ int set = 1, msg = 1;
+ size_t i;
+
+ // If no locale, load the defaults.
+ if (vm.locale == NULL) {
+ vm.catalog = BC_VM_INVALID_CATALOG;
+ bc_vm_defaultMsgs();
+ return;
+ }
+
+ vm.catalog = catopen(BC_MAINEXEC, NL_CAT_LOCALE);
+
+ // If no catalog, load the defaults.
+ if (vm.catalog == BC_VM_INVALID_CATALOG) {
+ bc_vm_defaultMsgs();
+ return;
+ }
+
+ // Load the function header.
+ vm.func_header = catgets(vm.catalog, set, msg, bc_err_func_header);
+
+ // Load the error categories.
+ 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];
+
+ // Load the error messages. In order to understand this loop, you must know
+ // the order of messages and categories in the enum and in the locale files.
+ 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
+}
+
+/**
+ * Starts execution. Really, this is a function of historical accident; it could
+ * probably be combined with bc_vm_boot(), but I don't care enough. Really, this
+ * function starts when execution of bc or dc source code starts.
+ */
+static void bc_vm_exec(void) {
+
+ size_t i;
+ bool has_file = false;
+ BcVec buf;
+
+#if BC_ENABLED
+ // Load the math libraries.
+ if (BC_IS_BC && (vm.flags & BC_FLAG_L)) {
+
+ // Can't allow redefinitions in the builtin library.
+ vm.no_redefine = true;
+
+ 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
+
+ // Make sure to clear this.
+ vm.no_redefine = false;
+
+ // Execute to ensure that all is hunky dory. Without this, scale can be
+ // set improperly.
+ bc_program_exec(&vm.prog);
+ }
+#endif // BC_ENABLED
+
+ // If there are expressions to execute...
+ if (vm.exprs.len) {
+
+ size_t len = vm.exprs.len - 1;
+ bool more;
+
+ BC_SIG_LOCK;
+
+ // Create this as a buffer for reading into.
+ bc_vec_init(&buf, sizeof(uchar), BC_DTOR_NONE);
+
+#ifndef NDEBUG
+ BC_SETJMP_LOCKED(err);
+#endif // NDEBUG
+
+ BC_SIG_UNLOCK;
+
+ // Prepare the lexer.
+ bc_lex_file(&vm.prs.l, bc_program_exprs_name);
+
+ // Process the expressions one at a time.
+ do {
+
+ more = bc_read_buf(&buf, vm.exprs.v, &len);
+ bc_vec_pushByte(&buf, '\0');
+ bc_vm_process(buf.v, false);
+
+ bc_vec_popAll(&buf);
+
+ } while (more);
+
+ BC_SIG_LOCK;
+
+ bc_vec_free(&buf);
+
+#ifndef NDEBUG
+ BC_UNSETJMP;
+#endif // NDEBUG
+
+ BC_SIG_UNLOCK;
+
+ // Sometimes, executing expressions means we need to quit.
+ if (!vm.no_exprs && vm.exit_exprs) return;
+ }
+
+ // Process files.
+ 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_ENABLE_EXTRA_MATH
+ // These are needed for the pseudo-random number generator.
+ bc_unveil("/dev/urandom", "r");
+ bc_unveil("/dev/random", "r");
+ bc_unveil(NULL, NULL);
+#endif // BC_ENABLE_EXTRA_MATH
+
+#if BC_ENABLE_HISTORY
+
+ // We need to keep tty if history is enabled, and we need to keep rpath for
+ // the times when we read from /dev/urandom.
+ if (BC_TTY && !vm.history.badTerm) {
+ bc_pledge(bc_pledge_end_history, NULL);
+ }
+ else
+#endif // BC_ENABLE_HISTORY
+ {
+ bc_pledge(bc_pledge_end, NULL);
+ }
+
+#if BC_ENABLE_AFL
+ // This is the thing that makes fuzzing with AFL++ so fast. If you move this
+ // back, you won't cause any problems, but fuzzing will slow down. If you
+ // move this forward, you won't fuzz anything because you will be skipping
+ // the reading from stdin.
+ __AFL_INIT();
+#endif // BC_ENABLE_AFL
+
+ // Execute from stdin. bc always does.
+ if (BC_IS_BC || !has_file) bc_vm_stdin();
+
+// These are all protected by ifndef NDEBUG because if these are needed, bc is
+// going 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[]) {
+
+ int ttyin, ttyout, ttyerr;
+ bool tty;
+ const char* const env_len = BC_IS_BC ? "BC_LINE_LENGTH" : "DC_LINE_LENGTH";
+ const char* const env_args = BC_IS_BC ? "BC_ENV_ARGS" : "DC_ENV_ARGS";
+
+ // We need to know which of stdin, stdout, and stderr are tty's.
+ ttyin = isatty(STDIN_FILENO);
+ ttyout = isatty(STDOUT_FILENO);
+ ttyerr = isatty(STDERR_FILENO);
+ tty = (ttyin != 0 && ttyout != 0 && ttyerr != 0);
+
+ vm.flags |= ttyin ? BC_FLAG_TTYIN : 0;
+ vm.flags |= tty ? BC_FLAG_TTY : 0;
+ vm.flags |= ttyin && ttyout ? BC_FLAG_I : 0;
+
+ // Set up signals.
+ bc_vm_sigaction();
+
+ // Initialize some vm stuff. This is separate to make things easier for the
+ // library.
+ bc_vm_init();
+
+ // Explicitly set this in case NULL isn't all zeroes.
+ vm.file = NULL;
+
+ // Set the error messages.
+ bc_vm_gettext();
+
+ // Initialize the output file buffers. They each take portions of the global
+ // buffer. stdout gets more because it will probably have more data.
+ 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);
+
+ // Set the input buffer to the rest of the global buffer.
+ vm.buf = output_bufs + BC_VM_STDOUT_BUF_SIZE + BC_VM_STDERR_BUF_SIZE;
+
+ // Set the line length by environment variable.
+ vm.line_len = (uint16_t) bc_vm_envLen(env_len);
+
+ // Clear the files and expressions vectors, just in case. This marks them as
+ // *not* allocated.
+ bc_vec_clear(&vm.files);
+ bc_vec_clear(&vm.exprs);
+
+#if !BC_ENABLE_LIBRARY
+
+ // Initialize the slab vectors.
+ bc_slabvec_init(&vm.main_const_slab);
+ bc_slabvec_init(&vm.main_slabs);
+ bc_slabvec_init(&vm.other_slabs);
+
+#endif // !BC_ENABLE_LIBRARY
+
+ // Initialize the program and main parser. These have to be in this order
+ // because the program has to be initialized first, since a pointer to it is
+ // passed to the parser.
+ bc_program_init(&vm.prog);
+ bc_parse_init(&vm.prs, &vm.prog, BC_PROG_MAIN);
+
+#if BC_ENABLED
+ // bc checks this environment variable to see if it should run in standard
+ // mode.
+ if (BC_IS_BC) {
+
+ char* var = bc_vm_getenv("POSIXLY_CORRECT");
+
+ vm.flags |= BC_FLAG_S * (var != NULL);
+ bc_vm_getenvFree(var);
+ }
+#endif // BC_ENABLED
+
+ // Set defaults.
+ vm.flags |= BC_TTY ? BC_FLAG_P | BC_FLAG_R : 0;
+ vm.flags |= BC_I ? BC_FLAG_Q : 0;
+
+#if BC_ENABLED
+ if (BC_IS_BC && BC_I) {
+ // Set whether we print the banner or not.
+ bc_vm_setenvFlag("BC_BANNER", BC_DEFAULT_BANNER, BC_FLAG_Q);
+ }
+#endif // BC_ENABLED
+
+ // Are we in TTY mode?
+ if (BC_TTY) {
+
+ const char* const env_tty = BC_IS_BC ? "BC_TTY_MODE" : "DC_TTY_MODE";
+ int env_tty_def = BC_IS_BC ? BC_DEFAULT_TTY_MODE : DC_DEFAULT_TTY_MODE;
+ const char* const env_prompt = BC_IS_BC ? "BC_PROMPT" : "DC_PROMPT";
+ int env_prompt_def = BC_IS_BC ? BC_DEFAULT_PROMPT : DC_DEFAULT_PROMPT;
+
+ // Set flags for TTY mode and prompt.
+ bc_vm_setenvFlag(env_tty, env_tty_def, BC_FLAG_TTY);
+ bc_vm_setenvFlag(env_prompt, tty ? env_prompt_def : 0, BC_FLAG_P);
+
+#if BC_ENABLE_HISTORY
+ // If TTY mode is used, activate history.
+ if (BC_TTY) bc_history_init(&vm.history);
+#endif // BC_ENABLE_HISTORY
+ }
+
+ // Process environment and command-line arguments.
+ bc_vm_envArgs(env_args);
+ bc_args(argc, argv, true);
+
+ // If we are in interactive mode...
+ if (BC_I) {
+
+ const char* const env_sigint = BC_IS_BC ? "BC_SIGINT_RESET" :
+ "DC_SIGINT_RESET";
+ int env_sigint_def = BC_IS_BC ? BC_DEFAULT_SIGINT_RESET :
+ DC_DEFAULT_SIGINT_RESET;
+
+ // Set whether we reset on SIGINT or not.
+ bc_vm_setenvFlag(env_sigint, env_sigint_def, BC_FLAG_SIGINT);
+ }
+
+#if BC_ENABLED
+ // Disable global stacks in POSIX mode.
+ if (BC_IS_POSIX) vm.flags &= ~(BC_FLAG_G);
+#endif // BC_ENABLED
+
+#if BC_ENABLED
+ // Print the banner if allowed. We have to be in bc, in interactive mode,
+ // and not be quieted by command-line option or environment variable.
+ if (BC_IS_BC && BC_I && (vm.flags & BC_FLAG_Q)) {
+ bc_vm_info(NULL);
+ bc_file_putchar(&vm.fout, bc_flush_none, '\n');
+ bc_file_flush(&vm.fout, bc_flush_none);
+ }
+#endif // BC_ENABLED
+
+ BC_SIG_UNLOCK;
+
+ // Start executing.
+ bc_vm_exec();
+}
+#endif // !BC_ENABLE_LIBRARY
+
+void bc_vm_init(void) {
+
+ BC_SIG_ASSERT_LOCKED;
+
+#if !BC_ENABLE_LIBRARY
+ // Set up the constant zero.
+ bc_num_setup(&vm.zero, vm.zero_num, BC_VM_ONE_CAP);
+#endif // !BC_ENABLE_LIBRARY
+
+ // Set up more constant BcNum's.
+ bc_num_setup(&vm.one, vm.one_num, BC_VM_ONE_CAP);
+ bc_num_one(&vm.one);
+
+ // Set up more constant BcNum's.
+ 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;
+
+ // Set up the maxes for the globals.
+ 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
+ vm.maxes[BC_PROG_MAX_RAND] = ((BcRand) 0) - 1;
+#endif // BC_ENABLE_EXTRA_MATH
+
+#if BC_ENABLED
+#if !BC_ENABLE_LIBRARY
+ // bc has a higher max ibase when it's not in POSIX mode.
+ if (BC_IS_BC && !BC_IS_POSIX)
+#endif // !BC_ENABLE_LIBRARY
+ {
+ vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_IBASE;
+ }
+#endif // BC_ENABLED
+}
+
+#if BC_ENABLE_LIBRARY
+void bc_vm_atexit(void) {
+
+ bc_vm_shutdown();
+
+#ifndef NDEBUG
+ bc_vec_free(&vm.jmp_bufs);
+#endif // NDEBUG
+}
+#else // BC_ENABLE_LIBRARY
+int bc_vm_atexit(int status) {
+
+ // Set the status correctly.
+ int s = BC_STATUS_IS_ERROR(status) ? status : BC_STATUS_SUCCESS;
+
+ bc_vm_shutdown();
+
+#ifndef NDEBUG
+ bc_vec_free(&vm.jmp_bufs);
+#endif // NDEBUG
+
+ return s;
+}
+#endif // BC_ENABLE_LIBRARY
diff --git a/contrib/bc/tests/all.sh b/contrib/bc/tests/all.sh
new file mode 100755
index 000000000000..d3e79ef80ece
--- /dev/null
+++ b/contrib/bc/tests/all.sh
@@ -0,0 +1,214 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+# We need to figure out if we should run stuff in parallel.
+pll=1
+
+while getopts "n" opt; do
+
+ case "$opt" in
+ n) pll=0 ; shift ; set -e ;;
+ ?) usage "Invalid option: $opt" ;;
+ esac
+
+done
+
+# Command-line processing.
+if [ "$#" -ge 1 ]; then
+ d="$1"
+ shift
+else
+ err_exit "usage: $script [-n] 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"
+
+# Set stuff for the correct calculator.
+if [ "$d" = "bc" ]; then
+ halt="quit"
+else
+ halt="q"
+fi
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+# Get the list of tests that require extra math.
+extra_required=$(cat "$testdir/extra_required.txt")
+
+pids=""
+
+printf '\nRunning %s tests...\n\n' "$d"
+
+# Run the tests one at a time.
+while read t; do
+
+ # If it requires extra, then skip if we don't have it.
+ if [ "$extra" -eq 0 ]; then
+ if [ -z "${extra_required##*$t*}" ]; then
+ printf 'Skipping %s %s\n' "$d" "$t"
+ continue
+ fi
+ fi
+
+ if [ "$pll" -ne 0 ]; then
+ sh "$testdir/test.sh" "$d" "$t" "$generate_tests" "$time_tests" "$exe" "$@" &
+ pids="$pids $!"
+ else
+ sh "$testdir/test.sh" "$d" "$t" "$generate_tests" "$time_tests" "$exe" "$@"
+ fi
+
+done < "$testdir/$d/all.txt"
+
+# stdin tests.
+if [ "$pll" -ne 0 ]; then
+ sh "$testdir/stdin.sh" "$d" "$exe" "$@" &
+ pids="$pids $!"
+else
+ sh "$testdir/stdin.sh" "$d" "$exe" "$@"
+fi
+
+# Script tests.
+if [ "$pll" -ne 0 ]; then
+ sh "$testdir/scripts.sh" "$d" "$extra" "$run_stack_tests" "$generate_tests" \
+ "$time_tests" "$exe" "$@" &
+ pids="$pids $!"
+else
+ sh "$testdir/scripts.sh" -n "$d" "$extra" "$run_stack_tests" "$generate_tests" \
+ "$time_tests" "$exe" "$@"
+fi
+
+# Read tests.
+if [ "$pll" -ne 0 ]; then
+ sh "$testdir/read.sh" "$d" "$exe" "$@" &
+ pids="$pids $!"
+else
+ sh "$testdir/read.sh" "$d" "$exe" "$@"
+fi
+
+# Error tests.
+if [ "$pll" -ne 0 ]; then
+ sh "$testdir/errors.sh" "$d" "$exe" "$@" &
+ pids="$pids $!"
+else
+ sh "$testdir/errors.sh" "$d" "$exe" "$@"
+fi
+
+# Test all the files in the errors directory. While the other error test (in
+# tests/errors.sh) does a test for every line, this does one test per file, but
+# it runs the file through stdin and as a file on the command-line.
+for testfile in $testdir/$d/errors/*.txt; do
+
+ b=$(basename "$testfile")
+
+ if [ "$pll" -ne 0 ]; then
+ sh "$testdir/error.sh" "$d" "$b" "$@" &
+ pids="$pids $!"
+ else
+ sh "$testdir/error.sh" "$d" "$b" "$@"
+ fi
+
+done
+
+# Other tests.
+if [ "$pll" -ne 0 ]; then
+ sh "$testdir/other.sh" "$d" "$extra" "$exe" "$@" &
+ pids="$pids $!"
+else
+ sh "$testdir/other.sh" "$d" "$extra" "$exe" "$@"
+fi
+
+if [ "$pll" -ne 0 ]; then
+
+ exit_err=0
+
+ for p in $pids; do
+
+ wait "$p"
+ err="$?"
+
+ if [ "$err" -ne 0 ]; then
+ printf 'A test failed!\n'
+ exit_err=1
+ fi
+ done
+
+ if [ "$exit_err" -ne 0 ]; then
+ exit 1
+ fi
+
+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..23244773b933
--- /dev/null
+++ b/contrib/bc/tests/bc/all.txt
@@ -0,0 +1,52 @@
+decimal
+print
+parse
+lib2
+print2
+length
+scale
+shift
+add
+subtract
+multiply
+divide
+modulus
+power
+sqrt
+trunc
+places
+vars
+boolean
+comp
+abs
+assignments
+functions
+scientific
+engineering
+globals
+strings
+strings2
+letters
+exponent
+log
+pi
+arctangent
+sine
+cosine
+bessel
+arrays
+misc
+misc1
+misc2
+misc3
+misc4
+misc5
+misc6
+misc7
+void
+rand
+recursive_arrays
+divmod
+modexp
+bitfuncs
+leadingzero
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/bitfuncs.txt b/contrib/bc/tests/bc/bitfuncs.txt
new file mode 100644
index 000000000000..f6a825fb6b5e
--- /dev/null
+++ b/contrib/bc/tests/bc/bitfuncs.txt
@@ -0,0 +1,5400 @@
+band(13946233938940740889, 12028823668264674112)
+bor(13946233938940740889, 12028823668264674112)
+bxor(13946233938940740889, 12028823668264674112)
+bshl(2366588185, 0)
+bshr(2366588185, 0)
+bshl(347743040, 25)
+bshr(347743040, 25)
+bnot8(13946233938940740889)
+bnot8(25)
+bnot16(13946233938940740889)
+bnot16(17689)
+bnot32(13946233938940740889)
+bnot32(2366588185)
+bnot64(13946233938940740889)
+brev8(13946233938940740889)
+brev8(25)
+brev16(13946233938940740889)
+brev16(17689)
+brev32(13946233938940740889)
+brev32(2366588185)
+brev64(13946233938940740889)
+brol8(13946233938940740889, 12028823668264674112)
+brol8(25, 12028823668264674112)
+brol8(13946233938940740889, 64)
+brol8(25, 64)
+brol16(13946233938940740889, 12028823668264674112)
+brol16(17689, 12028823668264674112)
+brol16(13946233938940740889, 9024)
+brol16(17689, 9024)
+brol32(13946233938940740889, 12028823668264674112)
+brol32(2366588185, 12028823668264674112)
+brol32(13946233938940740889, 347743040)
+brol32(2366588185, 347743040)
+brol64(13946233938940740889, 12028823668264674112)
+bror8(13946233938940740889, 12028823668264674112)
+bror8(25, 12028823668264674112)
+bror8(13946233938940740889, 64)
+bror8(25, 64)
+bror16(13946233938940740889, 12028823668264674112)
+bror16(17689, 12028823668264674112)
+bror16(13946233938940740889, 9024)
+bror16(17689, 9024)
+bror32(13946233938940740889, 12028823668264674112)
+bror32(2366588185, 12028823668264674112)
+bror32(13946233938940740889, 347743040)
+bror32(2366588185, 347743040)
+bror64(13946233938940740889, 12028823668264674112)
+bmod8(13946233938940740889)
+bmod8(25)
+bmod16(13946233938940740889)
+bmod16(17689)
+bmod32(13946233938940740889)
+bmod32(2366588185)
+bmod64(13946233938940740889)
+band(14844027055899793688, 4619699720745622714)
+bor(14844027055899793688, 4619699720745622714)
+bxor(14844027055899793688, 4619699720745622714)
+bshl(3610368280, 26)
+bshr(3610368280, 26)
+bshl(2013502650, 24)
+bshr(2013502650, 24)
+bnot8(14844027055899793688)
+bnot8(24)
+bnot16(14844027055899793688)
+bnot16(55576)
+bnot32(14844027055899793688)
+bnot32(3610368280)
+bnot64(14844027055899793688)
+brev8(14844027055899793688)
+brev8(24)
+brev16(14844027055899793688)
+brev16(55576)
+brev32(14844027055899793688)
+brev32(3610368280)
+brev64(14844027055899793688)
+brol8(14844027055899793688, 4619699720745622714)
+brol8(24, 4619699720745622714)
+brol8(14844027055899793688, 186)
+brol8(24, 186)
+brol16(14844027055899793688, 4619699720745622714)
+brol16(55576, 4619699720745622714)
+brol16(14844027055899793688, 40122)
+brol16(55576, 40122)
+brol32(14844027055899793688, 4619699720745622714)
+brol32(3610368280, 4619699720745622714)
+brol32(14844027055899793688, 2013502650)
+brol32(3610368280, 2013502650)
+brol64(14844027055899793688, 4619699720745622714)
+bror8(14844027055899793688, 4619699720745622714)
+bror8(24, 4619699720745622714)
+bror8(14844027055899793688, 186)
+bror8(24, 186)
+bror16(14844027055899793688, 4619699720745622714)
+bror16(55576, 4619699720745622714)
+bror16(14844027055899793688, 40122)
+bror16(55576, 40122)
+bror32(14844027055899793688, 4619699720745622714)
+bror32(3610368280, 4619699720745622714)
+bror32(14844027055899793688, 2013502650)
+bror32(3610368280, 2013502650)
+bror64(14844027055899793688, 4619699720745622714)
+bmod8(14844027055899793688)
+bmod8(24)
+bmod16(14844027055899793688)
+bmod16(55576)
+bmod32(14844027055899793688)
+bmod32(3610368280)
+bmod64(14844027055899793688)
+band(8303249650730161219, 7466469472095745231)
+bor(8303249650730161219, 7466469472095745231)
+bxor(8303249650730161219, 7466469472095745231)
+bshl(2569557059, 15)
+bshr(2569557059, 15)
+bshl(43037903, 3)
+bshr(43037903, 3)
+bnot8(8303249650730161219)
+bnot8(67)
+bnot16(8303249650730161219)
+bnot16(21571)
+bnot32(8303249650730161219)
+bnot32(2569557059)
+bnot64(8303249650730161219)
+brev8(8303249650730161219)
+brev8(67)
+brev16(8303249650730161219)
+brev16(21571)
+brev32(8303249650730161219)
+brev32(2569557059)
+brev64(8303249650730161219)
+brol8(8303249650730161219, 7466469472095745231)
+brol8(67, 7466469472095745231)
+brol8(8303249650730161219, 207)
+brol8(67, 207)
+brol16(8303249650730161219, 7466469472095745231)
+brol16(21571, 7466469472095745231)
+brol16(8303249650730161219, 46287)
+brol16(21571, 46287)
+brol32(8303249650730161219, 7466469472095745231)
+brol32(2569557059, 7466469472095745231)
+brol32(8303249650730161219, 43037903)
+brol32(2569557059, 43037903)
+brol64(8303249650730161219, 7466469472095745231)
+bror8(8303249650730161219, 7466469472095745231)
+bror8(67, 7466469472095745231)
+bror8(8303249650730161219, 207)
+bror8(67, 207)
+bror16(8303249650730161219, 7466469472095745231)
+bror16(21571, 7466469472095745231)
+bror16(8303249650730161219, 46287)
+bror16(21571, 46287)
+bror32(8303249650730161219, 7466469472095745231)
+bror32(2569557059, 7466469472095745231)
+bror32(8303249650730161219, 43037903)
+bror32(2569557059, 43037903)
+bror64(8303249650730161219, 7466469472095745231)
+bmod8(8303249650730161219)
+bmod8(67)
+bmod16(8303249650730161219)
+bmod16(21571)
+bmod32(8303249650730161219)
+bmod32(2569557059)
+bmod64(8303249650730161219)
+band(15305239921947559796, 1131748027708318092)
+bor(15305239921947559796, 1131748027708318092)
+bxor(15305239921947559796, 1131748027708318092)
+bshl(1305462644, 12)
+bshr(1305462644, 12)
+bshl(3201147276, 20)
+bshr(3201147276, 20)
+bnot8(15305239921947559796)
+bnot8(116)
+bnot16(15305239921947559796)
+bnot16(51060)
+bnot32(15305239921947559796)
+bnot32(1305462644)
+bnot64(15305239921947559796)
+brev8(15305239921947559796)
+brev8(116)
+brev16(15305239921947559796)
+brev16(51060)
+brev32(15305239921947559796)
+brev32(1305462644)
+brev64(15305239921947559796)
+brol8(15305239921947559796, 1131748027708318092)
+brol8(116, 1131748027708318092)
+brol8(15305239921947559796, 140)
+brol8(116, 140)
+brol16(15305239921947559796, 1131748027708318092)
+brol16(51060, 1131748027708318092)
+brol16(15305239921947559796, 41356)
+brol16(51060, 41356)
+brol32(15305239921947559796, 1131748027708318092)
+brol32(1305462644, 1131748027708318092)
+brol32(15305239921947559796, 3201147276)
+brol32(1305462644, 3201147276)
+brol64(15305239921947559796, 1131748027708318092)
+bror8(15305239921947559796, 1131748027708318092)
+bror8(116, 1131748027708318092)
+bror8(15305239921947559796, 140)
+bror8(116, 140)
+bror16(15305239921947559796, 1131748027708318092)
+bror16(51060, 1131748027708318092)
+bror16(15305239921947559796, 41356)
+bror16(51060, 41356)
+bror32(15305239921947559796, 1131748027708318092)
+bror32(1305462644, 1131748027708318092)
+bror32(15305239921947559796, 3201147276)
+bror32(1305462644, 3201147276)
+bror64(15305239921947559796, 1131748027708318092)
+bmod8(15305239921947559796)
+bmod8(116)
+bmod16(15305239921947559796)
+bmod16(51060)
+bmod32(15305239921947559796)
+bmod32(1305462644)
+bmod64(15305239921947559796)
+band(14343637700476478964, 3494204366248846339)
+bor(14343637700476478964, 3494204366248846339)
+bxor(14343637700476478964, 3494204366248846339)
+bshl(600647156, 3)
+bshr(600647156, 3)
+bshl(2799805443, 20)
+bshr(2799805443, 20)
+bnot8(14343637700476478964)
+bnot8(244)
+bnot16(14343637700476478964)
+bnot16(9716)
+bnot32(14343637700476478964)
+bnot32(600647156)
+bnot64(14343637700476478964)
+brev8(14343637700476478964)
+brev8(244)
+brev16(14343637700476478964)
+brev16(9716)
+brev32(14343637700476478964)
+brev32(600647156)
+brev64(14343637700476478964)
+brol8(14343637700476478964, 3494204366248846339)
+brol8(244, 3494204366248846339)
+brol8(14343637700476478964, 3)
+brol8(244, 3)
+brol16(14343637700476478964, 3494204366248846339)
+brol16(9716, 3494204366248846339)
+brol16(14343637700476478964, 41987)
+brol16(9716, 41987)
+brol32(14343637700476478964, 3494204366248846339)
+brol32(600647156, 3494204366248846339)
+brol32(14343637700476478964, 2799805443)
+brol32(600647156, 2799805443)
+brol64(14343637700476478964, 3494204366248846339)
+bror8(14343637700476478964, 3494204366248846339)
+bror8(244, 3494204366248846339)
+bror8(14343637700476478964, 3)
+bror8(244, 3)
+bror16(14343637700476478964, 3494204366248846339)
+bror16(9716, 3494204366248846339)
+bror16(14343637700476478964, 41987)
+bror16(9716, 41987)
+bror32(14343637700476478964, 3494204366248846339)
+bror32(600647156, 3494204366248846339)
+bror32(14343637700476478964, 2799805443)
+bror32(600647156, 2799805443)
+bror64(14343637700476478964, 3494204366248846339)
+bmod8(14343637700476478964)
+bmod8(244)
+bmod16(14343637700476478964)
+bmod16(9716)
+bmod32(14343637700476478964)
+bmod32(600647156)
+bmod64(14343637700476478964)
+band(16821131222458671059, 8707395051150237471)
+bor(16821131222458671059, 8707395051150237471)
+bxor(16821131222458671059, 8707395051150237471)
+bshl(2195824595, 31)
+bshr(2195824595, 31)
+bshl(1322114847, 19)
+bshr(1322114847, 19)
+bnot8(16821131222458671059)
+bnot8(211)
+bnot16(16821131222458671059)
+bnot16(40915)
+bnot32(16821131222458671059)
+bnot32(2195824595)
+bnot64(16821131222458671059)
+brev8(16821131222458671059)
+brev8(211)
+brev16(16821131222458671059)
+brev16(40915)
+brev32(16821131222458671059)
+brev32(2195824595)
+brev64(16821131222458671059)
+brol8(16821131222458671059, 8707395051150237471)
+brol8(211, 8707395051150237471)
+brol8(16821131222458671059, 31)
+brol8(211, 31)
+brol16(16821131222458671059, 8707395051150237471)
+brol16(40915, 8707395051150237471)
+brol16(16821131222458671059, 57119)
+brol16(40915, 57119)
+brol32(16821131222458671059, 8707395051150237471)
+brol32(2195824595, 8707395051150237471)
+brol32(16821131222458671059, 1322114847)
+brol32(2195824595, 1322114847)
+brol64(16821131222458671059, 8707395051150237471)
+bror8(16821131222458671059, 8707395051150237471)
+bror8(211, 8707395051150237471)
+bror8(16821131222458671059, 31)
+bror8(211, 31)
+bror16(16821131222458671059, 8707395051150237471)
+bror16(40915, 8707395051150237471)
+bror16(16821131222458671059, 57119)
+bror16(40915, 57119)
+bror32(16821131222458671059, 8707395051150237471)
+bror32(2195824595, 8707395051150237471)
+bror32(16821131222458671059, 1322114847)
+bror32(2195824595, 1322114847)
+bror64(16821131222458671059, 8707395051150237471)
+bmod8(16821131222458671059)
+bmod8(211)
+bmod16(16821131222458671059)
+bmod16(40915)
+bmod32(16821131222458671059)
+bmod32(2195824595)
+bmod64(16821131222458671059)
+band(17133933039273200696, 18354093072705654326)
+bor(17133933039273200696, 18354093072705654326)
+bxor(17133933039273200696, 18354093072705654326)
+bshl(3677703224, 22)
+bshr(3677703224, 22)
+bshl(3440643638, 24)
+bshr(3440643638, 24)
+bnot8(17133933039273200696)
+bnot8(56)
+bnot16(17133933039273200696)
+bnot16(19512)
+bnot32(17133933039273200696)
+bnot32(3677703224)
+bnot64(17133933039273200696)
+brev8(17133933039273200696)
+brev8(56)
+brev16(17133933039273200696)
+brev16(19512)
+brev32(17133933039273200696)
+brev32(3677703224)
+brev64(17133933039273200696)
+brol8(17133933039273200696, 18354093072705654326)
+brol8(56, 18354093072705654326)
+brol8(17133933039273200696, 54)
+brol8(56, 54)
+brol16(17133933039273200696, 18354093072705654326)
+brol16(19512, 18354093072705654326)
+brol16(17133933039273200696, 3638)
+brol16(19512, 3638)
+brol32(17133933039273200696, 18354093072705654326)
+brol32(3677703224, 18354093072705654326)
+brol32(17133933039273200696, 3440643638)
+brol32(3677703224, 3440643638)
+brol64(17133933039273200696, 18354093072705654326)
+bror8(17133933039273200696, 18354093072705654326)
+bror8(56, 18354093072705654326)
+bror8(17133933039273200696, 54)
+bror8(56, 54)
+bror16(17133933039273200696, 18354093072705654326)
+bror16(19512, 18354093072705654326)
+bror16(17133933039273200696, 3638)
+bror16(19512, 3638)
+bror32(17133933039273200696, 18354093072705654326)
+bror32(3677703224, 18354093072705654326)
+bror32(17133933039273200696, 3440643638)
+bror32(3677703224, 3440643638)
+bror64(17133933039273200696, 18354093072705654326)
+bmod8(17133933039273200696)
+bmod8(56)
+bmod16(17133933039273200696)
+bmod16(19512)
+bmod32(17133933039273200696)
+bmod32(3677703224)
+bmod64(17133933039273200696)
+band(2384001591844672901, 14826715856253798055)
+bor(2384001591844672901, 14826715856253798055)
+bxor(2384001591844672901, 14826715856253798055)
+bshl(433984901, 7)
+bshr(433984901, 7)
+bshl(363382439, 5)
+bshr(363382439, 5)
+bnot8(2384001591844672901)
+bnot8(133)
+bnot16(2384001591844672901)
+bnot16(5509)
+bnot32(2384001591844672901)
+bnot32(433984901)
+bnot64(2384001591844672901)
+brev8(2384001591844672901)
+brev8(133)
+brev16(2384001591844672901)
+brev16(5509)
+brev32(2384001591844672901)
+brev32(433984901)
+brev64(2384001591844672901)
+brol8(2384001591844672901, 14826715856253798055)
+brol8(133, 14826715856253798055)
+brol8(2384001591844672901, 167)
+brol8(133, 167)
+brol16(2384001591844672901, 14826715856253798055)
+brol16(5509, 14826715856253798055)
+brol16(2384001591844672901, 50855)
+brol16(5509, 50855)
+brol32(2384001591844672901, 14826715856253798055)
+brol32(433984901, 14826715856253798055)
+brol32(2384001591844672901, 363382439)
+brol32(433984901, 363382439)
+brol64(2384001591844672901, 14826715856253798055)
+bror8(2384001591844672901, 14826715856253798055)
+bror8(133, 14826715856253798055)
+bror8(2384001591844672901, 167)
+bror8(133, 167)
+bror16(2384001591844672901, 14826715856253798055)
+bror16(5509, 14826715856253798055)
+bror16(2384001591844672901, 50855)
+bror16(5509, 50855)
+bror32(2384001591844672901, 14826715856253798055)
+bror32(433984901, 14826715856253798055)
+bror32(2384001591844672901, 363382439)
+bror32(433984901, 363382439)
+bror64(2384001591844672901, 14826715856253798055)
+bmod8(2384001591844672901)
+bmod8(133)
+bmod16(2384001591844672901)
+bmod16(5509)
+bmod32(2384001591844672901)
+bmod32(433984901)
+bmod64(2384001591844672901)
+band(16863531943491491360, 13328030202801486755)
+bor(16863531943491491360, 13328030202801486755)
+bxor(16863531943491491360, 13328030202801486755)
+bshl(2923648544, 3)
+bshr(2923648544, 3)
+bshl(3249077155, 0)
+bshr(3249077155, 0)
+bnot8(16863531943491491360)
+bnot8(32)
+bnot16(16863531943491491360)
+bnot16(22048)
+bnot32(16863531943491491360)
+bnot32(2923648544)
+bnot64(16863531943491491360)
+brev8(16863531943491491360)
+brev8(32)
+brev16(16863531943491491360)
+brev16(22048)
+brev32(16863531943491491360)
+brev32(2923648544)
+brev64(16863531943491491360)
+brol8(16863531943491491360, 13328030202801486755)
+brol8(32, 13328030202801486755)
+brol8(16863531943491491360, 163)
+brol8(32, 163)
+brol16(16863531943491491360, 13328030202801486755)
+brol16(22048, 13328030202801486755)
+brol16(16863531943491491360, 64419)
+brol16(22048, 64419)
+brol32(16863531943491491360, 13328030202801486755)
+brol32(2923648544, 13328030202801486755)
+brol32(16863531943491491360, 3249077155)
+brol32(2923648544, 3249077155)
+brol64(16863531943491491360, 13328030202801486755)
+bror8(16863531943491491360, 13328030202801486755)
+bror8(32, 13328030202801486755)
+bror8(16863531943491491360, 163)
+bror8(32, 163)
+bror16(16863531943491491360, 13328030202801486755)
+bror16(22048, 13328030202801486755)
+bror16(16863531943491491360, 64419)
+bror16(22048, 64419)
+bror32(16863531943491491360, 13328030202801486755)
+bror32(2923648544, 13328030202801486755)
+bror32(16863531943491491360, 3249077155)
+bror32(2923648544, 3249077155)
+bror64(16863531943491491360, 13328030202801486755)
+bmod8(16863531943491491360)
+bmod8(32)
+bmod16(16863531943491491360)
+bmod16(22048)
+bmod32(16863531943491491360)
+bmod32(2923648544)
+bmod64(16863531943491491360)
+band(8698401535607757593, 15398820748105728968)
+bor(8698401535607757593, 15398820748105728968)
+bxor(8698401535607757593, 15398820748105728968)
+bshl(1268570905, 8)
+bshr(1268570905, 8)
+bshl(1254212552, 25)
+bshr(1254212552, 25)
+bnot8(8698401535607757593)
+bnot8(25)
+bnot16(8698401535607757593)
+bnot16(56089)
+bnot32(8698401535607757593)
+bnot32(1268570905)
+bnot64(8698401535607757593)
+brev8(8698401535607757593)
+brev8(25)
+brev16(8698401535607757593)
+brev16(56089)
+brev32(8698401535607757593)
+brev32(1268570905)
+brev64(8698401535607757593)
+brol8(8698401535607757593, 15398820748105728968)
+brol8(25, 15398820748105728968)
+brol8(8698401535607757593, 200)
+brol8(25, 200)
+brol16(8698401535607757593, 15398820748105728968)
+brol16(56089, 15398820748105728968)
+brol16(8698401535607757593, 50120)
+brol16(56089, 50120)
+brol32(8698401535607757593, 15398820748105728968)
+brol32(1268570905, 15398820748105728968)
+brol32(8698401535607757593, 1254212552)
+brol32(1268570905, 1254212552)
+brol64(8698401535607757593, 15398820748105728968)
+bror8(8698401535607757593, 15398820748105728968)
+bror8(25, 15398820748105728968)
+bror8(8698401535607757593, 200)
+bror8(25, 200)
+bror16(8698401535607757593, 15398820748105728968)
+bror16(56089, 15398820748105728968)
+bror16(8698401535607757593, 50120)
+bror16(56089, 50120)
+bror32(8698401535607757593, 15398820748105728968)
+bror32(1268570905, 15398820748105728968)
+bror32(8698401535607757593, 1254212552)
+bror32(1268570905, 1254212552)
+bror64(8698401535607757593, 15398820748105728968)
+bmod8(8698401535607757593)
+bmod8(25)
+bmod16(8698401535607757593)
+bmod16(56089)
+bmod32(8698401535607757593)
+bmod32(1268570905)
+bmod64(8698401535607757593)
+band(12646032387041020509, 1473170080201101839)
+bor(12646032387041020509, 1473170080201101839)
+bxor(12646032387041020509, 1473170080201101839)
+bshl(1470777949, 15)
+bshr(1470777949, 15)
+bshl(4229878287, 29)
+bshr(4229878287, 29)
+bnot8(12646032387041020509)
+bnot8(93)
+bnot16(12646032387041020509)
+bnot16(19037)
+bnot32(12646032387041020509)
+bnot32(1470777949)
+bnot64(12646032387041020509)
+brev8(12646032387041020509)
+brev8(93)
+brev16(12646032387041020509)
+brev16(19037)
+brev32(12646032387041020509)
+brev32(1470777949)
+brev64(12646032387041020509)
+brol8(12646032387041020509, 1473170080201101839)
+brol8(93, 1473170080201101839)
+brol8(12646032387041020509, 15)
+brol8(93, 15)
+brol16(12646032387041020509, 1473170080201101839)
+brol16(19037, 1473170080201101839)
+brol16(12646032387041020509, 53775)
+brol16(19037, 53775)
+brol32(12646032387041020509, 1473170080201101839)
+brol32(1470777949, 1473170080201101839)
+brol32(12646032387041020509, 4229878287)
+brol32(1470777949, 4229878287)
+brol64(12646032387041020509, 1473170080201101839)
+bror8(12646032387041020509, 1473170080201101839)
+bror8(93, 1473170080201101839)
+bror8(12646032387041020509, 15)
+bror8(93, 15)
+bror16(12646032387041020509, 1473170080201101839)
+bror16(19037, 1473170080201101839)
+bror16(12646032387041020509, 53775)
+bror16(19037, 53775)
+bror32(12646032387041020509, 1473170080201101839)
+bror32(1470777949, 1473170080201101839)
+bror32(12646032387041020509, 4229878287)
+bror32(1470777949, 4229878287)
+bror64(12646032387041020509, 1473170080201101839)
+bmod8(12646032387041020509)
+bmod8(93)
+bmod16(12646032387041020509)
+bmod16(19037)
+bmod32(12646032387041020509)
+bmod32(1470777949)
+bmod64(12646032387041020509)
+band(14507858657561773354, 1448717084254114359)
+bor(14507858657561773354, 1448717084254114359)
+bxor(14507858657561773354, 1448717084254114359)
+bshl(1200325930, 23)
+bshr(1200325930, 23)
+bshl(855740983, 10)
+bshr(855740983, 10)
+bnot8(14507858657561773354)
+bnot8(42)
+bnot16(14507858657561773354)
+bnot16(34090)
+bnot32(14507858657561773354)
+bnot32(1200325930)
+bnot64(14507858657561773354)
+brev8(14507858657561773354)
+brev8(42)
+brev16(14507858657561773354)
+brev16(34090)
+brev32(14507858657561773354)
+brev32(1200325930)
+brev64(14507858657561773354)
+brol8(14507858657561773354, 1448717084254114359)
+brol8(42, 1448717084254114359)
+brol8(14507858657561773354, 55)
+brol8(42, 55)
+brol16(14507858657561773354, 1448717084254114359)
+brol16(34090, 1448717084254114359)
+brol16(14507858657561773354, 37431)
+brol16(34090, 37431)
+brol32(14507858657561773354, 1448717084254114359)
+brol32(1200325930, 1448717084254114359)
+brol32(14507858657561773354, 855740983)
+brol32(1200325930, 855740983)
+brol64(14507858657561773354, 1448717084254114359)
+bror8(14507858657561773354, 1448717084254114359)
+bror8(42, 1448717084254114359)
+bror8(14507858657561773354, 55)
+bror8(42, 55)
+bror16(14507858657561773354, 1448717084254114359)
+bror16(34090, 1448717084254114359)
+bror16(14507858657561773354, 37431)
+bror16(34090, 37431)
+bror32(14507858657561773354, 1448717084254114359)
+bror32(1200325930, 1448717084254114359)
+bror32(14507858657561773354, 855740983)
+bror32(1200325930, 855740983)
+bror64(14507858657561773354, 1448717084254114359)
+bmod8(14507858657561773354)
+bmod8(42)
+bmod16(14507858657561773354)
+bmod16(34090)
+bmod32(14507858657561773354)
+bmod32(1200325930)
+bmod64(14507858657561773354)
+band(9338170161174399402, 5871583126889167076)
+bor(9338170161174399402, 5871583126889167076)
+bxor(9338170161174399402, 5871583126889167076)
+bshl(754174378, 4)
+bshr(754174378, 4)
+bshl(3009935588, 10)
+bshr(3009935588, 10)
+bnot8(9338170161174399402)
+bnot8(170)
+bnot16(9338170161174399402)
+bnot16(51626)
+bnot32(9338170161174399402)
+bnot32(754174378)
+bnot64(9338170161174399402)
+brev8(9338170161174399402)
+brev8(170)
+brev16(9338170161174399402)
+brev16(51626)
+brev32(9338170161174399402)
+brev32(754174378)
+brev64(9338170161174399402)
+brol8(9338170161174399402, 5871583126889167076)
+brol8(170, 5871583126889167076)
+brol8(9338170161174399402, 228)
+brol8(170, 228)
+brol16(9338170161174399402, 5871583126889167076)
+brol16(51626, 5871583126889167076)
+brol16(9338170161174399402, 63716)
+brol16(51626, 63716)
+brol32(9338170161174399402, 5871583126889167076)
+brol32(754174378, 5871583126889167076)
+brol32(9338170161174399402, 3009935588)
+brol32(754174378, 3009935588)
+brol64(9338170161174399402, 5871583126889167076)
+bror8(9338170161174399402, 5871583126889167076)
+bror8(170, 5871583126889167076)
+bror8(9338170161174399402, 228)
+bror8(170, 228)
+bror16(9338170161174399402, 5871583126889167076)
+bror16(51626, 5871583126889167076)
+bror16(9338170161174399402, 63716)
+bror16(51626, 63716)
+bror32(9338170161174399402, 5871583126889167076)
+bror32(754174378, 5871583126889167076)
+bror32(9338170161174399402, 3009935588)
+bror32(754174378, 3009935588)
+bror64(9338170161174399402, 5871583126889167076)
+bmod8(9338170161174399402)
+bmod8(170)
+bmod16(9338170161174399402)
+bmod16(51626)
+bmod32(9338170161174399402)
+bmod32(754174378)
+bmod64(9338170161174399402)
+band(2453880646200884732, 16136849305783275860)
+bor(2453880646200884732, 16136849305783275860)
+bxor(2453880646200884732, 16136849305783275860)
+bshl(1308786172, 20)
+bshr(1308786172, 20)
+bshl(1765314900, 28)
+bshr(1765314900, 28)
+bnot8(2453880646200884732)
+bnot8(252)
+bnot16(2453880646200884732)
+bnot16(32252)
+bnot32(2453880646200884732)
+bnot32(1308786172)
+bnot64(2453880646200884732)
+brev8(2453880646200884732)
+brev8(252)
+brev16(2453880646200884732)
+brev16(32252)
+brev32(2453880646200884732)
+brev32(1308786172)
+brev64(2453880646200884732)
+brol8(2453880646200884732, 16136849305783275860)
+brol8(252, 16136849305783275860)
+brol8(2453880646200884732, 84)
+brol8(252, 84)
+brol16(2453880646200884732, 16136849305783275860)
+brol16(32252, 16136849305783275860)
+brol16(2453880646200884732, 37204)
+brol16(32252, 37204)
+brol32(2453880646200884732, 16136849305783275860)
+brol32(1308786172, 16136849305783275860)
+brol32(2453880646200884732, 1765314900)
+brol32(1308786172, 1765314900)
+brol64(2453880646200884732, 16136849305783275860)
+bror8(2453880646200884732, 16136849305783275860)
+bror8(252, 16136849305783275860)
+bror8(2453880646200884732, 84)
+bror8(252, 84)
+bror16(2453880646200884732, 16136849305783275860)
+bror16(32252, 16136849305783275860)
+bror16(2453880646200884732, 37204)
+bror16(32252, 37204)
+bror32(2453880646200884732, 16136849305783275860)
+bror32(1308786172, 16136849305783275860)
+bror32(2453880646200884732, 1765314900)
+bror32(1308786172, 1765314900)
+bror64(2453880646200884732, 16136849305783275860)
+bmod8(2453880646200884732)
+bmod8(252)
+bmod16(2453880646200884732)
+bmod16(32252)
+bmod32(2453880646200884732)
+bmod32(1308786172)
+bmod64(2453880646200884732)
+band(1664361942690602714, 15497527681310922308)
+bor(1664361942690602714, 15497527681310922308)
+bxor(1664361942690602714, 15497527681310922308)
+bshl(1673567962, 4)
+bshr(1673567962, 4)
+bshl(357701188, 26)
+bshr(357701188, 26)
+bnot8(1664361942690602714)
+bnot8(218)
+bnot16(1664361942690602714)
+bnot16(40666)
+bnot32(1664361942690602714)
+bnot32(1673567962)
+bnot64(1664361942690602714)
+brev8(1664361942690602714)
+brev8(218)
+brev16(1664361942690602714)
+brev16(40666)
+brev32(1664361942690602714)
+brev32(1673567962)
+brev64(1664361942690602714)
+brol8(1664361942690602714, 15497527681310922308)
+brol8(218, 15497527681310922308)
+brol8(1664361942690602714, 68)
+brol8(218, 68)
+brol16(1664361942690602714, 15497527681310922308)
+brol16(40666, 15497527681310922308)
+brol16(1664361942690602714, 5700)
+brol16(40666, 5700)
+brol32(1664361942690602714, 15497527681310922308)
+brol32(1673567962, 15497527681310922308)
+brol32(1664361942690602714, 357701188)
+brol32(1673567962, 357701188)
+brol64(1664361942690602714, 15497527681310922308)
+bror8(1664361942690602714, 15497527681310922308)
+bror8(218, 15497527681310922308)
+bror8(1664361942690602714, 68)
+bror8(218, 68)
+bror16(1664361942690602714, 15497527681310922308)
+bror16(40666, 15497527681310922308)
+bror16(1664361942690602714, 5700)
+bror16(40666, 5700)
+bror32(1664361942690602714, 15497527681310922308)
+bror32(1673567962, 15497527681310922308)
+bror32(1664361942690602714, 357701188)
+bror32(1673567962, 357701188)
+bror64(1664361942690602714, 15497527681310922308)
+bmod8(1664361942690602714)
+bmod8(218)
+bmod16(1664361942690602714)
+bmod16(40666)
+bmod32(1664361942690602714)
+bmod32(1673567962)
+bmod64(1664361942690602714)
+band(7069231932291834844, 1960419139404322592)
+bor(7069231932291834844, 1960419139404322592)
+bxor(7069231932291834844, 1960419139404322592)
+bshl(4011484124, 0)
+bshr(4011484124, 0)
+bshl(252860192, 28)
+bshr(252860192, 28)
+bnot8(7069231932291834844)
+bnot8(220)
+bnot16(7069231932291834844)
+bnot16(25564)
+bnot32(7069231932291834844)
+bnot32(4011484124)
+bnot64(7069231932291834844)
+brev8(7069231932291834844)
+brev8(220)
+brev16(7069231932291834844)
+brev16(25564)
+brev32(7069231932291834844)
+brev32(4011484124)
+brev64(7069231932291834844)
+brol8(7069231932291834844, 1960419139404322592)
+brol8(220, 1960419139404322592)
+brol8(7069231932291834844, 32)
+brol8(220, 32)
+brol16(7069231932291834844, 1960419139404322592)
+brol16(25564, 1960419139404322592)
+brol16(7069231932291834844, 22304)
+brol16(25564, 22304)
+brol32(7069231932291834844, 1960419139404322592)
+brol32(4011484124, 1960419139404322592)
+brol32(7069231932291834844, 252860192)
+brol32(4011484124, 252860192)
+brol64(7069231932291834844, 1960419139404322592)
+bror8(7069231932291834844, 1960419139404322592)
+bror8(220, 1960419139404322592)
+bror8(7069231932291834844, 32)
+bror8(220, 32)
+bror16(7069231932291834844, 1960419139404322592)
+bror16(25564, 1960419139404322592)
+bror16(7069231932291834844, 22304)
+bror16(25564, 22304)
+bror32(7069231932291834844, 1960419139404322592)
+bror32(4011484124, 1960419139404322592)
+bror32(7069231932291834844, 252860192)
+bror32(4011484124, 252860192)
+bror64(7069231932291834844, 1960419139404322592)
+bmod8(7069231932291834844)
+bmod8(220)
+bmod16(7069231932291834844)
+bmod16(25564)
+bmod32(7069231932291834844)
+bmod32(4011484124)
+bmod64(7069231932291834844)
+band(7894939847814477761, 15859523660019189959)
+bor(7894939847814477761, 15859523660019189959)
+bxor(7894939847814477761, 15859523660019189959)
+bshl(1611593665, 7)
+bshr(1611593665, 7)
+bshl(3461925063, 1)
+bshr(3461925063, 1)
+bnot8(7894939847814477761)
+bnot8(193)
+bnot16(7894939847814477761)
+bnot16(63425)
+bnot32(7894939847814477761)
+bnot32(1611593665)
+bnot64(7894939847814477761)
+brev8(7894939847814477761)
+brev8(193)
+brev16(7894939847814477761)
+brev16(63425)
+brev32(7894939847814477761)
+brev32(1611593665)
+brev64(7894939847814477761)
+brol8(7894939847814477761, 15859523660019189959)
+brol8(193, 15859523660019189959)
+brol8(7894939847814477761, 199)
+brol8(193, 199)
+brol16(7894939847814477761, 15859523660019189959)
+brol16(63425, 15859523660019189959)
+brol16(7894939847814477761, 51399)
+brol16(63425, 51399)
+brol32(7894939847814477761, 15859523660019189959)
+brol32(1611593665, 15859523660019189959)
+brol32(7894939847814477761, 3461925063)
+brol32(1611593665, 3461925063)
+brol64(7894939847814477761, 15859523660019189959)
+bror8(7894939847814477761, 15859523660019189959)
+bror8(193, 15859523660019189959)
+bror8(7894939847814477761, 199)
+bror8(193, 199)
+bror16(7894939847814477761, 15859523660019189959)
+bror16(63425, 15859523660019189959)
+bror16(7894939847814477761, 51399)
+bror16(63425, 51399)
+bror32(7894939847814477761, 15859523660019189959)
+bror32(1611593665, 15859523660019189959)
+bror32(7894939847814477761, 3461925063)
+bror32(1611593665, 3461925063)
+bror64(7894939847814477761, 15859523660019189959)
+bmod8(7894939847814477761)
+bmod8(193)
+bmod16(7894939847814477761)
+bmod16(63425)
+bmod32(7894939847814477761)
+bmod32(1611593665)
+bmod64(7894939847814477761)
+band(5540076040277801861, 12069143915428734021)
+bor(5540076040277801861, 12069143915428734021)
+bxor(5540076040277801861, 12069143915428734021)
+bshl(1500068741, 5)
+bshr(1500068741, 5)
+bshl(775054405, 5)
+bshr(775054405, 5)
+bnot8(5540076040277801861)
+bnot8(133)
+bnot16(5540076040277801861)
+bnot16(15237)
+bnot32(5540076040277801861)
+bnot32(1500068741)
+bnot64(5540076040277801861)
+brev8(5540076040277801861)
+brev8(133)
+brev16(5540076040277801861)
+brev16(15237)
+brev32(5540076040277801861)
+brev32(1500068741)
+brev64(5540076040277801861)
+brol8(5540076040277801861, 12069143915428734021)
+brol8(133, 12069143915428734021)
+brol8(5540076040277801861, 69)
+brol8(133, 69)
+brol16(5540076040277801861, 12069143915428734021)
+brol16(15237, 12069143915428734021)
+brol16(5540076040277801861, 25669)
+brol16(15237, 25669)
+brol32(5540076040277801861, 12069143915428734021)
+brol32(1500068741, 12069143915428734021)
+brol32(5540076040277801861, 775054405)
+brol32(1500068741, 775054405)
+brol64(5540076040277801861, 12069143915428734021)
+bror8(5540076040277801861, 12069143915428734021)
+bror8(133, 12069143915428734021)
+bror8(5540076040277801861, 69)
+bror8(133, 69)
+bror16(5540076040277801861, 12069143915428734021)
+bror16(15237, 12069143915428734021)
+bror16(5540076040277801861, 25669)
+bror16(15237, 25669)
+bror32(5540076040277801861, 12069143915428734021)
+bror32(1500068741, 12069143915428734021)
+bror32(5540076040277801861, 775054405)
+bror32(1500068741, 775054405)
+bror64(5540076040277801861, 12069143915428734021)
+bmod8(5540076040277801861)
+bmod8(133)
+bmod16(5540076040277801861)
+bmod16(15237)
+bmod32(5540076040277801861)
+bmod32(1500068741)
+bmod64(5540076040277801861)
+band(297688763580905205, 3678664453785526729)
+bor(297688763580905205, 3678664453785526729)
+bxor(297688763580905205, 3678664453785526729)
+bshl(1860007669, 9)
+bshr(1860007669, 9)
+bshl(2411602377, 21)
+bshr(2411602377, 21)
+bnot8(297688763580905205)
+bnot8(245)
+bnot16(297688763580905205)
+bnot16(30453)
+bnot32(297688763580905205)
+bnot32(1860007669)
+bnot64(297688763580905205)
+brev8(297688763580905205)
+brev8(245)
+brev16(297688763580905205)
+brev16(30453)
+brev32(297688763580905205)
+brev32(1860007669)
+brev64(297688763580905205)
+brol8(297688763580905205, 3678664453785526729)
+brol8(245, 3678664453785526729)
+brol8(297688763580905205, 201)
+brol8(245, 201)
+brol16(297688763580905205, 3678664453785526729)
+brol16(30453, 3678664453785526729)
+brol16(297688763580905205, 8649)
+brol16(30453, 8649)
+brol32(297688763580905205, 3678664453785526729)
+brol32(1860007669, 3678664453785526729)
+brol32(297688763580905205, 2411602377)
+brol32(1860007669, 2411602377)
+brol64(297688763580905205, 3678664453785526729)
+bror8(297688763580905205, 3678664453785526729)
+bror8(245, 3678664453785526729)
+bror8(297688763580905205, 201)
+bror8(245, 201)
+bror16(297688763580905205, 3678664453785526729)
+bror16(30453, 3678664453785526729)
+bror16(297688763580905205, 8649)
+bror16(30453, 8649)
+bror32(297688763580905205, 3678664453785526729)
+bror32(1860007669, 3678664453785526729)
+bror32(297688763580905205, 2411602377)
+bror32(1860007669, 2411602377)
+bror64(297688763580905205, 3678664453785526729)
+bmod8(297688763580905205)
+bmod8(245)
+bmod16(297688763580905205)
+bmod16(30453)
+bmod32(297688763580905205)
+bmod32(1860007669)
+bmod64(297688763580905205)
+band(13014262039042167013, 7821020689542590350)
+bor(13014262039042167013, 7821020689542590350)
+bxor(13014262039042167013, 7821020689542590350)
+bshl(989171941, 14)
+bshr(989171941, 14)
+bshl(757772174, 5)
+bshr(757772174, 5)
+bnot8(13014262039042167013)
+bnot8(229)
+bnot16(13014262039042167013)
+bnot16(37093)
+bnot32(13014262039042167013)
+bnot32(989171941)
+bnot64(13014262039042167013)
+brev8(13014262039042167013)
+brev8(229)
+brev16(13014262039042167013)
+brev16(37093)
+brev32(13014262039042167013)
+brev32(989171941)
+brev64(13014262039042167013)
+brol8(13014262039042167013, 7821020689542590350)
+brol8(229, 7821020689542590350)
+brol8(13014262039042167013, 142)
+brol8(229, 142)
+brol16(13014262039042167013, 7821020689542590350)
+brol16(37093, 7821020689542590350)
+brol16(13014262039042167013, 44942)
+brol16(37093, 44942)
+brol32(13014262039042167013, 7821020689542590350)
+brol32(989171941, 7821020689542590350)
+brol32(13014262039042167013, 757772174)
+brol32(989171941, 757772174)
+brol64(13014262039042167013, 7821020689542590350)
+bror8(13014262039042167013, 7821020689542590350)
+bror8(229, 7821020689542590350)
+bror8(13014262039042167013, 142)
+bror8(229, 142)
+bror16(13014262039042167013, 7821020689542590350)
+bror16(37093, 7821020689542590350)
+bror16(13014262039042167013, 44942)
+bror16(37093, 44942)
+bror32(13014262039042167013, 7821020689542590350)
+bror32(989171941, 7821020689542590350)
+bror32(13014262039042167013, 757772174)
+bror32(989171941, 757772174)
+bror64(13014262039042167013, 7821020689542590350)
+bmod8(13014262039042167013)
+bmod8(229)
+bmod16(13014262039042167013)
+bmod16(37093)
+bmod32(13014262039042167013)
+bmod32(989171941)
+bmod64(13014262039042167013)
+band(16204362317104377535, 8696581347780206062)
+bor(16204362317104377535, 8696581347780206062)
+bxor(16204362317104377535, 8696581347780206062)
+bshl(1253797567, 14)
+bshr(1253797567, 14)
+bshl(3401194990, 31)
+bshr(3401194990, 31)
+bnot8(16204362317104377535)
+bnot8(191)
+bnot16(16204362317104377535)
+bnot16(28351)
+bnot32(16204362317104377535)
+bnot32(1253797567)
+bnot64(16204362317104377535)
+brev8(16204362317104377535)
+brev8(191)
+brev16(16204362317104377535)
+brev16(28351)
+brev32(16204362317104377535)
+brev32(1253797567)
+brev64(16204362317104377535)
+brol8(16204362317104377535, 8696581347780206062)
+brol8(191, 8696581347780206062)
+brol8(16204362317104377535, 238)
+brol8(191, 238)
+brol16(16204362317104377535, 8696581347780206062)
+brol16(28351, 8696581347780206062)
+brol16(16204362317104377535, 7662)
+brol16(28351, 7662)
+brol32(16204362317104377535, 8696581347780206062)
+brol32(1253797567, 8696581347780206062)
+brol32(16204362317104377535, 3401194990)
+brol32(1253797567, 3401194990)
+brol64(16204362317104377535, 8696581347780206062)
+bror8(16204362317104377535, 8696581347780206062)
+bror8(191, 8696581347780206062)
+bror8(16204362317104377535, 238)
+bror8(191, 238)
+bror16(16204362317104377535, 8696581347780206062)
+bror16(28351, 8696581347780206062)
+bror16(16204362317104377535, 7662)
+bror16(28351, 7662)
+bror32(16204362317104377535, 8696581347780206062)
+bror32(1253797567, 8696581347780206062)
+bror32(16204362317104377535, 3401194990)
+bror32(1253797567, 3401194990)
+bror64(16204362317104377535, 8696581347780206062)
+bmod8(16204362317104377535)
+bmod8(191)
+bmod16(16204362317104377535)
+bmod16(28351)
+bmod32(16204362317104377535)
+bmod32(1253797567)
+bmod64(16204362317104377535)
+band(8549412411146251181, 10065120969868479613)
+bor(8549412411146251181, 10065120969868479613)
+bxor(8549412411146251181, 10065120969868479613)
+bshl(2360355757, 29)
+bshr(2360355757, 29)
+bshl(3730345085, 13)
+bshr(3730345085, 13)
+bnot8(8549412411146251181)
+bnot8(173)
+bnot16(8549412411146251181)
+bnot16(11181)
+bnot32(8549412411146251181)
+bnot32(2360355757)
+bnot64(8549412411146251181)
+brev8(8549412411146251181)
+brev8(173)
+brev16(8549412411146251181)
+brev16(11181)
+brev32(8549412411146251181)
+brev32(2360355757)
+brev64(8549412411146251181)
+brol8(8549412411146251181, 10065120969868479613)
+brol8(173, 10065120969868479613)
+brol8(8549412411146251181, 125)
+brol8(173, 125)
+brol16(8549412411146251181, 10065120969868479613)
+brol16(11181, 10065120969868479613)
+brol16(8549412411146251181, 35965)
+brol16(11181, 35965)
+brol32(8549412411146251181, 10065120969868479613)
+brol32(2360355757, 10065120969868479613)
+brol32(8549412411146251181, 3730345085)
+brol32(2360355757, 3730345085)
+brol64(8549412411146251181, 10065120969868479613)
+bror8(8549412411146251181, 10065120969868479613)
+bror8(173, 10065120969868479613)
+bror8(8549412411146251181, 125)
+bror8(173, 125)
+bror16(8549412411146251181, 10065120969868479613)
+bror16(11181, 10065120969868479613)
+bror16(8549412411146251181, 35965)
+bror16(11181, 35965)
+bror32(8549412411146251181, 10065120969868479613)
+bror32(2360355757, 10065120969868479613)
+bror32(8549412411146251181, 3730345085)
+bror32(2360355757, 3730345085)
+bror64(8549412411146251181, 10065120969868479613)
+bmod8(8549412411146251181)
+bmod8(173)
+bmod16(8549412411146251181)
+bmod16(11181)
+bmod32(8549412411146251181)
+bmod32(2360355757)
+bmod64(8549412411146251181)
+band(5573024648100731809, 13510610806574443099)
+bor(5573024648100731809, 13510610806574443099)
+bxor(5573024648100731809, 13510610806574443099)
+bshl(3934935969, 27)
+bshr(3934935969, 27)
+bshl(1080846939, 1)
+bshr(1080846939, 1)
+bnot8(5573024648100731809)
+bnot8(161)
+bnot16(5573024648100731809)
+bnot16(23457)
+bnot32(5573024648100731809)
+bnot32(3934935969)
+bnot64(5573024648100731809)
+brev8(5573024648100731809)
+brev8(161)
+brev16(5573024648100731809)
+brev16(23457)
+brev32(5573024648100731809)
+brev32(3934935969)
+brev64(5573024648100731809)
+brol8(5573024648100731809, 13510610806574443099)
+brol8(161, 13510610806574443099)
+brol8(5573024648100731809, 91)
+brol8(161, 91)
+brol16(5573024648100731809, 13510610806574443099)
+brol16(23457, 13510610806574443099)
+brol16(5573024648100731809, 27227)
+brol16(23457, 27227)
+brol32(5573024648100731809, 13510610806574443099)
+brol32(3934935969, 13510610806574443099)
+brol32(5573024648100731809, 1080846939)
+brol32(3934935969, 1080846939)
+brol64(5573024648100731809, 13510610806574443099)
+bror8(5573024648100731809, 13510610806574443099)
+bror8(161, 13510610806574443099)
+bror8(5573024648100731809, 91)
+bror8(161, 91)
+bror16(5573024648100731809, 13510610806574443099)
+bror16(23457, 13510610806574443099)
+bror16(5573024648100731809, 27227)
+bror16(23457, 27227)
+bror32(5573024648100731809, 13510610806574443099)
+bror32(3934935969, 13510610806574443099)
+bror32(5573024648100731809, 1080846939)
+bror32(3934935969, 1080846939)
+bror64(5573024648100731809, 13510610806574443099)
+bmod8(5573024648100731809)
+bmod8(161)
+bmod16(5573024648100731809)
+bmod16(23457)
+bmod32(5573024648100731809)
+bmod32(3934935969)
+bmod64(5573024648100731809)
+band(3492022004345055198, 11446712752185565564)
+bor(3492022004345055198, 11446712752185565564)
+bxor(3492022004345055198, 11446712752185565564)
+bshl(3973425118, 28)
+bshr(3973425118, 28)
+bshl(3488899452, 30)
+bshr(3488899452, 30)
+bnot8(3492022004345055198)
+bnot8(222)
+bnot16(3492022004345055198)
+bnot16(42974)
+bnot32(3492022004345055198)
+bnot32(3973425118)
+bnot64(3492022004345055198)
+brev8(3492022004345055198)
+brev8(222)
+brev16(3492022004345055198)
+brev16(42974)
+brev32(3492022004345055198)
+brev32(3973425118)
+brev64(3492022004345055198)
+brol8(3492022004345055198, 11446712752185565564)
+brol8(222, 11446712752185565564)
+brol8(3492022004345055198, 124)
+brol8(222, 124)
+brol16(3492022004345055198, 11446712752185565564)
+brol16(42974, 11446712752185565564)
+brol16(3492022004345055198, 24956)
+brol16(42974, 24956)
+brol32(3492022004345055198, 11446712752185565564)
+brol32(3973425118, 11446712752185565564)
+brol32(3492022004345055198, 3488899452)
+brol32(3973425118, 3488899452)
+brol64(3492022004345055198, 11446712752185565564)
+bror8(3492022004345055198, 11446712752185565564)
+bror8(222, 11446712752185565564)
+bror8(3492022004345055198, 124)
+bror8(222, 124)
+bror16(3492022004345055198, 11446712752185565564)
+bror16(42974, 11446712752185565564)
+bror16(3492022004345055198, 24956)
+bror16(42974, 24956)
+bror32(3492022004345055198, 11446712752185565564)
+bror32(3973425118, 11446712752185565564)
+bror32(3492022004345055198, 3488899452)
+bror32(3973425118, 3488899452)
+bror64(3492022004345055198, 11446712752185565564)
+bmod8(3492022004345055198)
+bmod8(222)
+bmod16(3492022004345055198)
+bmod16(42974)
+bmod32(3492022004345055198)
+bmod32(3973425118)
+bmod64(3492022004345055198)
+band(6050030753771452666, 5098038141709207128)
+bor(6050030753771452666, 5098038141709207128)
+bxor(6050030753771452666, 5098038141709207128)
+bshl(2260498682, 24)
+bshr(2260498682, 24)
+bshl(3891807832, 26)
+bshr(3891807832, 26)
+bnot8(6050030753771452666)
+bnot8(250)
+bnot16(6050030753771452666)
+bnot16(30970)
+bnot32(6050030753771452666)
+bnot32(2260498682)
+bnot64(6050030753771452666)
+brev8(6050030753771452666)
+brev8(250)
+brev16(6050030753771452666)
+brev16(30970)
+brev32(6050030753771452666)
+brev32(2260498682)
+brev64(6050030753771452666)
+brol8(6050030753771452666, 5098038141709207128)
+brol8(250, 5098038141709207128)
+brol8(6050030753771452666, 88)
+brol8(250, 88)
+brol16(6050030753771452666, 5098038141709207128)
+brol16(30970, 5098038141709207128)
+brol16(6050030753771452666, 18008)
+brol16(30970, 18008)
+brol32(6050030753771452666, 5098038141709207128)
+brol32(2260498682, 5098038141709207128)
+brol32(6050030753771452666, 3891807832)
+brol32(2260498682, 3891807832)
+brol64(6050030753771452666, 5098038141709207128)
+bror8(6050030753771452666, 5098038141709207128)
+bror8(250, 5098038141709207128)
+bror8(6050030753771452666, 88)
+bror8(250, 88)
+bror16(6050030753771452666, 5098038141709207128)
+bror16(30970, 5098038141709207128)
+bror16(6050030753771452666, 18008)
+bror16(30970, 18008)
+bror32(6050030753771452666, 5098038141709207128)
+bror32(2260498682, 5098038141709207128)
+bror32(6050030753771452666, 3891807832)
+bror32(2260498682, 3891807832)
+bror64(6050030753771452666, 5098038141709207128)
+bmod8(6050030753771452666)
+bmod8(250)
+bmod16(6050030753771452666)
+bmod16(30970)
+bmod32(6050030753771452666)
+bmod32(2260498682)
+bmod64(6050030753771452666)
+band(15644200087514301261, 14485433206777196415)
+bor(15644200087514301261, 14485433206777196415)
+bxor(15644200087514301261, 14485433206777196415)
+bshl(3547120461, 31)
+bshr(3547120461, 31)
+bshl(597307263, 13)
+bshr(597307263, 13)
+bnot8(15644200087514301261)
+bnot8(77)
+bnot16(15644200087514301261)
+bnot16(49997)
+bnot32(15644200087514301261)
+bnot32(3547120461)
+bnot64(15644200087514301261)
+brev8(15644200087514301261)
+brev8(77)
+brev16(15644200087514301261)
+brev16(49997)
+brev32(15644200087514301261)
+brev32(3547120461)
+brev64(15644200087514301261)
+brol8(15644200087514301261, 14485433206777196415)
+brol8(77, 14485433206777196415)
+brol8(15644200087514301261, 127)
+brol8(77, 127)
+brol16(15644200087514301261, 14485433206777196415)
+brol16(49997, 14485433206777196415)
+brol16(15644200087514301261, 12159)
+brol16(49997, 12159)
+brol32(15644200087514301261, 14485433206777196415)
+brol32(3547120461, 14485433206777196415)
+brol32(15644200087514301261, 597307263)
+brol32(3547120461, 597307263)
+brol64(15644200087514301261, 14485433206777196415)
+bror8(15644200087514301261, 14485433206777196415)
+bror8(77, 14485433206777196415)
+bror8(15644200087514301261, 127)
+bror8(77, 127)
+bror16(15644200087514301261, 14485433206777196415)
+bror16(49997, 14485433206777196415)
+bror16(15644200087514301261, 12159)
+bror16(49997, 12159)
+bror32(15644200087514301261, 14485433206777196415)
+bror32(3547120461, 14485433206777196415)
+bror32(15644200087514301261, 597307263)
+bror32(3547120461, 597307263)
+bror64(15644200087514301261, 14485433206777196415)
+bmod8(15644200087514301261)
+bmod8(77)
+bmod16(15644200087514301261)
+bmod16(49997)
+bmod32(15644200087514301261)
+bmod32(3547120461)
+bmod64(15644200087514301261)
+band(2693744193160529780, 7666650766144753288)
+bor(2693744193160529780, 7666650766144753288)
+bxor(2693744193160529780, 7666650766144753288)
+bshl(1427818356, 8)
+bshr(1427818356, 8)
+bshl(2366164616, 20)
+bshr(2366164616, 20)
+bnot8(2693744193160529780)
+bnot8(116)
+bnot16(2693744193160529780)
+bnot16(51060)
+bnot32(2693744193160529780)
+bnot32(1427818356)
+bnot64(2693744193160529780)
+brev8(2693744193160529780)
+brev8(116)
+brev16(2693744193160529780)
+brev16(51060)
+brev32(2693744193160529780)
+brev32(1427818356)
+brev64(2693744193160529780)
+brol8(2693744193160529780, 7666650766144753288)
+brol8(116, 7666650766144753288)
+brol8(2693744193160529780, 136)
+brol8(116, 136)
+brol16(2693744193160529780, 7666650766144753288)
+brol16(51060, 7666650766144753288)
+brol16(2693744193160529780, 52872)
+brol16(51060, 52872)
+brol32(2693744193160529780, 7666650766144753288)
+brol32(1427818356, 7666650766144753288)
+brol32(2693744193160529780, 2366164616)
+brol32(1427818356, 2366164616)
+brol64(2693744193160529780, 7666650766144753288)
+bror8(2693744193160529780, 7666650766144753288)
+bror8(116, 7666650766144753288)
+bror8(2693744193160529780, 136)
+bror8(116, 136)
+bror16(2693744193160529780, 7666650766144753288)
+bror16(51060, 7666650766144753288)
+bror16(2693744193160529780, 52872)
+bror16(51060, 52872)
+bror32(2693744193160529780, 7666650766144753288)
+bror32(1427818356, 7666650766144753288)
+bror32(2693744193160529780, 2366164616)
+bror32(1427818356, 2366164616)
+bror64(2693744193160529780, 7666650766144753288)
+bmod8(2693744193160529780)
+bmod8(116)
+bmod16(2693744193160529780)
+bmod16(51060)
+bmod32(2693744193160529780)
+bmod32(1427818356)
+bmod64(2693744193160529780)
+band(14617328087047806475, 7770833596089243982)
+bor(14617328087047806475, 7770833596089243982)
+bxor(14617328087047806475, 7770833596089243982)
+bshl(30613003, 14)
+bshr(30613003, 14)
+bshl(3885111630, 11)
+bshr(3885111630, 11)
+bnot8(14617328087047806475)
+bnot8(11)
+bnot16(14617328087047806475)
+bnot16(7691)
+bnot32(14617328087047806475)
+bnot32(30613003)
+bnot64(14617328087047806475)
+brev8(14617328087047806475)
+brev8(11)
+brev16(14617328087047806475)
+brev16(7691)
+brev32(14617328087047806475)
+brev32(30613003)
+brev64(14617328087047806475)
+brol8(14617328087047806475, 7770833596089243982)
+brol8(11, 7770833596089243982)
+brol8(14617328087047806475, 78)
+brol8(11, 78)
+brol16(14617328087047806475, 7770833596089243982)
+brol16(7691, 7770833596089243982)
+brol16(14617328087047806475, 6478)
+brol16(7691, 6478)
+brol32(14617328087047806475, 7770833596089243982)
+brol32(30613003, 7770833596089243982)
+brol32(14617328087047806475, 3885111630)
+brol32(30613003, 3885111630)
+brol64(14617328087047806475, 7770833596089243982)
+bror8(14617328087047806475, 7770833596089243982)
+bror8(11, 7770833596089243982)
+bror8(14617328087047806475, 78)
+bror8(11, 78)
+bror16(14617328087047806475, 7770833596089243982)
+bror16(7691, 7770833596089243982)
+bror16(14617328087047806475, 6478)
+bror16(7691, 6478)
+bror32(14617328087047806475, 7770833596089243982)
+bror32(30613003, 7770833596089243982)
+bror32(14617328087047806475, 3885111630)
+bror32(30613003, 3885111630)
+bror64(14617328087047806475, 7770833596089243982)
+bmod8(14617328087047806475)
+bmod8(11)
+bmod16(14617328087047806475)
+bmod16(7691)
+bmod32(14617328087047806475)
+bmod32(30613003)
+bmod64(14617328087047806475)
+band(12057501540325336448, 12092428187581439212)
+bor(12057501540325336448, 12092428187581439212)
+bxor(12057501540325336448, 12092428187581439212)
+bshl(2110858624, 12)
+bshr(2110858624, 12)
+bshl(1085693164, 0)
+bshr(1085693164, 0)
+bnot8(12057501540325336448)
+bnot8(128)
+bnot16(12057501540325336448)
+bnot16(9600)
+bnot32(12057501540325336448)
+bnot32(2110858624)
+bnot64(12057501540325336448)
+brev8(12057501540325336448)
+brev8(128)
+brev16(12057501540325336448)
+brev16(9600)
+brev32(12057501540325336448)
+brev32(2110858624)
+brev64(12057501540325336448)
+brol8(12057501540325336448, 12092428187581439212)
+brol8(128, 12092428187581439212)
+brol8(12057501540325336448, 236)
+brol8(128, 236)
+brol16(12057501540325336448, 12092428187581439212)
+brol16(9600, 12092428187581439212)
+brol16(12057501540325336448, 23788)
+brol16(9600, 23788)
+brol32(12057501540325336448, 12092428187581439212)
+brol32(2110858624, 12092428187581439212)
+brol32(12057501540325336448, 1085693164)
+brol32(2110858624, 1085693164)
+brol64(12057501540325336448, 12092428187581439212)
+bror8(12057501540325336448, 12092428187581439212)
+bror8(128, 12092428187581439212)
+bror8(12057501540325336448, 236)
+bror8(128, 236)
+bror16(12057501540325336448, 12092428187581439212)
+bror16(9600, 12092428187581439212)
+bror16(12057501540325336448, 23788)
+bror16(9600, 23788)
+bror32(12057501540325336448, 12092428187581439212)
+bror32(2110858624, 12092428187581439212)
+bror32(12057501540325336448, 1085693164)
+bror32(2110858624, 1085693164)
+bror64(12057501540325336448, 12092428187581439212)
+bmod8(12057501540325336448)
+bmod8(128)
+bmod16(12057501540325336448)
+bmod16(9600)
+bmod32(12057501540325336448)
+bmod32(2110858624)
+bmod64(12057501540325336448)
+band(10705897999342116125, 9974169367752033883)
+bor(10705897999342116125, 9974169367752033883)
+bxor(10705897999342116125, 9974169367752033883)
+bshl(341450013, 27)
+bshr(341450013, 27)
+bshl(3463530075, 29)
+bshr(3463530075, 29)
+bnot8(10705897999342116125)
+bnot8(29)
+bnot16(10705897999342116125)
+bnot16(7453)
+bnot32(10705897999342116125)
+bnot32(341450013)
+bnot64(10705897999342116125)
+brev8(10705897999342116125)
+brev8(29)
+brev16(10705897999342116125)
+brev16(7453)
+brev32(10705897999342116125)
+brev32(341450013)
+brev64(10705897999342116125)
+brol8(10705897999342116125, 9974169367752033883)
+brol8(29, 9974169367752033883)
+brol8(10705897999342116125, 91)
+brol8(29, 91)
+brol16(10705897999342116125, 9974169367752033883)
+brol16(7453, 9974169367752033883)
+brol16(10705897999342116125, 18011)
+brol16(7453, 18011)
+brol32(10705897999342116125, 9974169367752033883)
+brol32(341450013, 9974169367752033883)
+brol32(10705897999342116125, 3463530075)
+brol32(341450013, 3463530075)
+brol64(10705897999342116125, 9974169367752033883)
+bror8(10705897999342116125, 9974169367752033883)
+bror8(29, 9974169367752033883)
+bror8(10705897999342116125, 91)
+bror8(29, 91)
+bror16(10705897999342116125, 9974169367752033883)
+bror16(7453, 9974169367752033883)
+bror16(10705897999342116125, 18011)
+bror16(7453, 18011)
+bror32(10705897999342116125, 9974169367752033883)
+bror32(341450013, 9974169367752033883)
+bror32(10705897999342116125, 3463530075)
+bror32(341450013, 3463530075)
+bror64(10705897999342116125, 9974169367752033883)
+bmod8(10705897999342116125)
+bmod8(29)
+bmod16(10705897999342116125)
+bmod16(7453)
+bmod32(10705897999342116125)
+bmod32(341450013)
+bmod64(10705897999342116125)
+band(3708754108241877138, 16558750771054102751)
+bor(3708754108241877138, 16558750771054102751)
+bxor(3708754108241877138, 16558750771054102751)
+bshl(755439762, 31)
+bshr(755439762, 31)
+bshl(552061151, 18)
+bshr(552061151, 18)
+bnot8(3708754108241877138)
+bnot8(146)
+bnot16(3708754108241877138)
+bnot16(6290)
+bnot32(3708754108241877138)
+bnot32(755439762)
+bnot64(3708754108241877138)
+brev8(3708754108241877138)
+brev8(146)
+brev16(3708754108241877138)
+brev16(6290)
+brev32(3708754108241877138)
+brev32(755439762)
+brev64(3708754108241877138)
+brol8(3708754108241877138, 16558750771054102751)
+brol8(146, 16558750771054102751)
+brol8(3708754108241877138, 223)
+brol8(146, 223)
+brol16(3708754108241877138, 16558750771054102751)
+brol16(6290, 16558750771054102751)
+brol16(3708754108241877138, 51423)
+brol16(6290, 51423)
+brol32(3708754108241877138, 16558750771054102751)
+brol32(755439762, 16558750771054102751)
+brol32(3708754108241877138, 552061151)
+brol32(755439762, 552061151)
+brol64(3708754108241877138, 16558750771054102751)
+bror8(3708754108241877138, 16558750771054102751)
+bror8(146, 16558750771054102751)
+bror8(3708754108241877138, 223)
+bror8(146, 223)
+bror16(3708754108241877138, 16558750771054102751)
+bror16(6290, 16558750771054102751)
+bror16(3708754108241877138, 51423)
+bror16(6290, 51423)
+bror32(3708754108241877138, 16558750771054102751)
+bror32(755439762, 16558750771054102751)
+bror32(3708754108241877138, 552061151)
+bror32(755439762, 552061151)
+bror64(3708754108241877138, 16558750771054102751)
+bmod8(3708754108241877138)
+bmod8(146)
+bmod16(3708754108241877138)
+bmod16(6290)
+bmod32(3708754108241877138)
+bmod32(755439762)
+bmod64(3708754108241877138)
+band(15629579542790190053, 11001744205379253724)
+bor(15629579542790190053, 11001744205379253724)
+bxor(15629579542790190053, 11001744205379253724)
+bshl(4239963109, 28)
+bshr(4239963109, 28)
+bshl(2807543260, 5)
+bshr(2807543260, 5)
+bnot8(15629579542790190053)
+bnot8(229)
+bnot16(15629579542790190053)
+bnot16(46053)
+bnot32(15629579542790190053)
+bnot32(4239963109)
+bnot64(15629579542790190053)
+brev8(15629579542790190053)
+brev8(229)
+brev16(15629579542790190053)
+brev16(46053)
+brev32(15629579542790190053)
+brev32(4239963109)
+brev64(15629579542790190053)
+brol8(15629579542790190053, 11001744205379253724)
+brol8(229, 11001744205379253724)
+brol8(15629579542790190053, 220)
+brol8(229, 220)
+brol16(15629579542790190053, 11001744205379253724)
+brol16(46053, 11001744205379253724)
+brol16(15629579542790190053, 46556)
+brol16(46053, 46556)
+brol32(15629579542790190053, 11001744205379253724)
+brol32(4239963109, 11001744205379253724)
+brol32(15629579542790190053, 2807543260)
+brol32(4239963109, 2807543260)
+brol64(15629579542790190053, 11001744205379253724)
+bror8(15629579542790190053, 11001744205379253724)
+bror8(229, 11001744205379253724)
+bror8(15629579542790190053, 220)
+bror8(229, 220)
+bror16(15629579542790190053, 11001744205379253724)
+bror16(46053, 11001744205379253724)
+bror16(15629579542790190053, 46556)
+bror16(46053, 46556)
+bror32(15629579542790190053, 11001744205379253724)
+bror32(4239963109, 11001744205379253724)
+bror32(15629579542790190053, 2807543260)
+bror32(4239963109, 2807543260)
+bror64(15629579542790190053, 11001744205379253724)
+bmod8(15629579542790190053)
+bmod8(229)
+bmod16(15629579542790190053)
+bmod16(46053)
+bmod32(15629579542790190053)
+bmod32(4239963109)
+bmod64(15629579542790190053)
+band(18364610049120454705, 5978101807400566745)
+bor(18364610049120454705, 5978101807400566745)
+bxor(18364610049120454705, 5978101807400566745)
+bshl(811911217, 25)
+bshr(811911217, 25)
+bshl(2772123609, 17)
+bshr(2772123609, 17)
+bnot8(18364610049120454705)
+bnot8(49)
+bnot16(18364610049120454705)
+bnot16(51249)
+bnot32(18364610049120454705)
+bnot32(811911217)
+bnot64(18364610049120454705)
+brev8(18364610049120454705)
+brev8(49)
+brev16(18364610049120454705)
+brev16(51249)
+brev32(18364610049120454705)
+brev32(811911217)
+brev64(18364610049120454705)
+brol8(18364610049120454705, 5978101807400566745)
+brol8(49, 5978101807400566745)
+brol8(18364610049120454705, 217)
+brol8(49, 217)
+brol16(18364610049120454705, 5978101807400566745)
+brol16(51249, 5978101807400566745)
+brol16(18364610049120454705, 16345)
+brol16(51249, 16345)
+brol32(18364610049120454705, 5978101807400566745)
+brol32(811911217, 5978101807400566745)
+brol32(18364610049120454705, 2772123609)
+brol32(811911217, 2772123609)
+brol64(18364610049120454705, 5978101807400566745)
+bror8(18364610049120454705, 5978101807400566745)
+bror8(49, 5978101807400566745)
+bror8(18364610049120454705, 217)
+bror8(49, 217)
+bror16(18364610049120454705, 5978101807400566745)
+bror16(51249, 5978101807400566745)
+bror16(18364610049120454705, 16345)
+bror16(51249, 16345)
+bror32(18364610049120454705, 5978101807400566745)
+bror32(811911217, 5978101807400566745)
+bror32(18364610049120454705, 2772123609)
+bror32(811911217, 2772123609)
+bror64(18364610049120454705, 5978101807400566745)
+bmod8(18364610049120454705)
+bmod8(49)
+bmod16(18364610049120454705)
+bmod16(51249)
+bmod32(18364610049120454705)
+bmod32(811911217)
+bmod64(18364610049120454705)
+band(7992089387369454553, 6026359350308095352)
+bor(7992089387369454553, 6026359350308095352)
+bxor(7992089387369454553, 6026359350308095352)
+bshl(861101017, 24)
+bshr(861101017, 24)
+bshl(1811400056, 25)
+bshr(1811400056, 25)
+bnot8(7992089387369454553)
+bnot8(217)
+bnot16(7992089387369454553)
+bnot16(23513)
+bnot32(7992089387369454553)
+bnot32(861101017)
+bnot64(7992089387369454553)
+brev8(7992089387369454553)
+brev8(217)
+brev16(7992089387369454553)
+brev16(23513)
+brev32(7992089387369454553)
+brev32(861101017)
+brev64(7992089387369454553)
+brol8(7992089387369454553, 6026359350308095352)
+brol8(217, 6026359350308095352)
+brol8(7992089387369454553, 120)
+brol8(217, 120)
+brol16(7992089387369454553, 6026359350308095352)
+brol16(23513, 6026359350308095352)
+brol16(7992089387369454553, 50552)
+brol16(23513, 50552)
+brol32(7992089387369454553, 6026359350308095352)
+brol32(861101017, 6026359350308095352)
+brol32(7992089387369454553, 1811400056)
+brol32(861101017, 1811400056)
+brol64(7992089387369454553, 6026359350308095352)
+bror8(7992089387369454553, 6026359350308095352)
+bror8(217, 6026359350308095352)
+bror8(7992089387369454553, 120)
+bror8(217, 120)
+bror16(7992089387369454553, 6026359350308095352)
+bror16(23513, 6026359350308095352)
+bror16(7992089387369454553, 50552)
+bror16(23513, 50552)
+bror32(7992089387369454553, 6026359350308095352)
+bror32(861101017, 6026359350308095352)
+bror32(7992089387369454553, 1811400056)
+bror32(861101017, 1811400056)
+bror64(7992089387369454553, 6026359350308095352)
+bmod8(7992089387369454553)
+bmod8(217)
+bmod16(7992089387369454553)
+bmod16(23513)
+bmod32(7992089387369454553)
+bmod32(861101017)
+bmod64(7992089387369454553)
+band(16842660107923593892, 3261312657690920987)
+bor(16842660107923593892, 3261312657690920987)
+bxor(16842660107923593892, 3261312657690920987)
+bshl(3312294564, 27)
+bshr(3312294564, 27)
+bshl(1059522587, 4)
+bshr(1059522587, 4)
+bnot8(16842660107923593892)
+bnot8(164)
+bnot16(16842660107923593892)
+bnot16(39588)
+bnot32(16842660107923593892)
+bnot32(3312294564)
+bnot64(16842660107923593892)
+brev8(16842660107923593892)
+brev8(164)
+brev16(16842660107923593892)
+brev16(39588)
+brev32(16842660107923593892)
+brev32(3312294564)
+brev64(16842660107923593892)
+brol8(16842660107923593892, 3261312657690920987)
+brol8(164, 3261312657690920987)
+brol8(16842660107923593892, 27)
+brol8(164, 27)
+brol16(16842660107923593892, 3261312657690920987)
+brol16(39588, 3261312657690920987)
+brol16(16842660107923593892, 2075)
+brol16(39588, 2075)
+brol32(16842660107923593892, 3261312657690920987)
+brol32(3312294564, 3261312657690920987)
+brol32(16842660107923593892, 1059522587)
+brol32(3312294564, 1059522587)
+brol64(16842660107923593892, 3261312657690920987)
+bror8(16842660107923593892, 3261312657690920987)
+bror8(164, 3261312657690920987)
+bror8(16842660107923593892, 27)
+bror8(164, 27)
+bror16(16842660107923593892, 3261312657690920987)
+bror16(39588, 3261312657690920987)
+bror16(16842660107923593892, 2075)
+bror16(39588, 2075)
+bror32(16842660107923593892, 3261312657690920987)
+bror32(3312294564, 3261312657690920987)
+bror32(16842660107923593892, 1059522587)
+bror32(3312294564, 1059522587)
+bror64(16842660107923593892, 3261312657690920987)
+bmod8(16842660107923593892)
+bmod8(164)
+bmod16(16842660107923593892)
+bmod16(39588)
+bmod32(16842660107923593892)
+bmod32(3312294564)
+bmod64(16842660107923593892)
+band(12696979136876657310, 7132813235665896656)
+bor(12696979136876657310, 7132813235665896656)
+bxor(12696979136876657310, 7132813235665896656)
+bshl(3860085406, 16)
+bshr(3860085406, 16)
+bshl(3104965840, 30)
+bshr(3104965840, 30)
+bnot8(12696979136876657310)
+bnot8(158)
+bnot16(12696979136876657310)
+bnot16(15006)
+bnot32(12696979136876657310)
+bnot32(3860085406)
+bnot64(12696979136876657310)
+brev8(12696979136876657310)
+brev8(158)
+brev16(12696979136876657310)
+brev16(15006)
+brev32(12696979136876657310)
+brev32(3860085406)
+brev64(12696979136876657310)
+brol8(12696979136876657310, 7132813235665896656)
+brol8(158, 7132813235665896656)
+brol8(12696979136876657310, 208)
+brol8(158, 208)
+brol16(12696979136876657310, 7132813235665896656)
+brol16(15006, 7132813235665896656)
+brol16(12696979136876657310, 1232)
+brol16(15006, 1232)
+brol32(12696979136876657310, 7132813235665896656)
+brol32(3860085406, 7132813235665896656)
+brol32(12696979136876657310, 3104965840)
+brol32(3860085406, 3104965840)
+brol64(12696979136876657310, 7132813235665896656)
+bror8(12696979136876657310, 7132813235665896656)
+bror8(158, 7132813235665896656)
+bror8(12696979136876657310, 208)
+bror8(158, 208)
+bror16(12696979136876657310, 7132813235665896656)
+bror16(15006, 7132813235665896656)
+bror16(12696979136876657310, 1232)
+bror16(15006, 1232)
+bror32(12696979136876657310, 7132813235665896656)
+bror32(3860085406, 7132813235665896656)
+bror32(12696979136876657310, 3104965840)
+bror32(3860085406, 3104965840)
+bror64(12696979136876657310, 7132813235665896656)
+bmod8(12696979136876657310)
+bmod8(158)
+bmod16(12696979136876657310)
+bmod16(15006)
+bmod32(12696979136876657310)
+bmod32(3860085406)
+bmod64(12696979136876657310)
+band(17435901513135003846, 11441127109026372391)
+bor(17435901513135003846, 11441127109026372391)
+bxor(17435901513135003846, 11441127109026372391)
+bshl(4246444230, 7)
+bshr(4246444230, 7)
+bshl(3952859943, 6)
+bshr(3952859943, 6)
+bnot8(17435901513135003846)
+bnot8(198)
+bnot16(17435901513135003846)
+bnot16(39110)
+bnot32(17435901513135003846)
+bnot32(4246444230)
+bnot64(17435901513135003846)
+brev8(17435901513135003846)
+brev8(198)
+brev16(17435901513135003846)
+brev16(39110)
+brev32(17435901513135003846)
+brev32(4246444230)
+brev64(17435901513135003846)
+brol8(17435901513135003846, 11441127109026372391)
+brol8(198, 11441127109026372391)
+brol8(17435901513135003846, 39)
+brol8(198, 39)
+brol16(17435901513135003846, 11441127109026372391)
+brol16(39110, 11441127109026372391)
+brol16(17435901513135003846, 56103)
+brol16(39110, 56103)
+brol32(17435901513135003846, 11441127109026372391)
+brol32(4246444230, 11441127109026372391)
+brol32(17435901513135003846, 3952859943)
+brol32(4246444230, 3952859943)
+brol64(17435901513135003846, 11441127109026372391)
+bror8(17435901513135003846, 11441127109026372391)
+bror8(198, 11441127109026372391)
+bror8(17435901513135003846, 39)
+bror8(198, 39)
+bror16(17435901513135003846, 11441127109026372391)
+bror16(39110, 11441127109026372391)
+bror16(17435901513135003846, 56103)
+bror16(39110, 56103)
+bror32(17435901513135003846, 11441127109026372391)
+bror32(4246444230, 11441127109026372391)
+bror32(17435901513135003846, 3952859943)
+bror32(4246444230, 3952859943)
+bror64(17435901513135003846, 11441127109026372391)
+bmod8(17435901513135003846)
+bmod8(198)
+bmod16(17435901513135003846)
+bmod16(39110)
+bmod32(17435901513135003846)
+bmod32(4246444230)
+bmod64(17435901513135003846)
+band(9590104870242229844, 18186750166448503638)
+bor(9590104870242229844, 18186750166448503638)
+bxor(9590104870242229844, 18186750166448503638)
+bshl(2777161300, 22)
+bshr(2777161300, 22)
+bshl(972061526, 20)
+bshr(972061526, 20)
+bnot8(9590104870242229844)
+bnot8(84)
+bnot16(9590104870242229844)
+bnot16(7764)
+bnot32(9590104870242229844)
+bnot32(2777161300)
+bnot64(9590104870242229844)
+brev8(9590104870242229844)
+brev8(84)
+brev16(9590104870242229844)
+brev16(7764)
+brev32(9590104870242229844)
+brev32(2777161300)
+brev64(9590104870242229844)
+brol8(9590104870242229844, 18186750166448503638)
+brol8(84, 18186750166448503638)
+brol8(9590104870242229844, 86)
+brol8(84, 86)
+brol16(9590104870242229844, 18186750166448503638)
+brol16(7764, 18186750166448503638)
+brol16(9590104870242229844, 31574)
+brol16(7764, 31574)
+brol32(9590104870242229844, 18186750166448503638)
+brol32(2777161300, 18186750166448503638)
+brol32(9590104870242229844, 972061526)
+brol32(2777161300, 972061526)
+brol64(9590104870242229844, 18186750166448503638)
+bror8(9590104870242229844, 18186750166448503638)
+bror8(84, 18186750166448503638)
+bror8(9590104870242229844, 86)
+bror8(84, 86)
+bror16(9590104870242229844, 18186750166448503638)
+bror16(7764, 18186750166448503638)
+bror16(9590104870242229844, 31574)
+bror16(7764, 31574)
+bror32(9590104870242229844, 18186750166448503638)
+bror32(2777161300, 18186750166448503638)
+bror32(9590104870242229844, 972061526)
+bror32(2777161300, 972061526)
+bror64(9590104870242229844, 18186750166448503638)
+bmod8(9590104870242229844)
+bmod8(84)
+bmod16(9590104870242229844)
+bmod16(7764)
+bmod32(9590104870242229844)
+bmod32(2777161300)
+bmod64(9590104870242229844)
+band(17098710469988438580, 7361917524176358439)
+bor(17098710469988438580, 7361917524176358439)
+bxor(17098710469988438580, 7361917524176358439)
+bshl(1625936436, 7)
+bshr(1625936436, 7)
+bshl(2923514919, 20)
+bshr(2923514919, 20)
+bnot8(17098710469988438580)
+bnot8(52)
+bnot16(17098710469988438580)
+bnot16(53812)
+bnot32(17098710469988438580)
+bnot32(1625936436)
+bnot64(17098710469988438580)
+brev8(17098710469988438580)
+brev8(52)
+brev16(17098710469988438580)
+brev16(53812)
+brev32(17098710469988438580)
+brev32(1625936436)
+brev64(17098710469988438580)
+brol8(17098710469988438580, 7361917524176358439)
+brol8(52, 7361917524176358439)
+brol8(17098710469988438580, 39)
+brol8(52, 39)
+brol16(17098710469988438580, 7361917524176358439)
+brol16(53812, 7361917524176358439)
+brol16(17098710469988438580, 19495)
+brol16(53812, 19495)
+brol32(17098710469988438580, 7361917524176358439)
+brol32(1625936436, 7361917524176358439)
+brol32(17098710469988438580, 2923514919)
+brol32(1625936436, 2923514919)
+brol64(17098710469988438580, 7361917524176358439)
+bror8(17098710469988438580, 7361917524176358439)
+bror8(52, 7361917524176358439)
+bror8(17098710469988438580, 39)
+bror8(52, 39)
+bror16(17098710469988438580, 7361917524176358439)
+bror16(53812, 7361917524176358439)
+bror16(17098710469988438580, 19495)
+bror16(53812, 19495)
+bror32(17098710469988438580, 7361917524176358439)
+bror32(1625936436, 7361917524176358439)
+bror32(17098710469988438580, 2923514919)
+bror32(1625936436, 2923514919)
+bror64(17098710469988438580, 7361917524176358439)
+bmod8(17098710469988438580)
+bmod8(52)
+bmod16(17098710469988438580)
+bmod16(53812)
+bmod32(17098710469988438580)
+bmod32(1625936436)
+bmod64(17098710469988438580)
+band(13895494405150278558, 3119744043262939407)
+bor(13895494405150278558, 3119744043262939407)
+bxor(13895494405150278558, 3119744043262939407)
+bshl(1030292382, 15)
+bshr(1030292382, 15)
+bshl(2698252559, 30)
+bshr(2698252559, 30)
+bnot8(13895494405150278558)
+bnot8(158)
+bnot16(13895494405150278558)
+bnot16(926)
+bnot32(13895494405150278558)
+bnot32(1030292382)
+bnot64(13895494405150278558)
+brev8(13895494405150278558)
+brev8(158)
+brev16(13895494405150278558)
+brev16(926)
+brev32(13895494405150278558)
+brev32(1030292382)
+brev64(13895494405150278558)
+brol8(13895494405150278558, 3119744043262939407)
+brol8(158, 3119744043262939407)
+brol8(13895494405150278558, 15)
+brol8(158, 15)
+brol16(13895494405150278558, 3119744043262939407)
+brol16(926, 3119744043262939407)
+brol16(13895494405150278558, 4367)
+brol16(926, 4367)
+brol32(13895494405150278558, 3119744043262939407)
+brol32(1030292382, 3119744043262939407)
+brol32(13895494405150278558, 2698252559)
+brol32(1030292382, 2698252559)
+brol64(13895494405150278558, 3119744043262939407)
+bror8(13895494405150278558, 3119744043262939407)
+bror8(158, 3119744043262939407)
+bror8(13895494405150278558, 15)
+bror8(158, 15)
+bror16(13895494405150278558, 3119744043262939407)
+bror16(926, 3119744043262939407)
+bror16(13895494405150278558, 4367)
+bror16(926, 4367)
+bror32(13895494405150278558, 3119744043262939407)
+bror32(1030292382, 3119744043262939407)
+bror32(13895494405150278558, 2698252559)
+bror32(1030292382, 2698252559)
+bror64(13895494405150278558, 3119744043262939407)
+bmod8(13895494405150278558)
+bmod8(158)
+bmod16(13895494405150278558)
+bmod16(926)
+bmod32(13895494405150278558)
+bmod32(1030292382)
+bmod64(13895494405150278558)
+band(2430156302210282244, 7090417138384424278)
+bor(2430156302210282244, 7090417138384424278)
+bxor(2430156302210282244, 7090417138384424278)
+bshl(99332868, 22)
+bshr(99332868, 22)
+bshl(448712022, 4)
+bshr(448712022, 4)
+bnot8(2430156302210282244)
+bnot8(4)
+bnot16(2430156302210282244)
+bnot16(45828)
+bnot32(2430156302210282244)
+bnot32(99332868)
+bnot64(2430156302210282244)
+brev8(2430156302210282244)
+brev8(4)
+brev16(2430156302210282244)
+brev16(45828)
+brev32(2430156302210282244)
+brev32(99332868)
+brev64(2430156302210282244)
+brol8(2430156302210282244, 7090417138384424278)
+brol8(4, 7090417138384424278)
+brol8(2430156302210282244, 86)
+brol8(4, 86)
+brol16(2430156302210282244, 7090417138384424278)
+brol16(45828, 7090417138384424278)
+brol16(2430156302210282244, 52566)
+brol16(45828, 52566)
+brol32(2430156302210282244, 7090417138384424278)
+brol32(99332868, 7090417138384424278)
+brol32(2430156302210282244, 448712022)
+brol32(99332868, 448712022)
+brol64(2430156302210282244, 7090417138384424278)
+bror8(2430156302210282244, 7090417138384424278)
+bror8(4, 7090417138384424278)
+bror8(2430156302210282244, 86)
+bror8(4, 86)
+bror16(2430156302210282244, 7090417138384424278)
+bror16(45828, 7090417138384424278)
+bror16(2430156302210282244, 52566)
+bror16(45828, 52566)
+bror32(2430156302210282244, 7090417138384424278)
+bror32(99332868, 7090417138384424278)
+bror32(2430156302210282244, 448712022)
+bror32(99332868, 448712022)
+bror64(2430156302210282244, 7090417138384424278)
+bmod8(2430156302210282244)
+bmod8(4)
+bmod16(2430156302210282244)
+bmod16(45828)
+bmod32(2430156302210282244)
+bmod32(99332868)
+bmod64(2430156302210282244)
+band(17411866921001426005, 11130391415759608262)
+bor(17411866921001426005, 11130391415759608262)
+bxor(17411866921001426005, 11130391415759608262)
+bshl(1856642133, 6)
+bshr(1856642133, 6)
+bshl(1936234950, 21)
+bshr(1936234950, 21)
+bnot8(17411866921001426005)
+bnot8(85)
+bnot16(17411866921001426005)
+bnot16(7253)
+bnot32(17411866921001426005)
+bnot32(1856642133)
+bnot64(17411866921001426005)
+brev8(17411866921001426005)
+brev8(85)
+brev16(17411866921001426005)
+brev16(7253)
+brev32(17411866921001426005)
+brev32(1856642133)
+brev64(17411866921001426005)
+brol8(17411866921001426005, 11130391415759608262)
+brol8(85, 11130391415759608262)
+brol8(17411866921001426005, 198)
+brol8(85, 198)
+brol16(17411866921001426005, 11130391415759608262)
+brol16(7253, 11130391415759608262)
+brol16(17411866921001426005, 39366)
+brol16(7253, 39366)
+brol32(17411866921001426005, 11130391415759608262)
+brol32(1856642133, 11130391415759608262)
+brol32(17411866921001426005, 1936234950)
+brol32(1856642133, 1936234950)
+brol64(17411866921001426005, 11130391415759608262)
+bror8(17411866921001426005, 11130391415759608262)
+bror8(85, 11130391415759608262)
+bror8(17411866921001426005, 198)
+bror8(85, 198)
+bror16(17411866921001426005, 11130391415759608262)
+bror16(7253, 11130391415759608262)
+bror16(17411866921001426005, 39366)
+bror16(7253, 39366)
+bror32(17411866921001426005, 11130391415759608262)
+bror32(1856642133, 11130391415759608262)
+bror32(17411866921001426005, 1936234950)
+bror32(1856642133, 1936234950)
+bror64(17411866921001426005, 11130391415759608262)
+bmod8(17411866921001426005)
+bmod8(85)
+bmod16(17411866921001426005)
+bmod16(7253)
+bmod32(17411866921001426005)
+bmod32(1856642133)
+bmod64(17411866921001426005)
+band(10011532728660082929, 8466932148095365832)
+bor(10011532728660082929, 8466932148095365832)
+bxor(10011532728660082929, 8466932148095365832)
+bshl(754663665, 8)
+bshr(754663665, 8)
+bshl(3499045576, 17)
+bshr(3499045576, 17)
+bnot8(10011532728660082929)
+bnot8(241)
+bnot16(10011532728660082929)
+bnot16(16625)
+bnot32(10011532728660082929)
+bnot32(754663665)
+bnot64(10011532728660082929)
+brev8(10011532728660082929)
+brev8(241)
+brev16(10011532728660082929)
+brev16(16625)
+brev32(10011532728660082929)
+brev32(754663665)
+brev64(10011532728660082929)
+brol8(10011532728660082929, 8466932148095365832)
+brol8(241, 8466932148095365832)
+brol8(10011532728660082929, 200)
+brol8(241, 200)
+brol16(10011532728660082929, 8466932148095365832)
+brol16(16625, 8466932148095365832)
+brol16(10011532728660082929, 13000)
+brol16(16625, 13000)
+brol32(10011532728660082929, 8466932148095365832)
+brol32(754663665, 8466932148095365832)
+brol32(10011532728660082929, 3499045576)
+brol32(754663665, 3499045576)
+brol64(10011532728660082929, 8466932148095365832)
+bror8(10011532728660082929, 8466932148095365832)
+bror8(241, 8466932148095365832)
+bror8(10011532728660082929, 200)
+bror8(241, 200)
+bror16(10011532728660082929, 8466932148095365832)
+bror16(16625, 8466932148095365832)
+bror16(10011532728660082929, 13000)
+bror16(16625, 13000)
+bror32(10011532728660082929, 8466932148095365832)
+bror32(754663665, 8466932148095365832)
+bror32(10011532728660082929, 3499045576)
+bror32(754663665, 3499045576)
+bror64(10011532728660082929, 8466932148095365832)
+bmod8(10011532728660082929)
+bmod8(241)
+bmod16(10011532728660082929)
+bmod16(16625)
+bmod32(10011532728660082929)
+bmod32(754663665)
+bmod64(10011532728660082929)
+band(4529366056582126358, 7053675441545522567)
+bor(4529366056582126358, 7053675441545522567)
+bxor(4529366056582126358, 7053675441545522567)
+bshl(1279925014, 7)
+bshr(1279925014, 7)
+bshl(775400839, 22)
+bshr(775400839, 22)
+bnot8(4529366056582126358)
+bnot8(22)
+bnot16(4529366056582126358)
+bnot16(6934)
+bnot32(4529366056582126358)
+bnot32(1279925014)
+bnot64(4529366056582126358)
+brev8(4529366056582126358)
+brev8(22)
+brev16(4529366056582126358)
+brev16(6934)
+brev32(4529366056582126358)
+brev32(1279925014)
+brev64(4529366056582126358)
+brol8(4529366056582126358, 7053675441545522567)
+brol8(22, 7053675441545522567)
+brol8(4529366056582126358, 135)
+brol8(22, 135)
+brol16(4529366056582126358, 7053675441545522567)
+brol16(6934, 7053675441545522567)
+brol16(4529366056582126358, 44423)
+brol16(6934, 44423)
+brol32(4529366056582126358, 7053675441545522567)
+brol32(1279925014, 7053675441545522567)
+brol32(4529366056582126358, 775400839)
+brol32(1279925014, 775400839)
+brol64(4529366056582126358, 7053675441545522567)
+bror8(4529366056582126358, 7053675441545522567)
+bror8(22, 7053675441545522567)
+bror8(4529366056582126358, 135)
+bror8(22, 135)
+bror16(4529366056582126358, 7053675441545522567)
+bror16(6934, 7053675441545522567)
+bror16(4529366056582126358, 44423)
+bror16(6934, 44423)
+bror32(4529366056582126358, 7053675441545522567)
+bror32(1279925014, 7053675441545522567)
+bror32(4529366056582126358, 775400839)
+bror32(1279925014, 775400839)
+bror64(4529366056582126358, 7053675441545522567)
+bmod8(4529366056582126358)
+bmod8(22)
+bmod16(4529366056582126358)
+bmod16(6934)
+bmod32(4529366056582126358)
+bmod32(1279925014)
+bmod64(4529366056582126358)
+band(9954505809764874338, 12357306252980692531)
+bor(9954505809764874338, 12357306252980692531)
+bxor(9954505809764874338, 12357306252980692531)
+bshl(4053334114, 19)
+bshr(4053334114, 19)
+bshl(3047204403, 2)
+bshr(3047204403, 2)
+bnot8(9954505809764874338)
+bnot8(98)
+bnot16(9954505809764874338)
+bnot16(63586)
+bnot32(9954505809764874338)
+bnot32(4053334114)
+bnot64(9954505809764874338)
+brev8(9954505809764874338)
+brev8(98)
+brev16(9954505809764874338)
+brev16(63586)
+brev32(9954505809764874338)
+brev32(4053334114)
+brev64(9954505809764874338)
+brol8(9954505809764874338, 12357306252980692531)
+brol8(98, 12357306252980692531)
+brol8(9954505809764874338, 51)
+brol8(98, 51)
+brol16(9954505809764874338, 12357306252980692531)
+brol16(63586, 12357306252980692531)
+brol16(9954505809764874338, 42547)
+brol16(63586, 42547)
+brol32(9954505809764874338, 12357306252980692531)
+brol32(4053334114, 12357306252980692531)
+brol32(9954505809764874338, 3047204403)
+brol32(4053334114, 3047204403)
+brol64(9954505809764874338, 12357306252980692531)
+bror8(9954505809764874338, 12357306252980692531)
+bror8(98, 12357306252980692531)
+bror8(9954505809764874338, 51)
+bror8(98, 51)
+bror16(9954505809764874338, 12357306252980692531)
+bror16(63586, 12357306252980692531)
+bror16(9954505809764874338, 42547)
+bror16(63586, 42547)
+bror32(9954505809764874338, 12357306252980692531)
+bror32(4053334114, 12357306252980692531)
+bror32(9954505809764874338, 3047204403)
+bror32(4053334114, 3047204403)
+bror64(9954505809764874338, 12357306252980692531)
+bmod8(9954505809764874338)
+bmod8(98)
+bmod16(9954505809764874338)
+bmod16(63586)
+bmod32(9954505809764874338)
+bmod32(4053334114)
+bmod64(9954505809764874338)
+band(1714357442527759693, 1630351958558425339)
+bor(1714357442527759693, 1630351958558425339)
+bxor(1714357442527759693, 1630351958558425339)
+bshl(3421113677, 27)
+bshr(3421113677, 27)
+bshl(3837575419, 13)
+bshr(3837575419, 13)
+bnot8(1714357442527759693)
+bnot8(77)
+bnot16(1714357442527759693)
+bnot16(3405)
+bnot32(1714357442527759693)
+bnot32(3421113677)
+bnot64(1714357442527759693)
+brev8(1714357442527759693)
+brev8(77)
+brev16(1714357442527759693)
+brev16(3405)
+brev32(1714357442527759693)
+brev32(3421113677)
+brev64(1714357442527759693)
+brol8(1714357442527759693, 1630351958558425339)
+brol8(77, 1630351958558425339)
+brol8(1714357442527759693, 251)
+brol8(77, 251)
+brol16(1714357442527759693, 1630351958558425339)
+brol16(3405, 1630351958558425339)
+brol16(1714357442527759693, 49403)
+brol16(3405, 49403)
+brol32(1714357442527759693, 1630351958558425339)
+brol32(3421113677, 1630351958558425339)
+brol32(1714357442527759693, 3837575419)
+brol32(3421113677, 3837575419)
+brol64(1714357442527759693, 1630351958558425339)
+bror8(1714357442527759693, 1630351958558425339)
+bror8(77, 1630351958558425339)
+bror8(1714357442527759693, 251)
+bror8(77, 251)
+bror16(1714357442527759693, 1630351958558425339)
+bror16(3405, 1630351958558425339)
+bror16(1714357442527759693, 49403)
+bror16(3405, 49403)
+bror32(1714357442527759693, 1630351958558425339)
+bror32(3421113677, 1630351958558425339)
+bror32(1714357442527759693, 3837575419)
+bror32(3421113677, 3837575419)
+bror64(1714357442527759693, 1630351958558425339)
+bmod8(1714357442527759693)
+bmod8(77)
+bmod16(1714357442527759693)
+bmod16(3405)
+bmod32(1714357442527759693)
+bmod32(3421113677)
+bmod64(1714357442527759693)
+band(3616954875711705367, 8611979855476168340)
+bor(3616954875711705367, 8611979855476168340)
+bxor(3616954875711705367, 8611979855476168340)
+bshl(3345600791, 20)
+bshr(3345600791, 20)
+bshl(3799651988, 23)
+bshr(3799651988, 23)
+bnot8(3616954875711705367)
+bnot8(23)
+bnot16(3616954875711705367)
+bnot16(53527)
+bnot32(3616954875711705367)
+bnot32(3345600791)
+bnot64(3616954875711705367)
+brev8(3616954875711705367)
+brev8(23)
+brev16(3616954875711705367)
+brev16(53527)
+brev32(3616954875711705367)
+brev32(3345600791)
+brev64(3616954875711705367)
+brol8(3616954875711705367, 8611979855476168340)
+brol8(23, 8611979855476168340)
+brol8(3616954875711705367, 148)
+brol8(23, 148)
+brol16(3616954875711705367, 8611979855476168340)
+brol16(53527, 8611979855476168340)
+brol16(3616954875711705367, 5780)
+brol16(53527, 5780)
+brol32(3616954875711705367, 8611979855476168340)
+brol32(3345600791, 8611979855476168340)
+brol32(3616954875711705367, 3799651988)
+brol32(3345600791, 3799651988)
+brol64(3616954875711705367, 8611979855476168340)
+bror8(3616954875711705367, 8611979855476168340)
+bror8(23, 8611979855476168340)
+bror8(3616954875711705367, 148)
+bror8(23, 148)
+bror16(3616954875711705367, 8611979855476168340)
+bror16(53527, 8611979855476168340)
+bror16(3616954875711705367, 5780)
+bror16(53527, 5780)
+bror32(3616954875711705367, 8611979855476168340)
+bror32(3345600791, 8611979855476168340)
+bror32(3616954875711705367, 3799651988)
+bror32(3345600791, 3799651988)
+bror64(3616954875711705367, 8611979855476168340)
+bmod8(3616954875711705367)
+bmod8(23)
+bmod16(3616954875711705367)
+bmod16(53527)
+bmod32(3616954875711705367)
+bmod32(3345600791)
+bmod64(3616954875711705367)
+band(13747829460615817976, 332415066838309686)
+bor(13747829460615817976, 332415066838309686)
+bxor(13747829460615817976, 332415066838309686)
+bshl(682093304, 22)
+bshr(682093304, 22)
+bshl(4175600438, 24)
+bshr(4175600438, 24)
+bnot8(13747829460615817976)
+bnot8(248)
+bnot16(13747829460615817976)
+bnot16(60152)
+bnot32(13747829460615817976)
+bnot32(682093304)
+bnot64(13747829460615817976)
+brev8(13747829460615817976)
+brev8(248)
+brev16(13747829460615817976)
+brev16(60152)
+brev32(13747829460615817976)
+brev32(682093304)
+brev64(13747829460615817976)
+brol8(13747829460615817976, 332415066838309686)
+brol8(248, 332415066838309686)
+brol8(13747829460615817976, 54)
+brol8(248, 54)
+brol16(13747829460615817976, 332415066838309686)
+brol16(60152, 332415066838309686)
+brol16(13747829460615817976, 39734)
+brol16(60152, 39734)
+brol32(13747829460615817976, 332415066838309686)
+brol32(682093304, 332415066838309686)
+brol32(13747829460615817976, 4175600438)
+brol32(682093304, 4175600438)
+brol64(13747829460615817976, 332415066838309686)
+bror8(13747829460615817976, 332415066838309686)
+bror8(248, 332415066838309686)
+bror8(13747829460615817976, 54)
+bror8(248, 54)
+bror16(13747829460615817976, 332415066838309686)
+bror16(60152, 332415066838309686)
+bror16(13747829460615817976, 39734)
+bror16(60152, 39734)
+bror32(13747829460615817976, 332415066838309686)
+bror32(682093304, 332415066838309686)
+bror32(13747829460615817976, 4175600438)
+bror32(682093304, 4175600438)
+bror64(13747829460615817976, 332415066838309686)
+bmod8(13747829460615817976)
+bmod8(248)
+bmod16(13747829460615817976)
+bmod16(60152)
+bmod32(13747829460615817976)
+bmod32(682093304)
+bmod64(13747829460615817976)
+band(16270508600839668153, 14573229950436308906)
+bor(16270508600839668153, 14573229950436308906)
+bxor(16270508600839668153, 14573229950436308906)
+bshl(469533113, 10)
+bshr(469533113, 10)
+bshl(2044131242, 25)
+bshr(2044131242, 25)
+bnot8(16270508600839668153)
+bnot8(185)
+bnot16(16270508600839668153)
+bnot16(33209)
+bnot32(16270508600839668153)
+bnot32(469533113)
+bnot64(16270508600839668153)
+brev8(16270508600839668153)
+brev8(185)
+brev16(16270508600839668153)
+brev16(33209)
+brev32(16270508600839668153)
+brev32(469533113)
+brev64(16270508600839668153)
+brol8(16270508600839668153, 14573229950436308906)
+brol8(185, 14573229950436308906)
+brol8(16270508600839668153, 170)
+brol8(185, 170)
+brol16(16270508600839668153, 14573229950436308906)
+brol16(33209, 14573229950436308906)
+brol16(16270508600839668153, 63402)
+brol16(33209, 63402)
+brol32(16270508600839668153, 14573229950436308906)
+brol32(469533113, 14573229950436308906)
+brol32(16270508600839668153, 2044131242)
+brol32(469533113, 2044131242)
+brol64(16270508600839668153, 14573229950436308906)
+bror8(16270508600839668153, 14573229950436308906)
+bror8(185, 14573229950436308906)
+bror8(16270508600839668153, 170)
+bror8(185, 170)
+bror16(16270508600839668153, 14573229950436308906)
+bror16(33209, 14573229950436308906)
+bror16(16270508600839668153, 63402)
+bror16(33209, 63402)
+bror32(16270508600839668153, 14573229950436308906)
+bror32(469533113, 14573229950436308906)
+bror32(16270508600839668153, 2044131242)
+bror32(469533113, 2044131242)
+bror64(16270508600839668153, 14573229950436308906)
+bmod8(16270508600839668153)
+bmod8(185)
+bmod16(16270508600839668153)
+bmod16(33209)
+bmod32(16270508600839668153)
+bmod32(469533113)
+bmod64(16270508600839668153)
+band(2414724656436165396, 8286121965987155007)
+bor(2414724656436165396, 8286121965987155007)
+bxor(2414724656436165396, 8286121965987155007)
+bshl(21052180, 31)
+bshr(21052180, 31)
+bshl(3157904447, 20)
+bshr(3157904447, 20)
+bnot8(2414724656436165396)
+bnot8(20)
+bnot16(2414724656436165396)
+bnot16(15124)
+bnot32(2414724656436165396)
+bnot32(21052180)
+bnot64(2414724656436165396)
+brev8(2414724656436165396)
+brev8(20)
+brev16(2414724656436165396)
+brev16(15124)
+brev32(2414724656436165396)
+brev32(21052180)
+brev64(2414724656436165396)
+brol8(2414724656436165396, 8286121965987155007)
+brol8(20, 8286121965987155007)
+brol8(2414724656436165396, 63)
+brol8(20, 63)
+brol16(2414724656436165396, 8286121965987155007)
+brol16(15124, 8286121965987155007)
+brol16(2414724656436165396, 52287)
+brol16(15124, 52287)
+brol32(2414724656436165396, 8286121965987155007)
+brol32(21052180, 8286121965987155007)
+brol32(2414724656436165396, 3157904447)
+brol32(21052180, 3157904447)
+brol64(2414724656436165396, 8286121965987155007)
+bror8(2414724656436165396, 8286121965987155007)
+bror8(20, 8286121965987155007)
+bror8(2414724656436165396, 63)
+bror8(20, 63)
+bror16(2414724656436165396, 8286121965987155007)
+bror16(15124, 8286121965987155007)
+bror16(2414724656436165396, 52287)
+bror16(15124, 52287)
+bror32(2414724656436165396, 8286121965987155007)
+bror32(21052180, 8286121965987155007)
+bror32(2414724656436165396, 3157904447)
+bror32(21052180, 3157904447)
+bror64(2414724656436165396, 8286121965987155007)
+bmod8(2414724656436165396)
+bmod8(20)
+bmod16(2414724656436165396)
+bmod16(15124)
+bmod32(2414724656436165396)
+bmod32(21052180)
+bmod64(2414724656436165396)
+band(14148416769642267438, 649786136326615070)
+bor(14148416769642267438, 649786136326615070)
+bxor(14148416769642267438, 649786136326615070)
+bshl(682951470, 30)
+bshr(682951470, 30)
+bshl(1538830366, 14)
+bshr(1538830366, 14)
+bnot8(14148416769642267438)
+bnot8(46)
+bnot16(14148416769642267438)
+bnot16(814)
+bnot32(14148416769642267438)
+bnot32(682951470)
+bnot64(14148416769642267438)
+brev8(14148416769642267438)
+brev8(46)
+brev16(14148416769642267438)
+brev16(814)
+brev32(14148416769642267438)
+brev32(682951470)
+brev64(14148416769642267438)
+brol8(14148416769642267438, 649786136326615070)
+brol8(46, 649786136326615070)
+brol8(14148416769642267438, 30)
+brol8(46, 30)
+brol16(14148416769642267438, 649786136326615070)
+brol16(814, 649786136326615070)
+brol16(14148416769642267438, 45086)
+brol16(814, 45086)
+brol32(14148416769642267438, 649786136326615070)
+brol32(682951470, 649786136326615070)
+brol32(14148416769642267438, 1538830366)
+brol32(682951470, 1538830366)
+brol64(14148416769642267438, 649786136326615070)
+bror8(14148416769642267438, 649786136326615070)
+bror8(46, 649786136326615070)
+bror8(14148416769642267438, 30)
+bror8(46, 30)
+bror16(14148416769642267438, 649786136326615070)
+bror16(814, 649786136326615070)
+bror16(14148416769642267438, 45086)
+bror16(814, 45086)
+bror32(14148416769642267438, 649786136326615070)
+bror32(682951470, 649786136326615070)
+bror32(14148416769642267438, 1538830366)
+bror32(682951470, 1538830366)
+bror64(14148416769642267438, 649786136326615070)
+bmod8(14148416769642267438)
+bmod8(46)
+bmod16(14148416769642267438)
+bmod16(814)
+bmod32(14148416769642267438)
+bmod32(682951470)
+bmod64(14148416769642267438)
+band(6422427504571247972, 262147824287046922)
+bor(6422427504571247972, 262147824287046922)
+bxor(6422427504571247972, 262147824287046922)
+bshl(3047877988, 10)
+bshr(3047877988, 10)
+bshl(2839895306, 4)
+bshr(2839895306, 4)
+bnot8(6422427504571247972)
+bnot8(100)
+bnot16(6422427504571247972)
+bnot16(60772)
+bnot32(6422427504571247972)
+bnot32(3047877988)
+bnot64(6422427504571247972)
+brev8(6422427504571247972)
+brev8(100)
+brev16(6422427504571247972)
+brev16(60772)
+brev32(6422427504571247972)
+brev32(3047877988)
+brev64(6422427504571247972)
+brol8(6422427504571247972, 262147824287046922)
+brol8(100, 262147824287046922)
+brol8(6422427504571247972, 10)
+brol8(100, 10)
+brol16(6422427504571247972, 262147824287046922)
+brol16(60772, 262147824287046922)
+brol16(6422427504571247972, 23818)
+brol16(60772, 23818)
+brol32(6422427504571247972, 262147824287046922)
+brol32(3047877988, 262147824287046922)
+brol32(6422427504571247972, 2839895306)
+brol32(3047877988, 2839895306)
+brol64(6422427504571247972, 262147824287046922)
+bror8(6422427504571247972, 262147824287046922)
+bror8(100, 262147824287046922)
+bror8(6422427504571247972, 10)
+bror8(100, 10)
+bror16(6422427504571247972, 262147824287046922)
+bror16(60772, 262147824287046922)
+bror16(6422427504571247972, 23818)
+bror16(60772, 23818)
+bror32(6422427504571247972, 262147824287046922)
+bror32(3047877988, 262147824287046922)
+bror32(6422427504571247972, 2839895306)
+bror32(3047877988, 2839895306)
+bror64(6422427504571247972, 262147824287046922)
+bmod8(6422427504571247972)
+bmod8(100)
+bmod16(6422427504571247972)
+bmod16(60772)
+bmod32(6422427504571247972)
+bmod32(3047877988)
+bmod64(6422427504571247972)
+band(8528916021543859673, 2065836426822817883)
+bor(8528916021543859673, 2065836426822817883)
+bxor(8528916021543859673, 2065836426822817883)
+bshl(4148327897, 27)
+bshr(4148327897, 27)
+bshl(4040562779, 25)
+bshr(4040562779, 25)
+bnot8(8528916021543859673)
+bnot8(217)
+bnot16(8528916021543859673)
+bnot16(30169)
+bnot32(8528916021543859673)
+bnot32(4148327897)
+bnot64(8528916021543859673)
+brev8(8528916021543859673)
+brev8(217)
+brev16(8528916021543859673)
+brev16(30169)
+brev32(8528916021543859673)
+brev32(4148327897)
+brev64(8528916021543859673)
+brol8(8528916021543859673, 2065836426822817883)
+brol8(217, 2065836426822817883)
+brol8(8528916021543859673, 91)
+brol8(217, 91)
+brol16(8528916021543859673, 2065836426822817883)
+brol16(30169, 2065836426822817883)
+brol16(8528916021543859673, 6235)
+brol16(30169, 6235)
+brol32(8528916021543859673, 2065836426822817883)
+brol32(4148327897, 2065836426822817883)
+brol32(8528916021543859673, 4040562779)
+brol32(4148327897, 4040562779)
+brol64(8528916021543859673, 2065836426822817883)
+bror8(8528916021543859673, 2065836426822817883)
+bror8(217, 2065836426822817883)
+bror8(8528916021543859673, 91)
+bror8(217, 91)
+bror16(8528916021543859673, 2065836426822817883)
+bror16(30169, 2065836426822817883)
+bror16(8528916021543859673, 6235)
+bror16(30169, 6235)
+bror32(8528916021543859673, 2065836426822817883)
+bror32(4148327897, 2065836426822817883)
+bror32(8528916021543859673, 4040562779)
+bror32(4148327897, 4040562779)
+bror64(8528916021543859673, 2065836426822817883)
+bmod8(8528916021543859673)
+bmod8(217)
+bmod16(8528916021543859673)
+bmod16(30169)
+bmod32(8528916021543859673)
+bmod32(4148327897)
+bmod64(8528916021543859673)
+band(11562368908454130659, 6492191351038272669)
+bor(11562368908454130659, 6492191351038272669)
+bxor(11562368908454130659, 6492191351038272669)
+bshl(510522339, 29)
+bshr(510522339, 29)
+bshl(4236240029, 3)
+bshr(4236240029, 3)
+bnot8(11562368908454130659)
+bnot8(227)
+bnot16(11562368908454130659)
+bnot16(62435)
+bnot32(11562368908454130659)
+bnot32(510522339)
+bnot64(11562368908454130659)
+brev8(11562368908454130659)
+brev8(227)
+brev16(11562368908454130659)
+brev16(62435)
+brev32(11562368908454130659)
+brev32(510522339)
+brev64(11562368908454130659)
+brol8(11562368908454130659, 6492191351038272669)
+brol8(227, 6492191351038272669)
+brol8(11562368908454130659, 157)
+brol8(227, 157)
+brol16(11562368908454130659, 6492191351038272669)
+brol16(62435, 6492191351038272669)
+brol16(11562368908454130659, 58525)
+brol16(62435, 58525)
+brol32(11562368908454130659, 6492191351038272669)
+brol32(510522339, 6492191351038272669)
+brol32(11562368908454130659, 4236240029)
+brol32(510522339, 4236240029)
+brol64(11562368908454130659, 6492191351038272669)
+bror8(11562368908454130659, 6492191351038272669)
+bror8(227, 6492191351038272669)
+bror8(11562368908454130659, 157)
+bror8(227, 157)
+bror16(11562368908454130659, 6492191351038272669)
+bror16(62435, 6492191351038272669)
+bror16(11562368908454130659, 58525)
+bror16(62435, 58525)
+bror32(11562368908454130659, 6492191351038272669)
+bror32(510522339, 6492191351038272669)
+bror32(11562368908454130659, 4236240029)
+bror32(510522339, 4236240029)
+bror64(11562368908454130659, 6492191351038272669)
+bmod8(11562368908454130659)
+bmod8(227)
+bmod16(11562368908454130659)
+bmod16(62435)
+bmod32(11562368908454130659)
+bmod32(510522339)
+bmod64(11562368908454130659)
+band(3912237790569908733, 722487241158840496)
+bor(3912237790569908733, 722487241158840496)
+bxor(3912237790569908733, 722487241158840496)
+bshl(3888597501, 16)
+bshr(3888597501, 16)
+bshl(1678135472, 29)
+bshr(1678135472, 29)
+bnot8(3912237790569908733)
+bnot8(253)
+bnot16(3912237790569908733)
+bnot16(18941)
+bnot32(3912237790569908733)
+bnot32(3888597501)
+bnot64(3912237790569908733)
+brev8(3912237790569908733)
+brev8(253)
+brev16(3912237790569908733)
+brev16(18941)
+brev32(3912237790569908733)
+brev32(3888597501)
+brev64(3912237790569908733)
+brol8(3912237790569908733, 722487241158840496)
+brol8(253, 722487241158840496)
+brol8(3912237790569908733, 176)
+brol8(253, 176)
+brol16(3912237790569908733, 722487241158840496)
+brol16(18941, 722487241158840496)
+brol16(3912237790569908733, 20656)
+brol16(18941, 20656)
+brol32(3912237790569908733, 722487241158840496)
+brol32(3888597501, 722487241158840496)
+brol32(3912237790569908733, 1678135472)
+brol32(3888597501, 1678135472)
+brol64(3912237790569908733, 722487241158840496)
+bror8(3912237790569908733, 722487241158840496)
+bror8(253, 722487241158840496)
+bror8(3912237790569908733, 176)
+bror8(253, 176)
+bror16(3912237790569908733, 722487241158840496)
+bror16(18941, 722487241158840496)
+bror16(3912237790569908733, 20656)
+bror16(18941, 20656)
+bror32(3912237790569908733, 722487241158840496)
+bror32(3888597501, 722487241158840496)
+bror32(3912237790569908733, 1678135472)
+bror32(3888597501, 1678135472)
+bror64(3912237790569908733, 722487241158840496)
+bmod8(3912237790569908733)
+bmod8(253)
+bmod16(3912237790569908733)
+bmod16(18941)
+bmod32(3912237790569908733)
+bmod32(3888597501)
+bmod64(3912237790569908733)
+band(1832899002788601466, 3707273195320999771)
+bor(1832899002788601466, 3707273195320999771)
+bxor(1832899002788601466, 3707273195320999771)
+bshl(2455887482, 27)
+bshr(2455887482, 27)
+bshl(1148157787, 26)
+bshr(1148157787, 26)
+bnot8(1832899002788601466)
+bnot8(122)
+bnot16(1832899002788601466)
+bnot16(56954)
+bnot32(1832899002788601466)
+bnot32(2455887482)
+bnot64(1832899002788601466)
+brev8(1832899002788601466)
+brev8(122)
+brev16(1832899002788601466)
+brev16(56954)
+brev32(1832899002788601466)
+brev32(2455887482)
+brev64(1832899002788601466)
+brol8(1832899002788601466, 3707273195320999771)
+brol8(122, 3707273195320999771)
+brol8(1832899002788601466, 91)
+brol8(122, 91)
+brol16(1832899002788601466, 3707273195320999771)
+brol16(56954, 3707273195320999771)
+brol16(1832899002788601466, 32603)
+brol16(56954, 32603)
+brol32(1832899002788601466, 3707273195320999771)
+brol32(2455887482, 3707273195320999771)
+brol32(1832899002788601466, 1148157787)
+brol32(2455887482, 1148157787)
+brol64(1832899002788601466, 3707273195320999771)
+bror8(1832899002788601466, 3707273195320999771)
+bror8(122, 3707273195320999771)
+bror8(1832899002788601466, 91)
+bror8(122, 91)
+bror16(1832899002788601466, 3707273195320999771)
+bror16(56954, 3707273195320999771)
+bror16(1832899002788601466, 32603)
+bror16(56954, 32603)
+bror32(1832899002788601466, 3707273195320999771)
+bror32(2455887482, 3707273195320999771)
+bror32(1832899002788601466, 1148157787)
+bror32(2455887482, 1148157787)
+bror64(1832899002788601466, 3707273195320999771)
+bmod8(1832899002788601466)
+bmod8(122)
+bmod16(1832899002788601466)
+bmod16(56954)
+bmod32(1832899002788601466)
+bmod32(2455887482)
+bmod64(1832899002788601466)
+band(9293182878692708428, 14992402141817223677)
+bor(9293182878692708428, 14992402141817223677)
+bxor(9293182878692708428, 14992402141817223677)
+bshl(1027117132, 29)
+bshr(1027117132, 29)
+bshl(2563914237, 12)
+bshr(2563914237, 12)
+bnot8(9293182878692708428)
+bnot8(76)
+bnot16(9293182878692708428)
+bnot16(36940)
+bnot32(9293182878692708428)
+bnot32(1027117132)
+bnot64(9293182878692708428)
+brev8(9293182878692708428)
+brev8(76)
+brev16(9293182878692708428)
+brev16(36940)
+brev32(9293182878692708428)
+brev32(1027117132)
+brev64(9293182878692708428)
+brol8(9293182878692708428, 14992402141817223677)
+brol8(76, 14992402141817223677)
+brol8(9293182878692708428, 253)
+brol8(76, 253)
+brol16(9293182878692708428, 14992402141817223677)
+brol16(36940, 14992402141817223677)
+brol16(9293182878692708428, 14845)
+brol16(36940, 14845)
+brol32(9293182878692708428, 14992402141817223677)
+brol32(1027117132, 14992402141817223677)
+brol32(9293182878692708428, 2563914237)
+brol32(1027117132, 2563914237)
+brol64(9293182878692708428, 14992402141817223677)
+bror8(9293182878692708428, 14992402141817223677)
+bror8(76, 14992402141817223677)
+bror8(9293182878692708428, 253)
+bror8(76, 253)
+bror16(9293182878692708428, 14992402141817223677)
+bror16(36940, 14992402141817223677)
+bror16(9293182878692708428, 14845)
+bror16(36940, 14845)
+bror32(9293182878692708428, 14992402141817223677)
+bror32(1027117132, 14992402141817223677)
+bror32(9293182878692708428, 2563914237)
+bror32(1027117132, 2563914237)
+bror64(9293182878692708428, 14992402141817223677)
+bmod8(9293182878692708428)
+bmod8(76)
+bmod16(9293182878692708428)
+bmod16(36940)
+bmod32(9293182878692708428)
+bmod32(1027117132)
+bmod64(9293182878692708428)
+band(17648575581392266921, 2219293127805397031)
+bor(17648575581392266921, 2219293127805397031)
+bxor(17648575581392266921, 2219293127805397031)
+bshl(814016169, 7)
+bshr(814016169, 7)
+bshl(1733191719, 9)
+bshr(1733191719, 9)
+bnot8(17648575581392266921)
+bnot8(169)
+bnot16(17648575581392266921)
+bnot16(59049)
+bnot32(17648575581392266921)
+bnot32(814016169)
+bnot64(17648575581392266921)
+brev8(17648575581392266921)
+brev8(169)
+brev16(17648575581392266921)
+brev16(59049)
+brev32(17648575581392266921)
+brev32(814016169)
+brev64(17648575581392266921)
+brol8(17648575581392266921, 2219293127805397031)
+brol8(169, 2219293127805397031)
+brol8(17648575581392266921, 39)
+brol8(169, 39)
+brol16(17648575581392266921, 2219293127805397031)
+brol16(59049, 2219293127805397031)
+brol16(17648575581392266921, 26663)
+brol16(59049, 26663)
+brol32(17648575581392266921, 2219293127805397031)
+brol32(814016169, 2219293127805397031)
+brol32(17648575581392266921, 1733191719)
+brol32(814016169, 1733191719)
+brol64(17648575581392266921, 2219293127805397031)
+bror8(17648575581392266921, 2219293127805397031)
+bror8(169, 2219293127805397031)
+bror8(17648575581392266921, 39)
+bror8(169, 39)
+bror16(17648575581392266921, 2219293127805397031)
+bror16(59049, 2219293127805397031)
+bror16(17648575581392266921, 26663)
+bror16(59049, 26663)
+bror32(17648575581392266921, 2219293127805397031)
+bror32(814016169, 2219293127805397031)
+bror32(17648575581392266921, 1733191719)
+bror32(814016169, 1733191719)
+bror64(17648575581392266921, 2219293127805397031)
+bmod8(17648575581392266921)
+bmod8(169)
+bmod16(17648575581392266921)
+bmod16(59049)
+bmod32(17648575581392266921)
+bmod32(814016169)
+bmod64(17648575581392266921)
+band(2538084433844068612, 1473327554323942016)
+bor(2538084433844068612, 1473327554323942016)
+bxor(2538084433844068612, 1473327554323942016)
+bshl(1631150340, 0)
+bshr(1631150340, 0)
+bshl(3376810624, 4)
+bshr(3376810624, 4)
+bnot8(2538084433844068612)
+bnot8(4)
+bnot16(2538084433844068612)
+bnot16(24836)
+bnot32(2538084433844068612)
+bnot32(1631150340)
+bnot64(2538084433844068612)
+brev8(2538084433844068612)
+brev8(4)
+brev16(2538084433844068612)
+brev16(24836)
+brev32(2538084433844068612)
+brev32(1631150340)
+brev64(2538084433844068612)
+brol8(2538084433844068612, 1473327554323942016)
+brol8(4, 1473327554323942016)
+brol8(2538084433844068612, 128)
+brol8(4, 128)
+brol16(2538084433844068612, 1473327554323942016)
+brol16(24836, 1473327554323942016)
+brol16(2538084433844068612, 2688)
+brol16(24836, 2688)
+brol32(2538084433844068612, 1473327554323942016)
+brol32(1631150340, 1473327554323942016)
+brol32(2538084433844068612, 3376810624)
+brol32(1631150340, 3376810624)
+brol64(2538084433844068612, 1473327554323942016)
+bror8(2538084433844068612, 1473327554323942016)
+bror8(4, 1473327554323942016)
+bror8(2538084433844068612, 128)
+bror8(4, 128)
+bror16(2538084433844068612, 1473327554323942016)
+bror16(24836, 1473327554323942016)
+bror16(2538084433844068612, 2688)
+bror16(24836, 2688)
+bror32(2538084433844068612, 1473327554323942016)
+bror32(1631150340, 1473327554323942016)
+bror32(2538084433844068612, 3376810624)
+bror32(1631150340, 3376810624)
+bror64(2538084433844068612, 1473327554323942016)
+bmod8(2538084433844068612)
+bmod8(4)
+bmod16(2538084433844068612)
+bmod16(24836)
+bmod32(2538084433844068612)
+bmod32(1631150340)
+bmod64(2538084433844068612)
+band(18003153537922563854, 16931346483669556688)
+bor(18003153537922563854, 16931346483669556688)
+bxor(18003153537922563854, 16931346483669556688)
+bshl(145817358, 16)
+bshr(145817358, 16)
+bshl(3090079184, 14)
+bshr(3090079184, 14)
+bnot8(18003153537922563854)
+bnot8(14)
+bnot16(18003153537922563854)
+bnot16(65294)
+bnot32(18003153537922563854)
+bnot32(145817358)
+bnot64(18003153537922563854)
+brev8(18003153537922563854)
+brev8(14)
+brev16(18003153537922563854)
+brev16(65294)
+brev32(18003153537922563854)
+brev32(145817358)
+brev64(18003153537922563854)
+brol8(18003153537922563854, 16931346483669556688)
+brol8(14, 16931346483669556688)
+brol8(18003153537922563854, 208)
+brol8(14, 208)
+brol16(18003153537922563854, 16931346483669556688)
+brol16(65294, 16931346483669556688)
+brol16(18003153537922563854, 56784)
+brol16(65294, 56784)
+brol32(18003153537922563854, 16931346483669556688)
+brol32(145817358, 16931346483669556688)
+brol32(18003153537922563854, 3090079184)
+brol32(145817358, 3090079184)
+brol64(18003153537922563854, 16931346483669556688)
+bror8(18003153537922563854, 16931346483669556688)
+bror8(14, 16931346483669556688)
+bror8(18003153537922563854, 208)
+bror8(14, 208)
+bror16(18003153537922563854, 16931346483669556688)
+bror16(65294, 16931346483669556688)
+bror16(18003153537922563854, 56784)
+bror16(65294, 56784)
+bror32(18003153537922563854, 16931346483669556688)
+bror32(145817358, 16931346483669556688)
+bror32(18003153537922563854, 3090079184)
+bror32(145817358, 3090079184)
+bror64(18003153537922563854, 16931346483669556688)
+bmod8(18003153537922563854)
+bmod8(14)
+bmod16(18003153537922563854)
+bmod16(65294)
+bmod32(18003153537922563854)
+bmod32(145817358)
+bmod64(18003153537922563854)
+band(11193086034034122745, 17772936273584077572)
+bor(11193086034034122745, 17772936273584077572)
+bxor(11193086034034122745, 17772936273584077572)
+bshl(3338493945, 4)
+bshr(3338493945, 4)
+bshl(849492740, 25)
+bshr(849492740, 25)
+bnot8(11193086034034122745)
+bnot8(249)
+bnot16(11193086034034122745)
+bnot16(24569)
+bnot32(11193086034034122745)
+bnot32(3338493945)
+bnot64(11193086034034122745)
+brev8(11193086034034122745)
+brev8(249)
+brev16(11193086034034122745)
+brev16(24569)
+brev32(11193086034034122745)
+brev32(3338493945)
+brev64(11193086034034122745)
+brol8(11193086034034122745, 17772936273584077572)
+brol8(249, 17772936273584077572)
+brol8(11193086034034122745, 4)
+brol8(249, 4)
+brol16(11193086034034122745, 17772936273584077572)
+brol16(24569, 17772936273584077572)
+brol16(11193086034034122745, 15108)
+brol16(24569, 15108)
+brol32(11193086034034122745, 17772936273584077572)
+brol32(3338493945, 17772936273584077572)
+brol32(11193086034034122745, 849492740)
+brol32(3338493945, 849492740)
+brol64(11193086034034122745, 17772936273584077572)
+bror8(11193086034034122745, 17772936273584077572)
+bror8(249, 17772936273584077572)
+bror8(11193086034034122745, 4)
+bror8(249, 4)
+bror16(11193086034034122745, 17772936273584077572)
+bror16(24569, 17772936273584077572)
+bror16(11193086034034122745, 15108)
+bror16(24569, 15108)
+bror32(11193086034034122745, 17772936273584077572)
+bror32(3338493945, 17772936273584077572)
+bror32(11193086034034122745, 849492740)
+bror32(3338493945, 849492740)
+bror64(11193086034034122745, 17772936273584077572)
+bmod8(11193086034034122745)
+bmod8(249)
+bmod16(11193086034034122745)
+bmod16(24569)
+bmod32(11193086034034122745)
+bmod32(3338493945)
+bmod64(11193086034034122745)
+band(93191692570513733, 3384295305723863025)
+bor(93191692570513733, 3384295305723863025)
+bxor(93191692570513733, 3384295305723863025)
+bshl(3283013957, 17)
+bshr(3283013957, 17)
+bshl(1488019441, 5)
+bshr(1488019441, 5)
+bnot8(93191692570513733)
+bnot8(69)
+bnot16(93191692570513733)
+bnot16(53573)
+bnot32(93191692570513733)
+bnot32(3283013957)
+bnot64(93191692570513733)
+brev8(93191692570513733)
+brev8(69)
+brev16(93191692570513733)
+brev16(53573)
+brev32(93191692570513733)
+brev32(3283013957)
+brev64(93191692570513733)
+brol8(93191692570513733, 3384295305723863025)
+brol8(69, 3384295305723863025)
+brol8(93191692570513733, 241)
+brol8(69, 241)
+brol16(93191692570513733, 3384295305723863025)
+brol16(53573, 3384295305723863025)
+brol16(93191692570513733, 24561)
+brol16(53573, 24561)
+brol32(93191692570513733, 3384295305723863025)
+brol32(3283013957, 3384295305723863025)
+brol32(93191692570513733, 1488019441)
+brol32(3283013957, 1488019441)
+brol64(93191692570513733, 3384295305723863025)
+bror8(93191692570513733, 3384295305723863025)
+bror8(69, 3384295305723863025)
+bror8(93191692570513733, 241)
+bror8(69, 241)
+bror16(93191692570513733, 3384295305723863025)
+bror16(53573, 3384295305723863025)
+bror16(93191692570513733, 24561)
+bror16(53573, 24561)
+bror32(93191692570513733, 3384295305723863025)
+bror32(3283013957, 3384295305723863025)
+bror32(93191692570513733, 1488019441)
+bror32(3283013957, 1488019441)
+bror64(93191692570513733, 3384295305723863025)
+bmod8(93191692570513733)
+bmod8(69)
+bmod16(93191692570513733)
+bmod16(53573)
+bmod32(93191692570513733)
+bmod32(3283013957)
+bmod64(93191692570513733)
+band(8326778086807755591, 7987389489596803624)
+bor(8326778086807755591, 7987389489596803624)
+bxor(8326778086807755591, 7987389489596803624)
+bshl(2209274695, 8)
+bshr(2209274695, 8)
+bshl(4196084264, 7)
+bshr(4196084264, 7)
+bnot8(8326778086807755591)
+bnot8(71)
+bnot16(8326778086807755591)
+bnot16(56135)
+bnot32(8326778086807755591)
+bnot32(2209274695)
+bnot64(8326778086807755591)
+brev8(8326778086807755591)
+brev8(71)
+brev16(8326778086807755591)
+brev16(56135)
+brev32(8326778086807755591)
+brev32(2209274695)
+brev64(8326778086807755591)
+brol8(8326778086807755591, 7987389489596803624)
+brol8(71, 7987389489596803624)
+brol8(8326778086807755591, 40)
+brol8(71, 40)
+brol16(8326778086807755591, 7987389489596803624)
+brol16(56135, 7987389489596803624)
+brol16(8326778086807755591, 10792)
+brol16(56135, 10792)
+brol32(8326778086807755591, 7987389489596803624)
+brol32(2209274695, 7987389489596803624)
+brol32(8326778086807755591, 4196084264)
+brol32(2209274695, 4196084264)
+brol64(8326778086807755591, 7987389489596803624)
+bror8(8326778086807755591, 7987389489596803624)
+bror8(71, 7987389489596803624)
+bror8(8326778086807755591, 40)
+bror8(71, 40)
+bror16(8326778086807755591, 7987389489596803624)
+bror16(56135, 7987389489596803624)
+bror16(8326778086807755591, 10792)
+bror16(56135, 10792)
+bror32(8326778086807755591, 7987389489596803624)
+bror32(2209274695, 7987389489596803624)
+bror32(8326778086807755591, 4196084264)
+bror32(2209274695, 4196084264)
+bror64(8326778086807755591, 7987389489596803624)
+bmod8(8326778086807755591)
+bmod8(71)
+bmod16(8326778086807755591)
+bmod16(56135)
+bmod32(8326778086807755591)
+bmod32(2209274695)
+bmod64(8326778086807755591)
+band(14364725877905444575, 16535693317026586781)
+bor(14364725877905444575, 16535693317026586781)
+bxor(14364725877905444575, 16535693317026586781)
+bshl(275402463, 29)
+bshr(275402463, 29)
+bshl(1143709853, 31)
+bshr(1143709853, 31)
+bnot8(14364725877905444575)
+bnot8(223)
+bnot16(14364725877905444575)
+bnot16(20191)
+bnot32(14364725877905444575)
+bnot32(275402463)
+bnot64(14364725877905444575)
+brev8(14364725877905444575)
+brev8(223)
+brev16(14364725877905444575)
+brev16(20191)
+brev32(14364725877905444575)
+brev32(275402463)
+brev64(14364725877905444575)
+brol8(14364725877905444575, 16535693317026586781)
+brol8(223, 16535693317026586781)
+brol8(14364725877905444575, 157)
+brol8(223, 157)
+brol16(14364725877905444575, 16535693317026586781)
+brol16(20191, 16535693317026586781)
+brol16(14364725877905444575, 41117)
+brol16(20191, 41117)
+brol32(14364725877905444575, 16535693317026586781)
+brol32(275402463, 16535693317026586781)
+brol32(14364725877905444575, 1143709853)
+brol32(275402463, 1143709853)
+brol64(14364725877905444575, 16535693317026586781)
+bror8(14364725877905444575, 16535693317026586781)
+bror8(223, 16535693317026586781)
+bror8(14364725877905444575, 157)
+bror8(223, 157)
+bror16(14364725877905444575, 16535693317026586781)
+bror16(20191, 16535693317026586781)
+bror16(14364725877905444575, 41117)
+bror16(20191, 41117)
+bror32(14364725877905444575, 16535693317026586781)
+bror32(275402463, 16535693317026586781)
+bror32(14364725877905444575, 1143709853)
+bror32(275402463, 1143709853)
+bror64(14364725877905444575, 16535693317026586781)
+bmod8(14364725877905444575)
+bmod8(223)
+bmod16(14364725877905444575)
+bmod16(20191)
+bmod32(14364725877905444575)
+bmod32(275402463)
+bmod64(14364725877905444575)
+band(4319720279216833138, 5581390398328313816)
+bor(4319720279216833138, 5581390398328313816)
+bxor(4319720279216833138, 5581390398328313816)
+bshl(63259250, 24)
+bshr(63259250, 24)
+bshl(3978467288, 18)
+bshr(3978467288, 18)
+bnot8(4319720279216833138)
+bnot8(114)
+bnot16(4319720279216833138)
+bnot16(17010)
+bnot32(4319720279216833138)
+bnot32(63259250)
+bnot64(4319720279216833138)
+brev8(4319720279216833138)
+brev8(114)
+brev16(4319720279216833138)
+brev16(17010)
+brev32(4319720279216833138)
+brev32(63259250)
+brev64(4319720279216833138)
+brol8(4319720279216833138, 5581390398328313816)
+brol8(114, 5581390398328313816)
+brol8(4319720279216833138, 216)
+brol8(114, 216)
+brol16(4319720279216833138, 5581390398328313816)
+brol16(17010, 5581390398328313816)
+brol16(4319720279216833138, 38872)
+brol16(17010, 38872)
+brol32(4319720279216833138, 5581390398328313816)
+brol32(63259250, 5581390398328313816)
+brol32(4319720279216833138, 3978467288)
+brol32(63259250, 3978467288)
+brol64(4319720279216833138, 5581390398328313816)
+bror8(4319720279216833138, 5581390398328313816)
+bror8(114, 5581390398328313816)
+bror8(4319720279216833138, 216)
+bror8(114, 216)
+bror16(4319720279216833138, 5581390398328313816)
+bror16(17010, 5581390398328313816)
+bror16(4319720279216833138, 38872)
+bror16(17010, 38872)
+bror32(4319720279216833138, 5581390398328313816)
+bror32(63259250, 5581390398328313816)
+bror32(4319720279216833138, 3978467288)
+bror32(63259250, 3978467288)
+bror64(4319720279216833138, 5581390398328313816)
+bmod8(4319720279216833138)
+bmod8(114)
+bmod16(4319720279216833138)
+bmod16(17010)
+bmod32(4319720279216833138)
+bmod32(63259250)
+bmod64(4319720279216833138)
+band(3496752655100391517, 7973250688758961256)
+bor(3496752655100391517, 7973250688758961256)
+bxor(3496752655100391517, 7973250688758961256)
+bshl(1655287901, 8)
+bshr(1655287901, 8)
+bshl(3768439912, 29)
+bshr(3768439912, 29)
+bnot8(3496752655100391517)
+bnot8(93)
+bnot16(3496752655100391517)
+bnot16(45149)
+bnot32(3496752655100391517)
+bnot32(1655287901)
+bnot64(3496752655100391517)
+brev8(3496752655100391517)
+brev8(93)
+brev16(3496752655100391517)
+brev16(45149)
+brev32(3496752655100391517)
+brev32(1655287901)
+brev64(3496752655100391517)
+brol8(3496752655100391517, 7973250688758961256)
+brol8(93, 7973250688758961256)
+brol8(3496752655100391517, 104)
+brol8(93, 104)
+brol16(3496752655100391517, 7973250688758961256)
+brol16(45149, 7973250688758961256)
+brol16(3496752655100391517, 54376)
+brol16(45149, 54376)
+brol32(3496752655100391517, 7973250688758961256)
+brol32(1655287901, 7973250688758961256)
+brol32(3496752655100391517, 3768439912)
+brol32(1655287901, 3768439912)
+brol64(3496752655100391517, 7973250688758961256)
+bror8(3496752655100391517, 7973250688758961256)
+bror8(93, 7973250688758961256)
+bror8(3496752655100391517, 104)
+bror8(93, 104)
+bror16(3496752655100391517, 7973250688758961256)
+bror16(45149, 7973250688758961256)
+bror16(3496752655100391517, 54376)
+bror16(45149, 54376)
+bror32(3496752655100391517, 7973250688758961256)
+bror32(1655287901, 7973250688758961256)
+bror32(3496752655100391517, 3768439912)
+bror32(1655287901, 3768439912)
+bror64(3496752655100391517, 7973250688758961256)
+bmod8(3496752655100391517)
+bmod8(93)
+bmod16(3496752655100391517)
+bmod16(45149)
+bmod32(3496752655100391517)
+bmod32(1655287901)
+bmod64(3496752655100391517)
+band(17407952358526426619, 4067569790606708517)
+bor(17407952358526426619, 4067569790606708517)
+bxor(17407952358526426619, 4067569790606708517)
+bshl(1424236027, 5)
+bshr(1424236027, 5)
+bshl(1949896485, 27)
+bshr(1949896485, 27)
+bnot8(17407952358526426619)
+bnot8(251)
+bnot16(17407952358526426619)
+bnot16(7675)
+bnot32(17407952358526426619)
+bnot32(1424236027)
+bnot64(17407952358526426619)
+brev8(17407952358526426619)
+brev8(251)
+brev16(17407952358526426619)
+brev16(7675)
+brev32(17407952358526426619)
+brev32(1424236027)
+brev64(17407952358526426619)
+brol8(17407952358526426619, 4067569790606708517)
+brol8(251, 4067569790606708517)
+brol8(17407952358526426619, 37)
+brol8(251, 37)
+brol16(17407952358526426619, 4067569790606708517)
+brol16(7675, 4067569790606708517)
+brol16(17407952358526426619, 3877)
+brol16(7675, 3877)
+brol32(17407952358526426619, 4067569790606708517)
+brol32(1424236027, 4067569790606708517)
+brol32(17407952358526426619, 1949896485)
+brol32(1424236027, 1949896485)
+brol64(17407952358526426619, 4067569790606708517)
+bror8(17407952358526426619, 4067569790606708517)
+bror8(251, 4067569790606708517)
+bror8(17407952358526426619, 37)
+bror8(251, 37)
+bror16(17407952358526426619, 4067569790606708517)
+bror16(7675, 4067569790606708517)
+bror16(17407952358526426619, 3877)
+bror16(7675, 3877)
+bror32(17407952358526426619, 4067569790606708517)
+bror32(1424236027, 4067569790606708517)
+bror32(17407952358526426619, 1949896485)
+bror32(1424236027, 1949896485)
+bror64(17407952358526426619, 4067569790606708517)
+bmod8(17407952358526426619)
+bmod8(251)
+bmod16(17407952358526426619)
+bmod16(7675)
+bmod32(17407952358526426619)
+bmod32(1424236027)
+bmod64(17407952358526426619)
+band(8365218566998696193, 18255222596950068455)
+bor(8365218566998696193, 18255222596950068455)
+bxor(8365218566998696193, 18255222596950068455)
+bshl(1115005185, 7)
+bshr(1115005185, 7)
+bshl(1256492263, 1)
+bshr(1256492263, 1)
+bnot8(8365218566998696193)
+bnot8(1)
+bnot16(8365218566998696193)
+bnot16(41217)
+bnot32(8365218566998696193)
+bnot32(1115005185)
+bnot64(8365218566998696193)
+brev8(8365218566998696193)
+brev8(1)
+brev16(8365218566998696193)
+brev16(41217)
+brev32(8365218566998696193)
+brev32(1115005185)
+brev64(8365218566998696193)
+brol8(8365218566998696193, 18255222596950068455)
+brol8(1, 18255222596950068455)
+brol8(8365218566998696193, 231)
+brol8(1, 231)
+brol16(8365218566998696193, 18255222596950068455)
+brol16(41217, 18255222596950068455)
+brol16(8365218566998696193, 36071)
+brol16(41217, 36071)
+brol32(8365218566998696193, 18255222596950068455)
+brol32(1115005185, 18255222596950068455)
+brol32(8365218566998696193, 1256492263)
+brol32(1115005185, 1256492263)
+brol64(8365218566998696193, 18255222596950068455)
+bror8(8365218566998696193, 18255222596950068455)
+bror8(1, 18255222596950068455)
+bror8(8365218566998696193, 231)
+bror8(1, 231)
+bror16(8365218566998696193, 18255222596950068455)
+bror16(41217, 18255222596950068455)
+bror16(8365218566998696193, 36071)
+bror16(41217, 36071)
+bror32(8365218566998696193, 18255222596950068455)
+bror32(1115005185, 18255222596950068455)
+bror32(8365218566998696193, 1256492263)
+bror32(1115005185, 1256492263)
+bror64(8365218566998696193, 18255222596950068455)
+bmod8(8365218566998696193)
+bmod8(1)
+bmod16(8365218566998696193)
+bmod16(41217)
+bmod32(8365218566998696193)
+bmod32(1115005185)
+bmod64(8365218566998696193)
+band(8995800124880876730, 4240248420548714222)
+bor(8995800124880876730, 4240248420548714222)
+bxor(8995800124880876730, 4240248420548714222)
+bshl(1106277562, 14)
+bshr(1106277562, 14)
+bshl(37199598, 26)
+bshr(37199598, 26)
+bnot8(8995800124880876730)
+bnot8(186)
+bnot16(8995800124880876730)
+bnot16(29882)
+bnot32(8995800124880876730)
+bnot32(1106277562)
+bnot64(8995800124880876730)
+brev8(8995800124880876730)
+brev8(186)
+brev16(8995800124880876730)
+brev16(29882)
+brev32(8995800124880876730)
+brev32(1106277562)
+brev64(8995800124880876730)
+brol8(8995800124880876730, 4240248420548714222)
+brol8(186, 4240248420548714222)
+brol8(8995800124880876730, 238)
+brol8(186, 238)
+brol16(8995800124880876730, 4240248420548714222)
+brol16(29882, 4240248420548714222)
+brol16(8995800124880876730, 40686)
+brol16(29882, 40686)
+brol32(8995800124880876730, 4240248420548714222)
+brol32(1106277562, 4240248420548714222)
+brol32(8995800124880876730, 37199598)
+brol32(1106277562, 37199598)
+brol64(8995800124880876730, 4240248420548714222)
+bror8(8995800124880876730, 4240248420548714222)
+bror8(186, 4240248420548714222)
+bror8(8995800124880876730, 238)
+bror8(186, 238)
+bror16(8995800124880876730, 4240248420548714222)
+bror16(29882, 4240248420548714222)
+bror16(8995800124880876730, 40686)
+bror16(29882, 40686)
+bror32(8995800124880876730, 4240248420548714222)
+bror32(1106277562, 4240248420548714222)
+bror32(8995800124880876730, 37199598)
+bror32(1106277562, 37199598)
+bror64(8995800124880876730, 4240248420548714222)
+bmod8(8995800124880876730)
+bmod8(186)
+bmod16(8995800124880876730)
+bmod16(29882)
+bmod32(8995800124880876730)
+bmod32(1106277562)
+bmod64(8995800124880876730)
+band(12108174150119532902, 14659823650723275973)
+bor(12108174150119532902, 14659823650723275973)
+bxor(12108174150119532902, 14659823650723275973)
+bshl(3631294822, 5)
+bshr(3631294822, 5)
+bshl(1933255877, 6)
+bshr(1933255877, 6)
+bnot8(12108174150119532902)
+bnot8(102)
+bnot16(12108174150119532902)
+bnot16(10598)
+bnot32(12108174150119532902)
+bnot32(3631294822)
+bnot64(12108174150119532902)
+brev8(12108174150119532902)
+brev8(102)
+brev16(12108174150119532902)
+brev16(10598)
+brev32(12108174150119532902)
+brev32(3631294822)
+brev64(12108174150119532902)
+brol8(12108174150119532902, 14659823650723275973)
+brol8(102, 14659823650723275973)
+brol8(12108174150119532902, 197)
+brol8(102, 197)
+brol16(12108174150119532902, 14659823650723275973)
+brol16(10598, 14659823650723275973)
+brol16(12108174150119532902, 9413)
+brol16(10598, 9413)
+brol32(12108174150119532902, 14659823650723275973)
+brol32(3631294822, 14659823650723275973)
+brol32(12108174150119532902, 1933255877)
+brol32(3631294822, 1933255877)
+brol64(12108174150119532902, 14659823650723275973)
+bror8(12108174150119532902, 14659823650723275973)
+bror8(102, 14659823650723275973)
+bror8(12108174150119532902, 197)
+bror8(102, 197)
+bror16(12108174150119532902, 14659823650723275973)
+bror16(10598, 14659823650723275973)
+bror16(12108174150119532902, 9413)
+bror16(10598, 9413)
+bror32(12108174150119532902, 14659823650723275973)
+bror32(3631294822, 14659823650723275973)
+bror32(12108174150119532902, 1933255877)
+bror32(3631294822, 1933255877)
+bror64(12108174150119532902, 14659823650723275973)
+bmod8(12108174150119532902)
+bmod8(102)
+bmod16(12108174150119532902)
+bmod16(10598)
+bmod32(12108174150119532902)
+bmod32(3631294822)
+bmod64(12108174150119532902)
+band(9152871333191109426, 6603868971069029717)
+bor(9152871333191109426, 6603868971069029717)
+bxor(9152871333191109426, 6603868971069029717)
+bshl(3384167218, 21)
+bshr(3384167218, 21)
+bshl(600522069, 18)
+bshr(600522069, 18)
+bnot8(9152871333191109426)
+bnot8(50)
+bnot16(9152871333191109426)
+bnot16(19250)
+bnot32(9152871333191109426)
+bnot32(3384167218)
+bnot64(9152871333191109426)
+brev8(9152871333191109426)
+brev8(50)
+brev16(9152871333191109426)
+brev16(19250)
+brev32(9152871333191109426)
+brev32(3384167218)
+brev64(9152871333191109426)
+brol8(9152871333191109426, 6603868971069029717)
+brol8(50, 6603868971069029717)
+brol8(9152871333191109426, 85)
+brol8(50, 85)
+brol16(9152871333191109426, 6603868971069029717)
+brol16(19250, 6603868971069029717)
+brol16(9152871333191109426, 15701)
+brol16(19250, 15701)
+brol32(9152871333191109426, 6603868971069029717)
+brol32(3384167218, 6603868971069029717)
+brol32(9152871333191109426, 600522069)
+brol32(3384167218, 600522069)
+brol64(9152871333191109426, 6603868971069029717)
+bror8(9152871333191109426, 6603868971069029717)
+bror8(50, 6603868971069029717)
+bror8(9152871333191109426, 85)
+bror8(50, 85)
+bror16(9152871333191109426, 6603868971069029717)
+bror16(19250, 6603868971069029717)
+bror16(9152871333191109426, 15701)
+bror16(19250, 15701)
+bror32(9152871333191109426, 6603868971069029717)
+bror32(3384167218, 6603868971069029717)
+bror32(9152871333191109426, 600522069)
+bror32(3384167218, 600522069)
+bror64(9152871333191109426, 6603868971069029717)
+bmod8(9152871333191109426)
+bmod8(50)
+bmod16(9152871333191109426)
+bmod16(19250)
+bmod32(9152871333191109426)
+bmod32(3384167218)
+bmod64(9152871333191109426)
+band(5636056131682700640, 1080456952844432388)
+bor(5636056131682700640, 1080456952844432388)
+bxor(5636056131682700640, 1080456952844432388)
+bshl(3474722144, 4)
+bshr(3474722144, 4)
+bshl(3311711236, 0)
+bshr(3311711236, 0)
+bnot8(5636056131682700640)
+bnot8(96)
+bnot16(5636056131682700640)
+bnot16(3424)
+bnot32(5636056131682700640)
+bnot32(3474722144)
+bnot64(5636056131682700640)
+brev8(5636056131682700640)
+brev8(96)
+brev16(5636056131682700640)
+brev16(3424)
+brev32(5636056131682700640)
+brev32(3474722144)
+brev64(5636056131682700640)
+brol8(5636056131682700640, 1080456952844432388)
+brol8(96, 1080456952844432388)
+brol8(5636056131682700640, 4)
+brol8(96, 4)
+brol16(5636056131682700640, 1080456952844432388)
+brol16(3424, 1080456952844432388)
+brol16(5636056131682700640, 46084)
+brol16(3424, 46084)
+brol32(5636056131682700640, 1080456952844432388)
+brol32(3474722144, 1080456952844432388)
+brol32(5636056131682700640, 3311711236)
+brol32(3474722144, 3311711236)
+brol64(5636056131682700640, 1080456952844432388)
+bror8(5636056131682700640, 1080456952844432388)
+bror8(96, 1080456952844432388)
+bror8(5636056131682700640, 4)
+bror8(96, 4)
+bror16(5636056131682700640, 1080456952844432388)
+bror16(3424, 1080456952844432388)
+bror16(5636056131682700640, 46084)
+bror16(3424, 46084)
+bror32(5636056131682700640, 1080456952844432388)
+bror32(3474722144, 1080456952844432388)
+bror32(5636056131682700640, 3311711236)
+bror32(3474722144, 3311711236)
+bror64(5636056131682700640, 1080456952844432388)
+bmod8(5636056131682700640)
+bmod8(96)
+bmod16(5636056131682700640)
+bmod16(3424)
+bmod32(5636056131682700640)
+bmod32(3474722144)
+bmod64(5636056131682700640)
+band(7937423473278223162, 9112819379003219710)
+bor(7937423473278223162, 9112819379003219710)
+bxor(7937423473278223162, 9112819379003219710)
+bshl(1016628026, 30)
+bshr(1016628026, 30)
+bshl(2210946814, 26)
+bshr(2210946814, 26)
+bnot8(7937423473278223162)
+bnot8(58)
+bnot16(7937423473278223162)
+bnot16(33594)
+bnot32(7937423473278223162)
+bnot32(1016628026)
+bnot64(7937423473278223162)
+brev8(7937423473278223162)
+brev8(58)
+brev16(7937423473278223162)
+brev16(33594)
+brev32(7937423473278223162)
+brev32(1016628026)
+brev64(7937423473278223162)
+brol8(7937423473278223162, 9112819379003219710)
+brol8(58, 9112819379003219710)
+brol8(7937423473278223162, 254)
+brol8(58, 254)
+brol16(7937423473278223162, 9112819379003219710)
+brol16(33594, 9112819379003219710)
+brol16(7937423473278223162, 24318)
+brol16(33594, 24318)
+brol32(7937423473278223162, 9112819379003219710)
+brol32(1016628026, 9112819379003219710)
+brol32(7937423473278223162, 2210946814)
+brol32(1016628026, 2210946814)
+brol64(7937423473278223162, 9112819379003219710)
+bror8(7937423473278223162, 9112819379003219710)
+bror8(58, 9112819379003219710)
+bror8(7937423473278223162, 254)
+bror8(58, 254)
+bror16(7937423473278223162, 9112819379003219710)
+bror16(33594, 9112819379003219710)
+bror16(7937423473278223162, 24318)
+bror16(33594, 24318)
+bror32(7937423473278223162, 9112819379003219710)
+bror32(1016628026, 9112819379003219710)
+bror32(7937423473278223162, 2210946814)
+bror32(1016628026, 2210946814)
+bror64(7937423473278223162, 9112819379003219710)
+bmod8(7937423473278223162)
+bmod8(58)
+bmod16(7937423473278223162)
+bmod16(33594)
+bmod32(7937423473278223162)
+bmod32(1016628026)
+bmod64(7937423473278223162)
+band(143047368094082620, 16334675985380291499)
+bor(143047368094082620, 16334675985380291499)
+bxor(143047368094082620, 16334675985380291499)
+bshl(3377292860, 11)
+bshr(3377292860, 11)
+bshl(2377266091, 28)
+bshr(2377266091, 28)
+bnot8(143047368094082620)
+bnot8(60)
+bnot16(143047368094082620)
+bnot16(26172)
+bnot32(143047368094082620)
+bnot32(3377292860)
+bnot64(143047368094082620)
+brev8(143047368094082620)
+brev8(60)
+brev16(143047368094082620)
+brev16(26172)
+brev32(143047368094082620)
+brev32(3377292860)
+brev64(143047368094082620)
+brol8(143047368094082620, 16334675985380291499)
+brol8(60, 16334675985380291499)
+brol8(143047368094082620, 171)
+brol8(60, 171)
+brol16(143047368094082620, 16334675985380291499)
+brol16(26172, 16334675985380291499)
+brol16(143047368094082620, 13227)
+brol16(26172, 13227)
+brol32(143047368094082620, 16334675985380291499)
+brol32(3377292860, 16334675985380291499)
+brol32(143047368094082620, 2377266091)
+brol32(3377292860, 2377266091)
+brol64(143047368094082620, 16334675985380291499)
+bror8(143047368094082620, 16334675985380291499)
+bror8(60, 16334675985380291499)
+bror8(143047368094082620, 171)
+bror8(60, 171)
+bror16(143047368094082620, 16334675985380291499)
+bror16(26172, 16334675985380291499)
+bror16(143047368094082620, 13227)
+bror16(26172, 13227)
+bror32(143047368094082620, 16334675985380291499)
+bror32(3377292860, 16334675985380291499)
+bror32(143047368094082620, 2377266091)
+bror32(3377292860, 2377266091)
+bror64(143047368094082620, 16334675985380291499)
+bmod8(143047368094082620)
+bmod8(60)
+bmod16(143047368094082620)
+bmod16(26172)
+bmod32(143047368094082620)
+bmod32(3377292860)
+bmod64(143047368094082620)
+band(14223149998491302938, 13151589259246694372)
+bor(14223149998491302938, 13151589259246694372)
+bxor(14223149998491302938, 13151589259246694372)
+bshl(4012637210, 4)
+bshr(4012637210, 4)
+bshl(1295904740, 26)
+bshr(1295904740, 26)
+bnot8(14223149998491302938)
+bnot8(26)
+bnot16(14223149998491302938)
+bnot16(64538)
+bnot32(14223149998491302938)
+bnot32(4012637210)
+bnot64(14223149998491302938)
+brev8(14223149998491302938)
+brev8(26)
+brev16(14223149998491302938)
+brev16(64538)
+brev32(14223149998491302938)
+brev32(4012637210)
+brev64(14223149998491302938)
+brol8(14223149998491302938, 13151589259246694372)
+brol8(26, 13151589259246694372)
+brol8(14223149998491302938, 228)
+brol8(26, 228)
+brol16(14223149998491302938, 13151589259246694372)
+brol16(64538, 13151589259246694372)
+brol16(14223149998491302938, 61412)
+brol16(64538, 61412)
+brol32(14223149998491302938, 13151589259246694372)
+brol32(4012637210, 13151589259246694372)
+brol32(14223149998491302938, 1295904740)
+brol32(4012637210, 1295904740)
+brol64(14223149998491302938, 13151589259246694372)
+bror8(14223149998491302938, 13151589259246694372)
+bror8(26, 13151589259246694372)
+bror8(14223149998491302938, 228)
+bror8(26, 228)
+bror16(14223149998491302938, 13151589259246694372)
+bror16(64538, 13151589259246694372)
+bror16(14223149998491302938, 61412)
+bror16(64538, 61412)
+bror32(14223149998491302938, 13151589259246694372)
+bror32(4012637210, 13151589259246694372)
+bror32(14223149998491302938, 1295904740)
+bror32(4012637210, 1295904740)
+bror64(14223149998491302938, 13151589259246694372)
+bmod8(14223149998491302938)
+bmod8(26)
+bmod16(14223149998491302938)
+bmod16(64538)
+bmod32(14223149998491302938)
+bmod32(4012637210)
+bmod64(14223149998491302938)
+band(98935896299790646, 13979467586534974274)
+bor(98935896299790646, 13979467586534974274)
+bxor(98935896299790646, 13979467586534974274)
+bshl(1786503478, 2)
+bshr(1786503478, 2)
+bshl(478225218, 22)
+bshr(478225218, 22)
+bnot8(98935896299790646)
+bnot8(54)
+bnot16(98935896299790646)
+bnot16(57654)
+bnot32(98935896299790646)
+bnot32(1786503478)
+bnot64(98935896299790646)
+brev8(98935896299790646)
+brev8(54)
+brev16(98935896299790646)
+brev16(57654)
+brev32(98935896299790646)
+brev32(1786503478)
+brev64(98935896299790646)
+brol8(98935896299790646, 13979467586534974274)
+brol8(54, 13979467586534974274)
+brol8(98935896299790646, 66)
+brol8(54, 66)
+brol16(98935896299790646, 13979467586534974274)
+brol16(57654, 13979467586534974274)
+brol16(98935896299790646, 9026)
+brol16(57654, 9026)
+brol32(98935896299790646, 13979467586534974274)
+brol32(1786503478, 13979467586534974274)
+brol32(98935896299790646, 478225218)
+brol32(1786503478, 478225218)
+brol64(98935896299790646, 13979467586534974274)
+bror8(98935896299790646, 13979467586534974274)
+bror8(54, 13979467586534974274)
+bror8(98935896299790646, 66)
+bror8(54, 66)
+bror16(98935896299790646, 13979467586534974274)
+bror16(57654, 13979467586534974274)
+bror16(98935896299790646, 9026)
+bror16(57654, 9026)
+bror32(98935896299790646, 13979467586534974274)
+bror32(1786503478, 13979467586534974274)
+bror32(98935896299790646, 478225218)
+bror32(1786503478, 478225218)
+bror64(98935896299790646, 13979467586534974274)
+bmod8(98935896299790646)
+bmod8(54)
+bmod16(98935896299790646)
+bmod16(57654)
+bmod32(98935896299790646)
+bmod32(1786503478)
+bmod64(98935896299790646)
+band(4017354977208507464, 8620949576054669191)
+bor(4017354977208507464, 8620949576054669191)
+bxor(4017354977208507464, 8620949576054669191)
+bshl(556342344, 7)
+bshr(556342344, 7)
+bshl(3008036743, 8)
+bshr(3008036743, 8)
+bnot8(4017354977208507464)
+bnot8(72)
+bnot16(4017354977208507464)
+bnot16(7240)
+bnot32(4017354977208507464)
+bnot32(556342344)
+bnot64(4017354977208507464)
+brev8(4017354977208507464)
+brev8(72)
+brev16(4017354977208507464)
+brev16(7240)
+brev32(4017354977208507464)
+brev32(556342344)
+brev64(4017354977208507464)
+brol8(4017354977208507464, 8620949576054669191)
+brol8(72, 8620949576054669191)
+brol8(4017354977208507464, 135)
+brol8(72, 135)
+brol16(4017354977208507464, 8620949576054669191)
+brol16(7240, 8620949576054669191)
+brol16(4017354977208507464, 65415)
+brol16(7240, 65415)
+brol32(4017354977208507464, 8620949576054669191)
+brol32(556342344, 8620949576054669191)
+brol32(4017354977208507464, 3008036743)
+brol32(556342344, 3008036743)
+brol64(4017354977208507464, 8620949576054669191)
+bror8(4017354977208507464, 8620949576054669191)
+bror8(72, 8620949576054669191)
+bror8(4017354977208507464, 135)
+bror8(72, 135)
+bror16(4017354977208507464, 8620949576054669191)
+bror16(7240, 8620949576054669191)
+bror16(4017354977208507464, 65415)
+bror16(7240, 65415)
+bror32(4017354977208507464, 8620949576054669191)
+bror32(556342344, 8620949576054669191)
+bror32(4017354977208507464, 3008036743)
+bror32(556342344, 3008036743)
+bror64(4017354977208507464, 8620949576054669191)
+bmod8(4017354977208507464)
+bmod8(72)
+bmod16(4017354977208507464)
+bmod16(7240)
+bmod32(4017354977208507464)
+bmod32(556342344)
+bmod64(4017354977208507464)
+band(8304950363193512478, 15051849109441255523)
+bor(8304950363193512478, 15051849109441255523)
+bxor(8304950363193512478, 15051849109441255523)
+bshl(2472972830, 3)
+bshr(2472972830, 3)
+bshl(1426495587, 30)
+bshr(1426495587, 30)
+bnot8(8304950363193512478)
+bnot8(30)
+bnot16(8304950363193512478)
+bnot16(37406)
+bnot32(8304950363193512478)
+bnot32(2472972830)
+bnot64(8304950363193512478)
+brev8(8304950363193512478)
+brev8(30)
+brev16(8304950363193512478)
+brev16(37406)
+brev32(8304950363193512478)
+brev32(2472972830)
+brev64(8304950363193512478)
+brol8(8304950363193512478, 15051849109441255523)
+brol8(30, 15051849109441255523)
+brol8(8304950363193512478, 99)
+brol8(30, 99)
+brol16(8304950363193512478, 15051849109441255523)
+brol16(37406, 15051849109441255523)
+brol16(8304950363193512478, 39011)
+brol16(37406, 39011)
+brol32(8304950363193512478, 15051849109441255523)
+brol32(2472972830, 15051849109441255523)
+brol32(8304950363193512478, 1426495587)
+brol32(2472972830, 1426495587)
+brol64(8304950363193512478, 15051849109441255523)
+bror8(8304950363193512478, 15051849109441255523)
+bror8(30, 15051849109441255523)
+bror8(8304950363193512478, 99)
+bror8(30, 99)
+bror16(8304950363193512478, 15051849109441255523)
+bror16(37406, 15051849109441255523)
+bror16(8304950363193512478, 39011)
+bror16(37406, 39011)
+bror32(8304950363193512478, 15051849109441255523)
+bror32(2472972830, 15051849109441255523)
+bror32(8304950363193512478, 1426495587)
+bror32(2472972830, 1426495587)
+bror64(8304950363193512478, 15051849109441255523)
+bmod8(8304950363193512478)
+bmod8(30)
+bmod16(8304950363193512478)
+bmod16(37406)
+bmod32(8304950363193512478)
+bmod32(2472972830)
+bmod64(8304950363193512478)
+band(5205211806348135630, 17076521419717060835)
+bor(5205211806348135630, 17076521419717060835)
+bxor(5205211806348135630, 17076521419717060835)
+bshl(973917390, 3)
+bshr(973917390, 3)
+bshl(2241177827, 14)
+bshr(2241177827, 14)
+bnot8(5205211806348135630)
+bnot8(206)
+bnot16(5205211806348135630)
+bnot16(52430)
+bnot32(5205211806348135630)
+bnot32(973917390)
+bnot64(5205211806348135630)
+brev8(5205211806348135630)
+brev8(206)
+brev16(5205211806348135630)
+brev16(52430)
+brev32(5205211806348135630)
+brev32(973917390)
+brev64(5205211806348135630)
+brol8(5205211806348135630, 17076521419717060835)
+brol8(206, 17076521419717060835)
+brol8(5205211806348135630, 227)
+brol8(206, 227)
+brol16(5205211806348135630, 17076521419717060835)
+brol16(52430, 17076521419717060835)
+brol16(5205211806348135630, 43235)
+brol16(52430, 43235)
+brol32(5205211806348135630, 17076521419717060835)
+brol32(973917390, 17076521419717060835)
+brol32(5205211806348135630, 2241177827)
+brol32(973917390, 2241177827)
+brol64(5205211806348135630, 17076521419717060835)
+bror8(5205211806348135630, 17076521419717060835)
+bror8(206, 17076521419717060835)
+bror8(5205211806348135630, 227)
+bror8(206, 227)
+bror16(5205211806348135630, 17076521419717060835)
+bror16(52430, 17076521419717060835)
+bror16(5205211806348135630, 43235)
+bror16(52430, 43235)
+bror32(5205211806348135630, 17076521419717060835)
+bror32(973917390, 17076521419717060835)
+bror32(5205211806348135630, 2241177827)
+bror32(973917390, 2241177827)
+bror64(5205211806348135630, 17076521419717060835)
+bmod8(5205211806348135630)
+bmod8(206)
+bmod16(5205211806348135630)
+bmod16(52430)
+bmod32(5205211806348135630)
+bmod32(973917390)
+bmod64(5205211806348135630)
+band(16527427662727213300, 6651564814332221722)
+bor(16527427662727213300, 6651564814332221722)
+bxor(16527427662727213300, 6651564814332221722)
+bshl(2815553780, 26)
+bshr(2815553780, 26)
+bshl(113400090, 20)
+bshr(113400090, 20)
+bnot8(16527427662727213300)
+bnot8(244)
+bnot16(16527427662727213300)
+bnot16(61684)
+bnot32(16527427662727213300)
+bnot32(2815553780)
+bnot64(16527427662727213300)
+brev8(16527427662727213300)
+brev8(244)
+brev16(16527427662727213300)
+brev16(61684)
+brev32(16527427662727213300)
+brev32(2815553780)
+brev64(16527427662727213300)
+brol8(16527427662727213300, 6651564814332221722)
+brol8(244, 6651564814332221722)
+brol8(16527427662727213300, 26)
+brol8(244, 26)
+brol16(16527427662727213300, 6651564814332221722)
+brol16(61684, 6651564814332221722)
+brol16(16527427662727213300, 22810)
+brol16(61684, 22810)
+brol32(16527427662727213300, 6651564814332221722)
+brol32(2815553780, 6651564814332221722)
+brol32(16527427662727213300, 113400090)
+brol32(2815553780, 113400090)
+brol64(16527427662727213300, 6651564814332221722)
+bror8(16527427662727213300, 6651564814332221722)
+bror8(244, 6651564814332221722)
+bror8(16527427662727213300, 26)
+bror8(244, 26)
+bror16(16527427662727213300, 6651564814332221722)
+bror16(61684, 6651564814332221722)
+bror16(16527427662727213300, 22810)
+bror16(61684, 22810)
+bror32(16527427662727213300, 6651564814332221722)
+bror32(2815553780, 6651564814332221722)
+bror32(16527427662727213300, 113400090)
+bror32(2815553780, 113400090)
+bror64(16527427662727213300, 6651564814332221722)
+bmod8(16527427662727213300)
+bmod8(244)
+bmod16(16527427662727213300)
+bmod16(61684)
+bmod32(16527427662727213300)
+bmod32(2815553780)
+bmod64(16527427662727213300)
+band(10641840435022628295, 14479003063947080097)
+bor(10641840435022628295, 14479003063947080097)
+bxor(10641840435022628295, 14479003063947080097)
+bshl(636061127, 1)
+bshr(636061127, 1)
+bshl(3629887905, 7)
+bshr(3629887905, 7)
+bnot8(10641840435022628295)
+bnot8(199)
+bnot16(10641840435022628295)
+bnot16(34247)
+bnot32(10641840435022628295)
+bnot32(636061127)
+bnot64(10641840435022628295)
+brev8(10641840435022628295)
+brev8(199)
+brev16(10641840435022628295)
+brev16(34247)
+brev32(10641840435022628295)
+brev32(636061127)
+brev64(10641840435022628295)
+brol8(10641840435022628295, 14479003063947080097)
+brol8(199, 14479003063947080097)
+brol8(10641840435022628295, 161)
+brol8(199, 161)
+brol16(10641840435022628295, 14479003063947080097)
+brol16(34247, 14479003063947080097)
+brol16(10641840435022628295, 45473)
+brol16(34247, 45473)
+brol32(10641840435022628295, 14479003063947080097)
+brol32(636061127, 14479003063947080097)
+brol32(10641840435022628295, 3629887905)
+brol32(636061127, 3629887905)
+brol64(10641840435022628295, 14479003063947080097)
+bror8(10641840435022628295, 14479003063947080097)
+bror8(199, 14479003063947080097)
+bror8(10641840435022628295, 161)
+bror8(199, 161)
+bror16(10641840435022628295, 14479003063947080097)
+bror16(34247, 14479003063947080097)
+bror16(10641840435022628295, 45473)
+bror16(34247, 45473)
+bror32(10641840435022628295, 14479003063947080097)
+bror32(636061127, 14479003063947080097)
+bror32(10641840435022628295, 3629887905)
+bror32(636061127, 3629887905)
+bror64(10641840435022628295, 14479003063947080097)
+bmod8(10641840435022628295)
+bmod8(199)
+bmod16(10641840435022628295)
+bmod16(34247)
+bmod32(10641840435022628295)
+bmod32(636061127)
+bmod64(10641840435022628295)
+band(10499995539115098586, 4378185852725387803)
+bor(10499995539115098586, 4378185852725387803)
+bxor(10499995539115098586, 4378185852725387803)
+bshl(3156492762, 27)
+bshr(3156492762, 27)
+bshl(542532123, 26)
+bshr(542532123, 26)
+bnot8(10499995539115098586)
+bnot8(218)
+bnot16(10499995539115098586)
+bnot16(16858)
+bnot32(10499995539115098586)
+bnot32(3156492762)
+bnot64(10499995539115098586)
+brev8(10499995539115098586)
+brev8(218)
+brev16(10499995539115098586)
+brev16(16858)
+brev32(10499995539115098586)
+brev32(3156492762)
+brev64(10499995539115098586)
+brol8(10499995539115098586, 4378185852725387803)
+brol8(218, 4378185852725387803)
+brol8(10499995539115098586, 27)
+brol8(218, 27)
+brol16(10499995539115098586, 4378185852725387803)
+brol16(16858, 4378185852725387803)
+brol16(10499995539115098586, 25115)
+brol16(16858, 25115)
+brol32(10499995539115098586, 4378185852725387803)
+brol32(3156492762, 4378185852725387803)
+brol32(10499995539115098586, 542532123)
+brol32(3156492762, 542532123)
+brol64(10499995539115098586, 4378185852725387803)
+bror8(10499995539115098586, 4378185852725387803)
+bror8(218, 4378185852725387803)
+bror8(10499995539115098586, 27)
+bror8(218, 27)
+bror16(10499995539115098586, 4378185852725387803)
+bror16(16858, 4378185852725387803)
+bror16(10499995539115098586, 25115)
+bror16(16858, 25115)
+bror32(10499995539115098586, 4378185852725387803)
+bror32(3156492762, 4378185852725387803)
+bror32(10499995539115098586, 542532123)
+bror32(3156492762, 542532123)
+bror64(10499995539115098586, 4378185852725387803)
+bmod8(10499995539115098586)
+bmod8(218)
+bmod16(10499995539115098586)
+bmod16(16858)
+bmod32(10499995539115098586)
+bmod32(3156492762)
+bmod64(10499995539115098586)
+band(1074373130761247060, 11147165611049962914)
+bor(1074373130761247060, 11147165611049962914)
+bxor(1074373130761247060, 11147165611049962914)
+bshl(2403309908, 2)
+bshr(2403309908, 2)
+bshl(588598690, 20)
+bshr(588598690, 20)
+bnot8(1074373130761247060)
+bnot8(84)
+bnot16(1074373130761247060)
+bnot16(39252)
+bnot32(1074373130761247060)
+bnot32(2403309908)
+bnot64(1074373130761247060)
+brev8(1074373130761247060)
+brev8(84)
+brev16(1074373130761247060)
+brev16(39252)
+brev32(1074373130761247060)
+brev32(2403309908)
+brev64(1074373130761247060)
+brol8(1074373130761247060, 11147165611049962914)
+brol8(84, 11147165611049962914)
+brol8(1074373130761247060, 162)
+brol8(84, 162)
+brol16(1074373130761247060, 11147165611049962914)
+brol16(39252, 11147165611049962914)
+brol16(1074373130761247060, 19874)
+brol16(39252, 19874)
+brol32(1074373130761247060, 11147165611049962914)
+brol32(2403309908, 11147165611049962914)
+brol32(1074373130761247060, 588598690)
+brol32(2403309908, 588598690)
+brol64(1074373130761247060, 11147165611049962914)
+bror8(1074373130761247060, 11147165611049962914)
+bror8(84, 11147165611049962914)
+bror8(1074373130761247060, 162)
+bror8(84, 162)
+bror16(1074373130761247060, 11147165611049962914)
+bror16(39252, 11147165611049962914)
+bror16(1074373130761247060, 19874)
+bror16(39252, 19874)
+bror32(1074373130761247060, 11147165611049962914)
+bror32(2403309908, 11147165611049962914)
+bror32(1074373130761247060, 588598690)
+bror32(2403309908, 588598690)
+bror64(1074373130761247060, 11147165611049962914)
+bmod8(1074373130761247060)
+bmod8(84)
+bmod16(1074373130761247060)
+bmod16(39252)
+bmod32(1074373130761247060)
+bmod32(2403309908)
+bmod64(1074373130761247060)
+band(9995157125005836544, 3264042356568534592)
+bor(9995157125005836544, 3264042356568534592)
+bxor(9995157125005836544, 3264042356568534592)
+bshl(3593470208, 0)
+bshr(3593470208, 0)
+bshl(3407392320, 0)
+bshr(3407392320, 0)
+bnot8(9995157125005836544)
+bnot8(0)
+bnot16(9995157125005836544)
+bnot16(256)
+bnot32(9995157125005836544)
+bnot32(3593470208)
+bnot64(9995157125005836544)
+brev8(9995157125005836544)
+brev8(0)
+brev16(9995157125005836544)
+brev16(256)
+brev32(9995157125005836544)
+brev32(3593470208)
+brev64(9995157125005836544)
+brol8(9995157125005836544, 3264042356568534592)
+brol8(0, 3264042356568534592)
+brol8(9995157125005836544, 64)
+brol8(0, 64)
+brol16(9995157125005836544, 3264042356568534592)
+brol16(256, 3264042356568534592)
+brol16(9995157125005836544, 44608)
+brol16(256, 44608)
+brol32(9995157125005836544, 3264042356568534592)
+brol32(3593470208, 3264042356568534592)
+brol32(9995157125005836544, 3407392320)
+brol32(3593470208, 3407392320)
+brol64(9995157125005836544, 3264042356568534592)
+bror8(9995157125005836544, 3264042356568534592)
+bror8(0, 3264042356568534592)
+bror8(9995157125005836544, 64)
+bror8(0, 64)
+bror16(9995157125005836544, 3264042356568534592)
+bror16(256, 3264042356568534592)
+bror16(9995157125005836544, 44608)
+bror16(256, 44608)
+bror32(9995157125005836544, 3264042356568534592)
+bror32(3593470208, 3264042356568534592)
+bror32(9995157125005836544, 3407392320)
+bror32(3593470208, 3407392320)
+bror64(9995157125005836544, 3264042356568534592)
+bmod8(9995157125005836544)
+bmod8(0)
+bmod16(9995157125005836544)
+bmod16(256)
+bmod32(9995157125005836544)
+bmod32(3593470208)
+bmod64(9995157125005836544)
+band(15241630863703326018, 13606872635146951975)
+bor(15241630863703326018, 13606872635146951975)
+bxor(15241630863703326018, 13606872635146951975)
+bshl(1420475714, 7)
+bshr(1420475714, 7)
+bshl(3253394727, 2)
+bshr(3253394727, 2)
+bnot8(15241630863703326018)
+bnot8(66)
+bnot16(15241630863703326018)
+bnot16(48450)
+bnot32(15241630863703326018)
+bnot32(1420475714)
+bnot64(15241630863703326018)
+brev8(15241630863703326018)
+brev8(66)
+brev16(15241630863703326018)
+brev16(48450)
+brev32(15241630863703326018)
+brev32(1420475714)
+brev64(15241630863703326018)
+brol8(15241630863703326018, 13606872635146951975)
+brol8(66, 13606872635146951975)
+brol8(15241630863703326018, 39)
+brol8(66, 39)
+brol16(15241630863703326018, 13606872635146951975)
+brol16(48450, 13606872635146951975)
+brol16(15241630863703326018, 56615)
+brol16(48450, 56615)
+brol32(15241630863703326018, 13606872635146951975)
+brol32(1420475714, 13606872635146951975)
+brol32(15241630863703326018, 3253394727)
+brol32(1420475714, 3253394727)
+brol64(15241630863703326018, 13606872635146951975)
+bror8(15241630863703326018, 13606872635146951975)
+bror8(66, 13606872635146951975)
+bror8(15241630863703326018, 39)
+bror8(66, 39)
+bror16(15241630863703326018, 13606872635146951975)
+bror16(48450, 13606872635146951975)
+bror16(15241630863703326018, 56615)
+bror16(48450, 56615)
+bror32(15241630863703326018, 13606872635146951975)
+bror32(1420475714, 13606872635146951975)
+bror32(15241630863703326018, 3253394727)
+bror32(1420475714, 3253394727)
+bror64(15241630863703326018, 13606872635146951975)
+bmod8(15241630863703326018)
+bmod8(66)
+bmod16(15241630863703326018)
+bmod16(48450)
+bmod32(15241630863703326018)
+bmod32(1420475714)
+bmod64(15241630863703326018)
+band(17123813738935299022, 16096625453625248741)
+bor(17123813738935299022, 16096625453625248741)
+bxor(17123813738935299022, 16096625453625248741)
+bshl(2771463118, 5)
+bshr(2771463118, 5)
+bshl(98044901, 14)
+bshr(98044901, 14)
+bnot8(17123813738935299022)
+bnot8(206)
+bnot16(17123813738935299022)
+bnot16(11214)
+bnot32(17123813738935299022)
+bnot32(2771463118)
+bnot64(17123813738935299022)
+brev8(17123813738935299022)
+brev8(206)
+brev16(17123813738935299022)
+brev16(11214)
+brev32(17123813738935299022)
+brev32(2771463118)
+brev64(17123813738935299022)
+brol8(17123813738935299022, 16096625453625248741)
+brol8(206, 16096625453625248741)
+brol8(17123813738935299022, 229)
+brol8(206, 229)
+brol16(17123813738935299022, 16096625453625248741)
+brol16(11214, 16096625453625248741)
+brol16(17123813738935299022, 3045)
+brol16(11214, 3045)
+brol32(17123813738935299022, 16096625453625248741)
+brol32(2771463118, 16096625453625248741)
+brol32(17123813738935299022, 98044901)
+brol32(2771463118, 98044901)
+brol64(17123813738935299022, 16096625453625248741)
+bror8(17123813738935299022, 16096625453625248741)
+bror8(206, 16096625453625248741)
+bror8(17123813738935299022, 229)
+bror8(206, 229)
+bror16(17123813738935299022, 16096625453625248741)
+bror16(11214, 16096625453625248741)
+bror16(17123813738935299022, 3045)
+bror16(11214, 3045)
+bror32(17123813738935299022, 16096625453625248741)
+bror32(2771463118, 16096625453625248741)
+bror32(17123813738935299022, 98044901)
+bror32(2771463118, 98044901)
+bror64(17123813738935299022, 16096625453625248741)
+bmod8(17123813738935299022)
+bmod8(206)
+bmod16(17123813738935299022)
+bmod16(11214)
+bmod32(17123813738935299022)
+bmod32(2771463118)
+bmod64(17123813738935299022)
+band(4746555852716517511, 1377312048802829031)
+bor(4746555852716517511, 1377312048802829031)
+bxor(4746555852716517511, 1377312048802829031)
+bshl(1404577927, 7)
+bshr(1404577927, 7)
+bshl(3586265831, 7)
+bshr(3586265831, 7)
+bnot8(4746555852716517511)
+bnot8(135)
+bnot16(4746555852716517511)
+bnot16(10375)
+bnot32(4746555852716517511)
+bnot32(1404577927)
+bnot64(4746555852716517511)
+brev8(4746555852716517511)
+brev8(135)
+brev16(4746555852716517511)
+brev16(10375)
+brev32(4746555852716517511)
+brev32(1404577927)
+brev64(4746555852716517511)
+brol8(4746555852716517511, 1377312048802829031)
+brol8(135, 1377312048802829031)
+brol8(4746555852716517511, 231)
+brol8(135, 231)
+brol16(4746555852716517511, 1377312048802829031)
+brol16(10375, 1377312048802829031)
+brol16(4746555852716517511, 4839)
+brol16(10375, 4839)
+brol32(4746555852716517511, 1377312048802829031)
+brol32(1404577927, 1377312048802829031)
+brol32(4746555852716517511, 3586265831)
+brol32(1404577927, 3586265831)
+brol64(4746555852716517511, 1377312048802829031)
+bror8(4746555852716517511, 1377312048802829031)
+bror8(135, 1377312048802829031)
+bror8(4746555852716517511, 231)
+bror8(135, 231)
+bror16(4746555852716517511, 1377312048802829031)
+bror16(10375, 1377312048802829031)
+bror16(4746555852716517511, 4839)
+bror16(10375, 4839)
+bror32(4746555852716517511, 1377312048802829031)
+bror32(1404577927, 1377312048802829031)
+bror32(4746555852716517511, 3586265831)
+bror32(1404577927, 3586265831)
+bror64(4746555852716517511, 1377312048802829031)
+bmod8(4746555852716517511)
+bmod8(135)
+bmod16(4746555852716517511)
+bmod16(10375)
+bmod32(4746555852716517511)
+bmod32(1404577927)
+bmod64(4746555852716517511)
+band(14626963365082536037, 2309994936510276917)
+bor(14626963365082536037, 2309994936510276917)
+bxor(14626963365082536037, 2309994936510276917)
+bshl(4268071013, 21)
+bshr(4268071013, 21)
+bshl(3886376245, 5)
+bshr(3886376245, 5)
+bnot8(14626963365082536037)
+bnot8(101)
+bnot16(14626963365082536037)
+bnot16(39013)
+bnot32(14626963365082536037)
+bnot32(4268071013)
+bnot64(14626963365082536037)
+brev8(14626963365082536037)
+brev8(101)
+brev16(14626963365082536037)
+brev16(39013)
+brev32(14626963365082536037)
+brev32(4268071013)
+brev64(14626963365082536037)
+brol8(14626963365082536037, 2309994936510276917)
+brol8(101, 2309994936510276917)
+brol8(14626963365082536037, 53)
+brol8(101, 53)
+brol16(14626963365082536037, 2309994936510276917)
+brol16(39013, 2309994936510276917)
+brol16(14626963365082536037, 25909)
+brol16(39013, 25909)
+brol32(14626963365082536037, 2309994936510276917)
+brol32(4268071013, 2309994936510276917)
+brol32(14626963365082536037, 3886376245)
+brol32(4268071013, 3886376245)
+brol64(14626963365082536037, 2309994936510276917)
+bror8(14626963365082536037, 2309994936510276917)
+bror8(101, 2309994936510276917)
+bror8(14626963365082536037, 53)
+bror8(101, 53)
+bror16(14626963365082536037, 2309994936510276917)
+bror16(39013, 2309994936510276917)
+bror16(14626963365082536037, 25909)
+bror16(39013, 25909)
+bror32(14626963365082536037, 2309994936510276917)
+bror32(4268071013, 2309994936510276917)
+bror32(14626963365082536037, 3886376245)
+bror32(4268071013, 3886376245)
+bror64(14626963365082536037, 2309994936510276917)
+bmod8(14626963365082536037)
+bmod8(101)
+bmod16(14626963365082536037)
+bmod16(39013)
+bmod32(14626963365082536037)
+bmod32(4268071013)
+bmod64(14626963365082536037)
+band(2041104271867029339, 4637206736756171033)
+bor(2041104271867029339, 4637206736756171033)
+bxor(2041104271867029339, 4637206736756171033)
+bshl(1646962523, 25)
+bshr(1646962523, 25)
+bshl(1181114649, 27)
+bshr(1181114649, 27)
+bnot8(2041104271867029339)
+bnot8(91)
+bnot16(2041104271867029339)
+bnot16(42843)
+bnot32(2041104271867029339)
+bnot32(1646962523)
+bnot64(2041104271867029339)
+brev8(2041104271867029339)
+brev8(91)
+brev16(2041104271867029339)
+brev16(42843)
+brev32(2041104271867029339)
+brev32(1646962523)
+brev64(2041104271867029339)
+brol8(2041104271867029339, 4637206736756171033)
+brol8(91, 4637206736756171033)
+brol8(2041104271867029339, 25)
+brol8(91, 25)
+brol16(2041104271867029339, 4637206736756171033)
+brol16(42843, 4637206736756171033)
+brol16(2041104271867029339, 24857)
+brol16(42843, 24857)
+brol32(2041104271867029339, 4637206736756171033)
+brol32(1646962523, 4637206736756171033)
+brol32(2041104271867029339, 1181114649)
+brol32(1646962523, 1181114649)
+brol64(2041104271867029339, 4637206736756171033)
+bror8(2041104271867029339, 4637206736756171033)
+bror8(91, 4637206736756171033)
+bror8(2041104271867029339, 25)
+bror8(91, 25)
+bror16(2041104271867029339, 4637206736756171033)
+bror16(42843, 4637206736756171033)
+bror16(2041104271867029339, 24857)
+bror16(42843, 24857)
+bror32(2041104271867029339, 4637206736756171033)
+bror32(1646962523, 4637206736756171033)
+bror32(2041104271867029339, 1181114649)
+bror32(1646962523, 1181114649)
+bror64(2041104271867029339, 4637206736756171033)
+bmod8(2041104271867029339)
+bmod8(91)
+bmod16(2041104271867029339)
+bmod16(42843)
+bmod32(2041104271867029339)
+bmod32(1646962523)
+bmod64(2041104271867029339)
+band(4889748273845146518, 14321308034790189151)
+bor(4889748273845146518, 14321308034790189151)
+bxor(4889748273845146518, 14321308034790189151)
+bshl(3885929366, 31)
+bshr(3885929366, 31)
+bshl(3030247519, 22)
+bshr(3030247519, 22)
+bnot8(4889748273845146518)
+bnot8(150)
+bnot16(4889748273845146518)
+bnot16(37782)
+bnot32(4889748273845146518)
+bnot32(3885929366)
+bnot64(4889748273845146518)
+brev8(4889748273845146518)
+brev8(150)
+brev16(4889748273845146518)
+brev16(37782)
+brev32(4889748273845146518)
+brev32(3885929366)
+brev64(4889748273845146518)
+brol8(4889748273845146518, 14321308034790189151)
+brol8(150, 14321308034790189151)
+brol8(4889748273845146518, 95)
+brol8(150, 95)
+brol16(4889748273845146518, 14321308034790189151)
+brol16(37782, 14321308034790189151)
+brol16(4889748273845146518, 59487)
+brol16(37782, 59487)
+brol32(4889748273845146518, 14321308034790189151)
+brol32(3885929366, 14321308034790189151)
+brol32(4889748273845146518, 3030247519)
+brol32(3885929366, 3030247519)
+brol64(4889748273845146518, 14321308034790189151)
+bror8(4889748273845146518, 14321308034790189151)
+bror8(150, 14321308034790189151)
+bror8(4889748273845146518, 95)
+bror8(150, 95)
+bror16(4889748273845146518, 14321308034790189151)
+bror16(37782, 14321308034790189151)
+bror16(4889748273845146518, 59487)
+bror16(37782, 59487)
+bror32(4889748273845146518, 14321308034790189151)
+bror32(3885929366, 14321308034790189151)
+bror32(4889748273845146518, 3030247519)
+bror32(3885929366, 3030247519)
+bror64(4889748273845146518, 14321308034790189151)
+bmod8(4889748273845146518)
+bmod8(150)
+bmod16(4889748273845146518)
+bmod16(37782)
+bmod32(4889748273845146518)
+bmod32(3885929366)
+bmod64(4889748273845146518)
+band(3701647316701050728, 4963558888053938375)
+bor(3701647316701050728, 4963558888053938375)
+bxor(3701647316701050728, 4963558888053938375)
+bshl(1404991336, 7)
+bshr(1404991336, 7)
+bshl(3090159815, 8)
+bshr(3090159815, 8)
+bnot8(3701647316701050728)
+bnot8(104)
+bnot16(3701647316701050728)
+bnot16(30568)
+bnot32(3701647316701050728)
+bnot32(1404991336)
+bnot64(3701647316701050728)
+brev8(3701647316701050728)
+brev8(104)
+brev16(3701647316701050728)
+brev16(30568)
+brev32(3701647316701050728)
+brev32(1404991336)
+brev64(3701647316701050728)
+brol8(3701647316701050728, 4963558888053938375)
+brol8(104, 4963558888053938375)
+brol8(3701647316701050728, 199)
+brol8(104, 199)
+brol16(3701647316701050728, 4963558888053938375)
+brol16(30568, 4963558888053938375)
+brol16(3701647316701050728, 6343)
+brol16(30568, 6343)
+brol32(3701647316701050728, 4963558888053938375)
+brol32(1404991336, 4963558888053938375)
+brol32(3701647316701050728, 3090159815)
+brol32(1404991336, 3090159815)
+brol64(3701647316701050728, 4963558888053938375)
+bror8(3701647316701050728, 4963558888053938375)
+bror8(104, 4963558888053938375)
+bror8(3701647316701050728, 199)
+bror8(104, 199)
+bror16(3701647316701050728, 4963558888053938375)
+bror16(30568, 4963558888053938375)
+bror16(3701647316701050728, 6343)
+bror16(30568, 6343)
+bror32(3701647316701050728, 4963558888053938375)
+bror32(1404991336, 4963558888053938375)
+bror32(3701647316701050728, 3090159815)
+bror32(1404991336, 3090159815)
+bror64(3701647316701050728, 4963558888053938375)
+bmod8(3701647316701050728)
+bmod8(104)
+bmod16(3701647316701050728)
+bmod16(30568)
+bmod32(3701647316701050728)
+bmod32(1404991336)
+bmod64(3701647316701050728)
+band(1414300993952632473, 6739988921344596742)
+bor(1414300993952632473, 6739988921344596742)
+bxor(1414300993952632473, 6739988921344596742)
+bshl(3188149913, 6)
+bshr(3188149913, 6)
+bshl(3335527174, 25)
+bshr(3335527174, 25)
+bnot8(1414300993952632473)
+bnot8(153)
+bnot16(1414300993952632473)
+bnot16(20121)
+bnot32(1414300993952632473)
+bnot32(3188149913)
+bnot64(1414300993952632473)
+brev8(1414300993952632473)
+brev8(153)
+brev16(1414300993952632473)
+brev16(20121)
+brev32(1414300993952632473)
+brev32(3188149913)
+brev64(1414300993952632473)
+brol8(1414300993952632473, 6739988921344596742)
+brol8(153, 6739988921344596742)
+brol8(1414300993952632473, 6)
+brol8(153, 6)
+brol16(1414300993952632473, 6739988921344596742)
+brol16(20121, 6739988921344596742)
+brol16(1414300993952632473, 6918)
+brol16(20121, 6918)
+brol32(1414300993952632473, 6739988921344596742)
+brol32(3188149913, 6739988921344596742)
+brol32(1414300993952632473, 3335527174)
+brol32(3188149913, 3335527174)
+brol64(1414300993952632473, 6739988921344596742)
+bror8(1414300993952632473, 6739988921344596742)
+bror8(153, 6739988921344596742)
+bror8(1414300993952632473, 6)
+bror8(153, 6)
+bror16(1414300993952632473, 6739988921344596742)
+bror16(20121, 6739988921344596742)
+bror16(1414300993952632473, 6918)
+bror16(20121, 6918)
+bror32(1414300993952632473, 6739988921344596742)
+bror32(3188149913, 6739988921344596742)
+bror32(1414300993952632473, 3335527174)
+bror32(3188149913, 3335527174)
+bror64(1414300993952632473, 6739988921344596742)
+bmod8(1414300993952632473)
+bmod8(153)
+bmod16(1414300993952632473)
+bmod16(20121)
+bmod32(1414300993952632473)
+bmod32(3188149913)
+bmod64(1414300993952632473)
+band(8386904733128639898, 8623034443290091584)
+bor(8386904733128639898, 8623034443290091584)
+bxor(8386904733128639898, 8623034443290091584)
+bshl(1194116506, 0)
+bshr(1194116506, 0)
+bshl(2923667520, 26)
+bshr(2923667520, 26)
+bnot8(8386904733128639898)
+bnot8(154)
+bnot16(8386904733128639898)
+bnot16(50586)
+bnot32(8386904733128639898)
+bnot32(1194116506)
+bnot64(8386904733128639898)
+brev8(8386904733128639898)
+brev8(154)
+brev16(8386904733128639898)
+brev16(50586)
+brev32(8386904733128639898)
+brev32(1194116506)
+brev64(8386904733128639898)
+brol8(8386904733128639898, 8623034443290091584)
+brol8(154, 8623034443290091584)
+brol8(8386904733128639898, 64)
+brol8(154, 64)
+brol16(8386904733128639898, 8623034443290091584)
+brol16(50586, 8623034443290091584)
+brol16(8386904733128639898, 41024)
+brol16(50586, 41024)
+brol32(8386904733128639898, 8623034443290091584)
+brol32(1194116506, 8623034443290091584)
+brol32(8386904733128639898, 2923667520)
+brol32(1194116506, 2923667520)
+brol64(8386904733128639898, 8623034443290091584)
+bror8(8386904733128639898, 8623034443290091584)
+bror8(154, 8623034443290091584)
+bror8(8386904733128639898, 64)
+bror8(154, 64)
+bror16(8386904733128639898, 8623034443290091584)
+bror16(50586, 8623034443290091584)
+bror16(8386904733128639898, 41024)
+bror16(50586, 41024)
+bror32(8386904733128639898, 8623034443290091584)
+bror32(1194116506, 8623034443290091584)
+bror32(8386904733128639898, 2923667520)
+bror32(1194116506, 2923667520)
+bror64(8386904733128639898, 8623034443290091584)
+bmod8(8386904733128639898)
+bmod8(154)
+bmod16(8386904733128639898)
+bmod16(50586)
+bmod32(8386904733128639898)
+bmod32(1194116506)
+bmod64(8386904733128639898)
+band(1590232978542291978, 1882225824502721111)
+bor(1590232978542291978, 1882225824502721111)
+bxor(1590232978542291978, 1882225824502721111)
+bshl(4095732746, 23)
+bshr(4095732746, 23)
+bshl(948775511, 10)
+bshr(948775511, 10)
+bnot8(1590232978542291978)
+bnot8(10)
+bnot16(1590232978542291978)
+bnot16(60426)
+bnot32(1590232978542291978)
+bnot32(4095732746)
+bnot64(1590232978542291978)
+brev8(1590232978542291978)
+brev8(10)
+brev16(1590232978542291978)
+brev16(60426)
+brev32(1590232978542291978)
+brev32(4095732746)
+brev64(1590232978542291978)
+brol8(1590232978542291978, 1882225824502721111)
+brol8(10, 1882225824502721111)
+brol8(1590232978542291978, 87)
+brol8(10, 87)
+brol16(1590232978542291978, 1882225824502721111)
+brol16(60426, 1882225824502721111)
+brol16(1590232978542291978, 10839)
+brol16(60426, 10839)
+brol32(1590232978542291978, 1882225824502721111)
+brol32(4095732746, 1882225824502721111)
+brol32(1590232978542291978, 948775511)
+brol32(4095732746, 948775511)
+brol64(1590232978542291978, 1882225824502721111)
+bror8(1590232978542291978, 1882225824502721111)
+bror8(10, 1882225824502721111)
+bror8(1590232978542291978, 87)
+bror8(10, 87)
+bror16(1590232978542291978, 1882225824502721111)
+bror16(60426, 1882225824502721111)
+bror16(1590232978542291978, 10839)
+bror16(60426, 10839)
+bror32(1590232978542291978, 1882225824502721111)
+bror32(4095732746, 1882225824502721111)
+bror32(1590232978542291978, 948775511)
+bror32(4095732746, 948775511)
+bror64(1590232978542291978, 1882225824502721111)
+bmod8(1590232978542291978)
+bmod8(10)
+bmod16(1590232978542291978)
+bmod16(60426)
+bmod32(1590232978542291978)
+bmod32(4095732746)
+bmod64(1590232978542291978)
+band(529425170122629968, 4330503052237228119)
+bor(529425170122629968, 4330503052237228119)
+bxor(529425170122629968, 4330503052237228119)
+bshl(542073680, 23)
+bshr(542073680, 23)
+bshl(4283975767, 16)
+bshr(4283975767, 16)
+bnot8(529425170122629968)
+bnot8(80)
+bnot16(529425170122629968)
+bnot16(25424)
+bnot32(529425170122629968)
+bnot32(542073680)
+bnot64(529425170122629968)
+brev8(529425170122629968)
+brev8(80)
+brev16(529425170122629968)
+brev16(25424)
+brev32(529425170122629968)
+brev32(542073680)
+brev64(529425170122629968)
+brol8(529425170122629968, 4330503052237228119)
+brol8(80, 4330503052237228119)
+brol8(529425170122629968, 87)
+brol8(80, 87)
+brol16(529425170122629968, 4330503052237228119)
+brol16(25424, 4330503052237228119)
+brol16(529425170122629968, 18519)
+brol16(25424, 18519)
+brol32(529425170122629968, 4330503052237228119)
+brol32(542073680, 4330503052237228119)
+brol32(529425170122629968, 4283975767)
+brol32(542073680, 4283975767)
+brol64(529425170122629968, 4330503052237228119)
+bror8(529425170122629968, 4330503052237228119)
+bror8(80, 4330503052237228119)
+bror8(529425170122629968, 87)
+bror8(80, 87)
+bror16(529425170122629968, 4330503052237228119)
+bror16(25424, 4330503052237228119)
+bror16(529425170122629968, 18519)
+bror16(25424, 18519)
+bror32(529425170122629968, 4330503052237228119)
+bror32(542073680, 4330503052237228119)
+bror32(529425170122629968, 4283975767)
+bror32(542073680, 4283975767)
+bror64(529425170122629968, 4330503052237228119)
+bmod8(529425170122629968)
+bmod8(80)
+bmod16(529425170122629968)
+bmod16(25424)
+bmod32(529425170122629968)
+bmod32(542073680)
+bmod64(529425170122629968)
+band(15821936739280024290, 10935938245296661885)
+bor(15821936739280024290, 10935938245296661885)
+bxor(15821936739280024290, 10935938245296661885)
+bshl(3682398946, 29)
+bshr(3682398946, 29)
+bshl(2625906045, 2)
+bshr(2625906045, 2)
+bnot8(15821936739280024290)
+bnot8(226)
+bnot16(15821936739280024290)
+bnot16(62178)
+bnot32(15821936739280024290)
+bnot32(3682398946)
+bnot64(15821936739280024290)
+brev8(15821936739280024290)
+brev8(226)
+brev16(15821936739280024290)
+brev16(62178)
+brev32(15821936739280024290)
+brev32(3682398946)
+brev64(15821936739280024290)
+brol8(15821936739280024290, 10935938245296661885)
+brol8(226, 10935938245296661885)
+brol8(15821936739280024290, 125)
+brol8(226, 125)
+brol16(15821936739280024290, 10935938245296661885)
+brol16(62178, 10935938245296661885)
+brol16(15821936739280024290, 9597)
+brol16(62178, 9597)
+brol32(15821936739280024290, 10935938245296661885)
+brol32(3682398946, 10935938245296661885)
+brol32(15821936739280024290, 2625906045)
+brol32(3682398946, 2625906045)
+brol64(15821936739280024290, 10935938245296661885)
+bror8(15821936739280024290, 10935938245296661885)
+bror8(226, 10935938245296661885)
+bror8(15821936739280024290, 125)
+bror8(226, 125)
+bror16(15821936739280024290, 10935938245296661885)
+bror16(62178, 10935938245296661885)
+bror16(15821936739280024290, 9597)
+bror16(62178, 9597)
+bror32(15821936739280024290, 10935938245296661885)
+bror32(3682398946, 10935938245296661885)
+bror32(15821936739280024290, 2625906045)
+bror32(3682398946, 2625906045)
+bror64(15821936739280024290, 10935938245296661885)
+bmod8(15821936739280024290)
+bmod8(226)
+bmod16(15821936739280024290)
+bmod16(62178)
+bmod32(15821936739280024290)
+bmod32(3682398946)
+bmod64(15821936739280024290)
+band(9920051000182851075, 11466635482488830435)
+bor(9920051000182851075, 11466635482488830435)
+bxor(9920051000182851075, 11466635482488830435)
+bshl(1940407811, 3)
+bshr(1940407811, 3)
+bshl(4003658211, 3)
+bshr(4003658211, 3)
+bnot8(9920051000182851075)
+bnot8(3)
+bnot16(9920051000182851075)
+bnot16(17923)
+bnot32(9920051000182851075)
+bnot32(1940407811)
+bnot64(9920051000182851075)
+brev8(9920051000182851075)
+brev8(3)
+brev16(9920051000182851075)
+brev16(17923)
+brev32(9920051000182851075)
+brev32(1940407811)
+brev64(9920051000182851075)
+brol8(9920051000182851075, 11466635482488830435)
+brol8(3, 11466635482488830435)
+brol8(9920051000182851075, 227)
+brol8(3, 227)
+brol16(9920051000182851075, 11466635482488830435)
+brol16(17923, 11466635482488830435)
+brol16(9920051000182851075, 63971)
+brol16(17923, 63971)
+brol32(9920051000182851075, 11466635482488830435)
+brol32(1940407811, 11466635482488830435)
+brol32(9920051000182851075, 4003658211)
+brol32(1940407811, 4003658211)
+brol64(9920051000182851075, 11466635482488830435)
+bror8(9920051000182851075, 11466635482488830435)
+bror8(3, 11466635482488830435)
+bror8(9920051000182851075, 227)
+bror8(3, 227)
+bror16(9920051000182851075, 11466635482488830435)
+bror16(17923, 11466635482488830435)
+bror16(9920051000182851075, 63971)
+bror16(17923, 63971)
+bror32(9920051000182851075, 11466635482488830435)
+bror32(1940407811, 11466635482488830435)
+bror32(9920051000182851075, 4003658211)
+bror32(1940407811, 4003658211)
+bror64(9920051000182851075, 11466635482488830435)
+bmod8(9920051000182851075)
+bmod8(3)
+bmod16(9920051000182851075)
+bmod16(17923)
+bmod32(9920051000182851075)
+bmod32(1940407811)
+bmod64(9920051000182851075)
+band(6960136430480362150, 11351650405755785491)
+bor(6960136430480362150, 11351650405755785491)
+bxor(6960136430480362150, 11351650405755785491)
+bshl(118065830, 19)
+bshr(118065830, 19)
+bshl(2172522771, 6)
+bshr(2172522771, 6)
+bnot8(6960136430480362150)
+bnot8(166)
+bnot16(6960136430480362150)
+bnot16(35494)
+bnot32(6960136430480362150)
+bnot32(118065830)
+bnot64(6960136430480362150)
+brev8(6960136430480362150)
+brev8(166)
+brev16(6960136430480362150)
+brev16(35494)
+brev32(6960136430480362150)
+brev32(118065830)
+brev64(6960136430480362150)
+brol8(6960136430480362150, 11351650405755785491)
+brol8(166, 11351650405755785491)
+brol8(6960136430480362150, 19)
+brol8(166, 19)
+brol16(6960136430480362150, 11351650405755785491)
+brol16(35494, 11351650405755785491)
+brol16(6960136430480362150, 4371)
+brol16(35494, 4371)
+brol32(6960136430480362150, 11351650405755785491)
+brol32(118065830, 11351650405755785491)
+brol32(6960136430480362150, 2172522771)
+brol32(118065830, 2172522771)
+brol64(6960136430480362150, 11351650405755785491)
+bror8(6960136430480362150, 11351650405755785491)
+bror8(166, 11351650405755785491)
+bror8(6960136430480362150, 19)
+bror8(166, 19)
+bror16(6960136430480362150, 11351650405755785491)
+bror16(35494, 11351650405755785491)
+bror16(6960136430480362150, 4371)
+bror16(35494, 4371)
+bror32(6960136430480362150, 11351650405755785491)
+bror32(118065830, 11351650405755785491)
+bror32(6960136430480362150, 2172522771)
+bror32(118065830, 2172522771)
+bror64(6960136430480362150, 11351650405755785491)
+bmod8(6960136430480362150)
+bmod8(166)
+bmod16(6960136430480362150)
+bmod16(35494)
+bmod32(6960136430480362150)
+bmod32(118065830)
+bmod64(6960136430480362150)
+band(869320618226679840, 15779715921992018698)
+bor(869320618226679840, 15779715921992018698)
+bxor(869320618226679840, 15779715921992018698)
+bshl(357761056, 10)
+bshr(357761056, 10)
+bshl(3404262154, 0)
+bshr(3404262154, 0)
+bnot8(869320618226679840)
+bnot8(32)
+bnot16(869320618226679840)
+bnot16(32)
+bnot32(869320618226679840)
+bnot32(357761056)
+bnot64(869320618226679840)
+brev8(869320618226679840)
+brev8(32)
+brev16(869320618226679840)
+brev16(32)
+brev32(869320618226679840)
+brev32(357761056)
+brev64(869320618226679840)
+brol8(869320618226679840, 15779715921992018698)
+brol8(32, 15779715921992018698)
+brol8(869320618226679840, 10)
+brol8(32, 10)
+brol16(869320618226679840, 15779715921992018698)
+brol16(32, 15779715921992018698)
+brol16(869320618226679840, 60170)
+brol16(32, 60170)
+brol32(869320618226679840, 15779715921992018698)
+brol32(357761056, 15779715921992018698)
+brol32(869320618226679840, 3404262154)
+brol32(357761056, 3404262154)
+brol64(869320618226679840, 15779715921992018698)
+bror8(869320618226679840, 15779715921992018698)
+bror8(32, 15779715921992018698)
+bror8(869320618226679840, 10)
+bror8(32, 10)
+bror16(869320618226679840, 15779715921992018698)
+bror16(32, 15779715921992018698)
+bror16(869320618226679840, 60170)
+bror16(32, 60170)
+bror32(869320618226679840, 15779715921992018698)
+bror32(357761056, 15779715921992018698)
+bror32(869320618226679840, 3404262154)
+bror32(357761056, 3404262154)
+bror64(869320618226679840, 15779715921992018698)
+bmod8(869320618226679840)
+bmod8(32)
+bmod16(869320618226679840)
+bmod16(32)
+bmod32(869320618226679840)
+bmod32(357761056)
+bmod64(869320618226679840)
+band(11784620717065408517, 14976544843797949497)
+bor(11784620717065408517, 14976544843797949497)
+bxor(11784620717065408517, 14976544843797949497)
+bshl(3311702021, 25)
+bshr(3311702021, 25)
+bshl(2974346297, 5)
+bshr(2974346297, 5)
+bnot8(11784620717065408517)
+bnot8(5)
+bnot16(11784620717065408517)
+bnot16(36869)
+bnot32(11784620717065408517)
+bnot32(3311702021)
+bnot64(11784620717065408517)
+brev8(11784620717065408517)
+brev8(5)
+brev16(11784620717065408517)
+brev16(36869)
+brev32(11784620717065408517)
+brev32(3311702021)
+brev64(11784620717065408517)
+brol8(11784620717065408517, 14976544843797949497)
+brol8(5, 14976544843797949497)
+brol8(11784620717065408517, 57)
+brol8(5, 57)
+brol16(11784620717065408517, 14976544843797949497)
+brol16(36869, 14976544843797949497)
+brol16(11784620717065408517, 60473)
+brol16(36869, 60473)
+brol32(11784620717065408517, 14976544843797949497)
+brol32(3311702021, 14976544843797949497)
+brol32(11784620717065408517, 2974346297)
+brol32(3311702021, 2974346297)
+brol64(11784620717065408517, 14976544843797949497)
+bror8(11784620717065408517, 14976544843797949497)
+bror8(5, 14976544843797949497)
+bror8(11784620717065408517, 57)
+bror8(5, 57)
+bror16(11784620717065408517, 14976544843797949497)
+bror16(36869, 14976544843797949497)
+bror16(11784620717065408517, 60473)
+bror16(36869, 60473)
+bror32(11784620717065408517, 14976544843797949497)
+bror32(3311702021, 14976544843797949497)
+bror32(11784620717065408517, 2974346297)
+bror32(3311702021, 2974346297)
+bror64(11784620717065408517, 14976544843797949497)
+bmod8(11784620717065408517)
+bmod8(5)
+bmod16(11784620717065408517)
+bmod16(36869)
+bmod32(11784620717065408517)
+bmod32(3311702021)
+bmod64(11784620717065408517)
diff --git a/contrib/bc/tests/bc/bitfuncs_results.txt b/contrib/bc/tests/bc/bitfuncs_results.txt
new file mode 100644
index 000000000000..984e4aabf18d
--- /dev/null
+++ b/contrib/bc/tests/bc/bitfuncs_results.txt
@@ -0,0 +1,5400 @@
+9262480978327765248
+16712576628877649753
+7450095650549884505
+2366588185
+2366588185
+11668320189153280
+10
+230
+230
+47846
+47846
+1928379110
+1928379110
+4500510134768810726
+152
+152
+39074
+39074
+2560815281
+2560815281
+10998617883119931779
+25
+25
+25
+25
+17689
+17689
+17689
+17689
+2366588185
+2366588185
+2366588185
+2366588185
+13946233938940740889
+25
+25
+25
+25
+17689
+17689
+17689
+17689
+2366588185
+2366588185
+2366588185
+2366588185
+13946233938940740889
+25
+25
+17689
+17689
+2366588185
+2366588185
+13946233938940740889
+4611704028567541784
+14852022748077874618
+10240318719510332834
+242287713892433920
+53
+33780968875622400
+120
+231
+231
+9959
+9959
+684599015
+684599015
+3602717017809757927
+24
+24
+6299
+6299
+412847339
+412847339
+1773165822194810995
+96
+96
+96
+96
+25444
+25444
+25444
+25444
+1667024740
+1667024740
+1667024740
+1667024740
+7149466950389516132
+6
+6
+6
+6
+17974
+17974
+17974
+17974
+3430303285
+3430303285
+3430303285
+3430303285
+9233783818399663667
+24
+24
+55576
+55576
+3610368280
+3610368280
+14844027055899793688
+7141037751335392323
+8628681371490514127
+1487643620155121804
+84199245709312
+78416
+344303224
+5379737
+188
+188
+43964
+43964
+1725410236
+1725410236
+10143494422979390396
+194
+194
+49706
+49706
+3257537689
+3257537689
+13991017839902383310
+161
+161
+161
+161
+43553
+43553
+43553
+43553
+706858132
+706858132
+706858132
+706858132
+9856211983746054557
+134
+134
+134
+134
+43142
+43142
+43142
+43142
+2827432528
+2827432528
+2827432528
+2827432528
+12143646840321028688
+67
+67
+21571
+21571
+2569557059
+2569557059
+8303249650730161219
+298366310206505220
+16138621639449372668
+15840255329242867448
+5347174989824
+318716
+3356646206078976
+3052
+139
+139
+14475
+14475
+2989504651
+2989504651
+3141504151761991819
+46
+46
+12003
+12003
+786690994
+786690994
+3378812093322290731
+71
+71
+71
+71
+19575
+19575
+19575
+19575
+4235674844
+4235674844
+4235674844
+4235674844
+8226357832148536646
+71
+71
+71
+71
+30540
+30540
+30540
+30540
+2001001724
+2001001724
+2001001724
+2001001724
+8596604719863225596
+116
+116
+51060
+51060
+1305462644
+1305462644
+15305239921947559796
+3589193083200512
+17834252873642124791
+17830663680558924279
+4805177248
+75080894
+2935808792199168
+2670
+11
+11
+55819
+55819
+3694320139
+3694320139
+4103106373233072651
+47
+47
+12196
+12196
+799323076
+799323076
+3433066472479092963
+167
+167
+167
+167
+12193
+12193
+12193
+12193
+510209953
+510209953
+510209953
+510209953
+4068637161554522022
+158
+158
+158
+158
+33982
+33982
+33982
+33982
+2222564542
+2222564542
+2222564542
+2222564542
+11016326749414335678
+244
+244
+9716
+9716
+600647156
+600647156
+14343637700476478964
+7516685521054179091
+18011840752554729439
+10495155231500550348
+4715497411638722560
+1
+693168948903936
+2521
+44
+44
+24620
+24620
+2099142700
+2099142700
+1625612851250880556
+203
+203
+52217
+52217
+3422127937
+3422127937
+14697927574786739863
+233
+233
+233
+233
+53225
+53225
+53225
+53225
+3245395945
+3245395945
+3245395945
+3245395945
+13938869450451735772
+167
+167
+167
+167
+16295
+16295
+16295
+16295
+96681895
+96681895
+96681895
+96681895
+415245580678288243
+211
+211
+40915
+40915
+2195824595
+2195824595
+16821131222458671059
+17043543218841717808
+18444482893137137214
+1400939674295419406
+15425405343236096
+876
+57724421493751808
+205
+199
+199
+46023
+46023
+617264071
+617264071
+1312811034436350919
+28
+28
+7218
+7218
+473083099
+473083099
+2031876440822113207
+14
+14
+14
+14
+3603
+3603
+3603
+3603
+238472531
+238472531
+238472531
+238472531
+1025538673014656339
+224
+224
+224
+224
+57648
+57648
+57648
+57648
+3576750956
+3576750956
+3576750956
+3576750956
+2293818117973926839
+56
+56
+19512
+19512
+3677703224
+3677703224
+17133933039273200696
+72339619064579205
+17138377829033891751
+17066038209969312546
+55550067328
+3390507
+11628238048
+11355701
+122
+122
+60026
+60026
+3860982394
+3860982394
+16062742481864878714
+161
+161
+41384
+41384
+2712173464
+2712173464
+11648696331294582916
+194
+194
+194
+194
+49802
+49802
+49802
+49802
+4010459788
+4010459788
+4010459788
+4010459788
+17224793650892269708
+11
+11
+11
+11
+2603
+2603
+2603
+2603
+171162667
+171162667
+171162667
+171162667
+11687892350998293337
+133
+133
+5509
+5509
+433984901
+433984901
+2384001591844672901
+12107378737872392736
+18084183408420585379
+5976804670548192643
+23389188352
+365456068
+3249077155
+3249077155
+223
+223
+43487
+43487
+1371318751
+1371318751
+1583212130218060255
+4
+4
+1130
+1130
+74105461
+74105461
+318280532241866839
+1
+1
+1
+1
+45314
+45314
+45314
+45314
+1914351877
+1914351877
+1914351877
+1914351877
+8222078714687154085
+4
+4
+4
+4
+2756
+2756
+2756
+2756
+365456068
+365456068
+365456068
+365456068
+10792993897530321310
+32
+32
+22048
+22048
+2923648544
+2923648544
+16863531943491491360
+5814859603720061704
+18282362679993424857
+12467503076273363153
+324754151680
+4955355
+42084389789630464
+37
+230
+230
+9446
+9446
+3026396390
+3026396390
+9748342538101794022
+152
+152
+39131
+39131
+2564504018
+2564504018
+11014460888717946142
+25
+25
+25
+25
+6619
+6619
+6619
+6619
+2631604555
+2631604555
+2631604555
+2631604555
+13181504270439750008
+25
+25
+25
+25
+6619
+6619
+6619
+6619
+424385755
+424385755
+424385755
+424385755
+1835417981946666203
+25
+25
+56089
+56089
+1268570905
+1268570905
+8698401535607757593
+320178199735190029
+13799024267506932319
+13478846067771742290
+48194451832832
+44884
+2270898613590687744
+7
+162
+162
+46498
+46498
+2824189346
+2824189346
+5800711686668531106
+186
+186
+47698
+47698
+3125958122
+3125958122
+13425887903441878773
+174
+174
+174
+174
+42286
+42286
+42286
+42286
+623815637
+623815637
+623815637
+623815637
+15977130822502111167
+186
+186
+186
+186
+38074
+38074
+38074
+38074
+2495262548
+2495262548
+2495262548
+2495262548
+10717264189562859348
+93
+93
+19037
+19037
+1470777949
+1470777949
+12646032387041020509
+5137472426180642
+15951438269389707071
+15946300796963526429
+10069063699005440
+143
+876278766592
+835684
+213
+213
+31445
+31445
+3094641365
+3094641365
+3938885416147778261
+84
+84
+21665
+21665
+1419891170
+1419891170
+6098386141866781331
+21
+21
+21
+21
+38210
+38210
+38210
+38210
+2502149570
+2502149570
+2502149570
+2502149570
+10764917173091812802
+84
+84
+84
+84
+21770
+21770
+21770
+21770
+386552975
+386552975
+386552975
+386552975
+12432515040388208018
+42
+42
+34090
+34090
+1200325930
+1200325930
+14507858657561773354
+77695924568311968
+15132057363495254510
+15054361438926942542
+12066790048
+47135898
+3082174042112
+2939390
+85
+85
+13909
+13909
+3540792917
+3540792917
+9108573912535152213
+85
+85
+21907
+21907
+1435750196
+1435750196
+6166500139496892801
+170
+170
+170
+170
+39596
+39596
+39596
+39596
+3476855458
+3476855458
+3476855458
+3476855458
+14932980511226561682
+170
+170
+170
+170
+44186
+44186
+44186
+44186
+2731490458
+2731490458
+2731490458
+2731490458
+10578740684659457412
+170
+170
+51626
+51626
+754174378
+754174378
+9338170161174399402
+144548886491435348
+18446181065492725244
+18301632179001289896
+1372361769091072
+1248
+473873110165094400
+6
+3
+3
+33283
+33283
+2986181123
+2986181123
+15992863427508666883
+63
+63
+16318
+16318
+1069432946
+1069432946
+4593179529659789380
+207
+207
+207
+207
+57287
+57287
+57287
+57287
+3754221607
+3754221607
+3754221607
+3754221607
+17808605288392171742
+207
+207
+207
+207
+51167
+51167
+51167
+51167
+668976352
+668976352
+668976352
+668976352
+2873228533721146592
+252
+252
+32252
+32252
+1308786172
+1308786172
+2453880646200884732
+1661828606118073920
+15500061017883451102
+13838232411765377182
+26777087392
+104597997
+24004920378130432
+5
+37
+37
+24869
+24869
+2621399333
+2621399333
+16782382131018948901
+91
+91
+23417
+23417
+1534657478
+1534657478
+6591303680618698984
+173
+173
+173
+173
+60841
+60841
+60841
+60841
+1007283622
+1007283622
+1007283622
+1007283622
+8183047009340091809
+173
+173
+173
+173
+43501
+43501
+43501
+43501
+2788952557
+2788952557
+2788952557
+2788952557
+11633237667486632429
+218
+218
+40666
+40666
+1673567962
+1673567962
+1664361942690602714
+148835185588323072
+8880815886107834364
+8731980700519511292
+4011484124
+4011484124
+67876640943767552
+0
+35
+35
+39971
+39971
+283483171
+283483171
+11377512141417716771
+59
+59
+15302
+15302
+1002854647
+1002854647
+4307227912566691910
+220
+220
+220
+220
+25564
+25564
+25564
+25564
+4011484124
+4011484124
+4011484124
+4011484124
+17229193122649142524
+220
+220
+220
+220
+25564
+25564
+25564
+25564
+4011484124
+4011484124
+4011484124
+4011484124
+17229193122649142524
+220
+220
+25564
+25564
+4011484124
+4011484124
+7069231932291834844
+5480969481608544449
+18273494026225123271
+12792524544616578822
+206283989120
+12590575
+6923850126
+1730962531
+62
+62
+2110
+2110
+2683373630
+2683373630
+10551804225895073854
+131
+131
+33775
+33775
+2213507078
+2213507078
+9506940511348197814
+224
+224
+224
+224
+57595
+57595
+57595
+57595
+125558960
+125558960
+125558960
+125558960
+14428120539937366198
+131
+131
+131
+131
+33775
+33775
+33775
+33775
+2193628655
+2193628655
+2193628655
+2193628655
+9429166442491682287
+193
+193
+63425
+63425
+1611593665
+1611593665
+7894939847814477761
+315819605520031749
+17293400350186504133
+16977580744666472384
+48002199712
+46877148
+24801740960
+24220450
+122
+122
+50298
+50298
+2794898554
+2794898554
+12906668033431749754
+161
+161
+41436
+41436
+2715588250
+2715588250
+11663362725092935474
+176
+176
+176
+176
+28839
+28839
+28839
+28839
+757559467
+757559467
+757559467
+757559467
+11261736625503695017
+44
+44
+44
+44
+10716
+10716
+10716
+10716
+717965788
+717965788
+717965788
+717965788
+3055431137775798748
+133
+133
+15237
+15237
+1500068741
+1500068741
+5540076040277801861
+308207098273985
+3976045010268157949
+3975736803169883964
+952323926528
+3632827
+5057496748130304
+1149
+10
+10
+35082
+35082
+2434959626
+2434959626
+18149055310128646410
+175
+175
+44910
+44910
+2943269750
+2943269750
+12641247321071911968
+235
+235
+235
+235
+60141
+60141
+60141
+60141
+3136154333
+3136154333
+3136154333
+3136154333
+4842694363747052040
+250
+250
+250
+250
+31419
+31419
+31419
+31419
+2058841787
+2058841787
+2058841787
+2058841787
+8827636693012541115
+245
+245
+30453
+30453
+1860007669
+1860007669
+297688763580905205
+2632864435439435908
+18202418293145321455
+15569553857705885547
+16206593081344
+60374
+24248709568
+23680380
+26
+26
+28442
+28442
+3305795354
+3305795354
+5432482034667384602
+167
+167
+42761
+42761
+2802429788
+2802429788
+12036344292995750189
+121
+121
+121
+121
+25657
+25657
+25657
+25657
+1681477309
+1681477309
+1681477309
+1681477309
+18201243731866774822
+151
+151
+151
+151
+17302
+17302
+17302
+17302
+1133833174
+1133833174
+1133833174
+1133833174
+4870311424611380182
+229
+229
+37093
+37093
+989171941
+989171941
+13014262039042167013
+6962693290071821486
+17938250374812762111
+10975557084740940625
+20542219337728
+76525
+7304010624684523520
+1
+64
+64
+37184
+37184
+3041169728
+3041169728
+2242381756605174080
+253
+253
+64886
+64886
+4252425554
+4252425554
+18264028684005312263
+239
+239
+239
+239
+56239
+56239
+56239
+56239
+3685733038
+3685733038
+3685733038
+3685733038
+15830144136199738030
+254
+254
+254
+254
+47869
+47869
+47869
+47869
+3137153773
+3137153773
+3137153773
+3137153773
+15470193395527287685
+191
+191
+28351
+28351
+1253797567
+1253797567
+16204362317104377535
+190307872931842093
+18424225508082888701
+18233917635151046608
+1267206347905040384
+4
+30558986936320
+455364
+82
+82
+54354
+54354
+1934611538
+1934611538
+9897331662563300434
+181
+181
+46548
+46548
+3050573105
+3050573105
+13102111721420072302
+181
+181
+181
+181
+42357
+42357
+42357
+42357
+2979399029
+2979399029
+2979399029
+2979399029
+12597891597461751157
+109
+109
+109
+109
+23913
+23913
+23913
+23913
+1702976876
+1702976876
+1702976876
+1702976876
+13055067068041354603
+173
+173
+11181
+11181
+2360355757
+2360355757
+8549412411146251181
+673099450272991745
+18410536004402183163
+17737436554129191418
+528138165584658432
+29
+2161693878
+540423469
+94
+94
+42078
+42078
+360031326
+360031326
+12873719425608819806
+133
+133
+34266
+34266
+2245677399
+2245677399
+9645110989397093042
+13
+13
+13
+13
+2781
+2781
+2781
+2781
+257184477
+257184477
+257184477
+257184477
+2257520422535477987
+52
+52
+52
+52
+29739
+29739
+29739
+29739
+1363899453
+1363899453
+1363899453
+1363899453
+5857903462635506813
+161
+161
+23457
+23457
+3934935969
+3934935969
+5573024648100731809
+1176042588307988828
+13762692168222631934
+12586649579914643106
+1066608183432183808
+14
+3746177261343080448
+3
+33
+33
+22561
+22561
+321542177
+321542177
+14954722069364496417
+123
+123
+31717
+31717
+2078649143
+2078649143
+8927730090148916748
+237
+237
+237
+237
+60029
+60029
+60029
+60029
+4006435453
+4006435453
+4006435453
+4006435453
+16359152439767423613
+237
+237
+237
+237
+32234
+32234
+32234
+32234
+3445259758
+3445259758
+3445259758
+3445259758
+532119848392228323
+222
+222
+42974
+42974
+3973425118
+3973425118
+3492022004345055198
+4807036973149077592
+6341031922331582202
+1533994949182504610
+37924874655629312
+134
+261174802511822848
+57
+5
+5
+34565
+34565
+2034468613
+2034468613
+12396713319938098949
+95
+95
+24350
+24350
+1595817313
+1595817313
+6853983171191533514
+250
+250
+250
+250
+64120
+64120
+64120
+64120
+4203134072
+4203134072
+4203134072
+4203134072
+16899401879536268806
+250
+250
+250
+250
+64120
+64120
+64120
+64120
+3162045062
+3162045062
+3162045062
+3162045062
+13580879914852608646
+250
+250
+30970
+30970
+2260498682
+2260498682
+6050030753771452666
+14484165744201827149
+15645467550089670527
+1161301805887843378
+7617383187483721728
+1
+4893141098496
+72913
+178
+178
+15538
+15538
+747846834
+747846834
+2802543986195250354
+178
+178
+45763
+45763
+2999137995
+2999137995
+12881199608620570779
+166
+166
+166
+166
+57766
+57766
+57766
+57766
+3921043878
+3921043878
+3921043878
+3921043878
+17045472080611926438
+154
+154
+154
+154
+34459
+34459
+34459
+34459
+2799273627
+2799273627
+2799273627
+2799273627
+12841656101319050907
+77
+77
+49997
+49997
+3547120461
+3547120461
+15644200087514301261
+2332875602178655744
+8027519357126627324
+5694643754947971580
+365521499136
+5577415
+2481103428386816
+2256
+139
+139
+14475
+14475
+2867148939
+2867148939
+15752999880549021835
+46
+46
+12003
+12003
+786651306
+786651306
+3378641633839433380
+116
+116
+116
+116
+29895
+29895
+29895
+29895
+449279061
+449279061
+449279061
+449279061
+7068982721842213925
+116
+116
+116
+116
+29895
+29895
+29895
+29895
+1951734471
+1951734471
+1951734471
+1951734471
+8369203346654173895
+116
+116
+51060
+51060
+1427818356
+1427818356
+2693744193160529780
+5391664667956484106
+16996497015180566351
+11604832347224082245
+501563441152
+1868
+7956708618240
+1897027
+244
+244
+57844
+57844
+4264354292
+4264354292
+3829415986661745140
+208
+208
+53368
+53368
+3497577344
+3497577344
+15021980311174306643
+194
+194
+194
+194
+51074
+51074
+51074
+51074
+3347234932
+3347234932
+3347234932
+3347234932
+14671813293862220470
+44
+44
+44
+44
+30764
+30764
+30764
+30764
+2016151372
+2016151372
+2016151372
+2016151372
+8660188354430371660
+11
+11
+7691
+7691
+30613003
+30613003
+14617328087047806475
+12056357497448957056
+12093572230457818604
+37214733008861548
+8646076923904
+515346
+1085693164
+1085693164
+127
+127
+55935
+55935
+2184108671
+2184108671
+6389242533384215167
+1
+1
+420
+420
+27560894
+27560894
+118373138975894245
+8
+8
+8
+8
+600
+600
+600
+600
+307759069
+307759069
+307759069
+307759069
+1321817989562779613
+8
+8
+8
+8
+22530
+22530
+22530
+22530
+1476910354
+1476910354
+1476910354
+1476910354
+11261212464119444813
+128
+128
+9600
+9600
+2110858624
+2110858624
+12057501540325336448
+9224036141950305305
+11456031225143844703
+2231995083193539398
+45828644970430464
+2
+1859468550104678400
+6
+226
+226
+58082
+58082
+3953517282
+3953517282
+7740846074367435490
+184
+184
+47288
+47288
+3099089448
+3099089448
+13310487827641747753
+232
+232
+232
+232
+59624
+59624
+59624
+59624
+3902984424
+3902984424
+3902984424
+3902984424
+1198750149655173100
+163
+163
+163
+163
+41891
+41891
+41891
+41891
+2336465826
+2336465826
+2336465826
+2336465826
+10035044382066847810
+29
+29
+7453
+7453
+341450013
+341450013
+10705897999342116125
+2398166870831597714
+17869338008464382175
+15471171137632784461
+1622294535944011776
+0
+144719518367744
+2105
+109
+109
+59245
+59245
+3539527533
+3539527533
+14737989965467674477
+73
+73
+18712
+18712
+1226367156
+1226367156
+5267206829722836684
+73
+73
+73
+73
+3145
+3145
+3145
+3145
+377719881
+377719881
+377719881
+377719881
+1622294536375767579
+37
+37
+37
+37
+12580
+12580
+12580
+12580
+1510879524
+1510879524
+1510879524
+1510879524
+6489178145503070316
+146
+146
+6290
+6290
+755439762
+755439762
+3708754108241877138
+10999487938744594884
+15631835809424848893
+4632347870680254009
+1138156430587592704
+15
+89841384320
+87735726
+26
+26
+19482
+19482
+55004186
+55004186
+2817164530919361562
+167
+167
+42957
+42957
+2815237439
+2815237439
+12091352731312645915
+94
+94
+94
+94
+23358
+23358
+23358
+23358
+1607174974
+1607174974
+1607174974
+1607174974
+10361528467669808828
+94
+94
+94
+94
+15963
+15963
+15963
+15963
+3414900319
+3414900319
+3414900319
+3414900319
+14666885183005179023
+229
+229
+46053
+46053
+4239963109
+4239963109
+15629579542790190053
+5968452074510223377
+18374259782010798073
+12405807707500574696
+27243219720863744
+24
+363347785678848
+21149
+206
+206
+14286
+14286
+3483056078
+3483056078
+82134024589096910
+140
+140
+35859
+35859
+2350065164
+2350065164
+10093453024221215615
+98
+98
+98
+98
+25488
+25488
+25488
+25488
+1650510224
+1650510224
+1650510224
+1650510224
+1468395100512827495
+152
+152
+152
+152
+6372
+6372
+6372
+6372
+845420696
+845420696
+845420696
+845420696
+3631054684910372120
+49
+49
+51249
+51249
+811911217
+811911217
+18364610049120454705
+4801269191180239192
+9217179546497310713
+4415910355317071521
+14446877760028672
+51
+60780500003848192
+53
+38
+38
+42022
+42022
+3433866278
+3433866278
+10454654686340097062
+155
+155
+39898
+39898
+2614807244
+2614807244
+11230511599118292854
+217
+217
+217
+217
+55643
+55643
+55643
+55643
+3644019547
+3644019547
+3644019547
+3644019547
+15667717005399774043
+217
+217
+217
+217
+55643
+55643
+55643
+55643
+1398528307
+1398528307
+1398528307
+1398528307
+16833035058529687918
+217
+217
+23513
+23513
+861101017
+861101017
+7992089387369454553
+2954363558959581184
+17149609206654933695
+14195245647695352511
+444568650846830592
+24
+16952361392
+66220161
+91
+91
+25947
+25947
+982672731
+982672731
+1604083965785957723
+37
+37
+9561
+9561
+626636451
+626636451
+2691383065747701143
+37
+37
+37
+37
+9429
+9429
+9429
+9429
+640380117
+640380117
+640380117
+640380117
+1021029403272800561
+148
+148
+148
+148
+21651
+21651
+21651
+21651
+2914210968
+2914210968
+2914210968
+2914210968
+12516440823612884024
+164
+164
+39588
+39588
+3312294564
+3312294564
+16842660107923593892
+2320641613775241360
+17509150758767312606
+15188509144992071246
+252974557167616
+58900
+3333931684499292160
+2
+97
+97
+50529
+50529
+434881889
+434881889
+5749764936832894305
+121
+121
+31068
+31068
+2036082791
+2036082791
+8744908999341452301
+158
+158
+158
+158
+15006
+15006
+15006
+15006
+983492116
+983492116
+983492116
+983492116
+13493037458159218740
+158
+158
+158
+158
+15006
+15006
+15006
+15006
+983492116
+983492116
+983492116
+983492116
+4224007241046484500
+158
+158
+15006
+15006
+3860085406
+3860085406
+12696979136876657310
+10430341173307217926
+18446687448854158311
+8016346275546940385
+543544861440
+33175345
+252983036352
+61763436
+57
+57
+26425
+26425
+48523065
+48523065
+1010842560574547769
+99
+99
+25369
+25369
+1662638271
+1662638271
+7140977002514947983
+99
+99
+99
+99
+25420
+25420
+25420
+25420
+2378982270
+2378982270
+2378982270
+2378982270
+10217651025878320638
+141
+141
+141
+141
+36145
+36145
+36145
+36145
+2381985585
+2381985585
+2381985585
+2381985585
+1727754093023457672
+198
+198
+39110
+39110
+4246444230
+4246444230
+17435901513135003846
+9512799236270332500
+18264055800420400982
+8751256564150068482
+11648258749235200
+662
+1019280386686976
+927
+171
+171
+57771
+57771
+1517805995
+1517805995
+8856639203467321771
+42
+42
+10872
+10872
+712511909
+712511909
+3060215349474977953
+21
+21
+21
+21
+38151
+38151
+38151
+38151
+2502517255
+2502517255
+2502517255
+2502517255
+7235422061053691321
+81
+81
+81
+81
+20601
+20601
+20601
+20601
+544821910
+544821910
+544821910
+544821910
+2339991728785082006
+84
+84
+7764
+7764
+2777161300
+2777161300
+9590104870242229844
+7208785878808870948
+17251842115355926071
+10043056236547055123
+208119863808
+12702628
+3065527579705344
+2788
+203
+203
+11723
+11723
+2669030859
+2669030859
+1348033603721113035
+44
+44
+11339
+11339
+743151366
+743151366
+3191810813640528567
+26
+26
+26
+26
+6761
+6761
+6761
+6761
+1961433648
+1961433648
+1961433648
+1961433648
+8424293674856827440
+104
+104
+104
+104
+27044
+27044
+27044
+27044
+1757533092
+1757533092
+1757533092
+1757533092
+2936861135126304165
+52
+52
+53812
+53812
+1625936436
+1625936436
+17098710469988438580
+18725267677643022
+16996513180735574943
+16977787913057931921
+33760620773376
+31442
+2897226624313327616
+2
+97
+97
+64609
+64609
+3264674913
+3264674913
+4551249668559273057
+121
+121
+31168
+31168
+2042664636
+2042664636
+8773177809681869571
+79
+79
+79
+79
+463
+463
+463
+463
+2177834676
+2177834676
+2177834676
+2177834676
+6576696591465275499
+61
+61
+61
+61
+1852
+1852
+1852
+1852
+121404114
+121404114
+121404114
+121404114
+521715713704229586
+158
+158
+926
+926
+1030292382
+1030292382
+13895494405150278558
+2314885667729604868
+7205687772865101654
+4890802105135496786
+416632245583872
+23
+7179392352
+28044501
+251
+251
+19707
+19707
+4195634427
+4195634427
+16016587771499269371
+32
+32
+8397
+8397
+550360992
+550360992
+2363782461942766980
+1
+1
+1
+1
+49452
+49452
+49452
+49452
+3238099692
+3238099692
+3238099692
+3238099692
+10520825361783615081
+16
+16
+16
+16
+4812
+4812
+4812
+4812
+2932609047
+2932609047
+2932609047
+2932609047
+12595460429428891671
+4
+4
+45828
+45828
+99332868
+99332868
+2430156302210282244
+10386145184473159748
+18156113152287874519
+7769967967814714771
+118825096512
+29010033
+4060578997862400
+923
+170
+170
+58282
+58282
+2438325162
+2438325162
+1034877152708125610
+170
+170
+43576
+43576
+2855818614
+2855818614
+12265647552267208079
+85
+85
+85
+85
+5447
+5447
+5447
+5447
+2860979547
+2860979547
+2860979547
+2860979547
+7554838521518167420
+85
+85
+85
+85
+21617
+21617
+21617
+21617
+1438296177
+1438296177
+1438296177
+1438296177
+6324898319826593905
+85
+85
+7253
+7253
+1856642133
+1856642133
+17411866921001426005
+36048489453125824
+18442416387302322937
+18406367897849197113
+193193898240
+2947904
+458626901737472
+26695
+14
+14
+48910
+48910
+3540303630
+3540303630
+8435211345049468686
+143
+143
+36610
+36610
+2399330100
+2399330100
+10305044314490146641
+241
+241
+241
+241
+61760
+61760
+61760
+61760
+4215337260
+4215337260
+4215337260
+4215337260
+17301696365063106954
+241
+241
+241
+241
+61760
+61760
+61760
+61760
+4046256960
+4046256960
+4046256960
+4046256960
+17404987712861961024
+241
+241
+16625
+16625
+754663665
+754663665
+10011532728660082929
+2360871779678947590
+9222169718448701335
+6861297938769753745
+163830401792
+9999414
+3252266840621056
+184
+233
+233
+58601
+58601
+3015042281
+3015042281
+13917378017127425257
+104
+104
+26840
+26840
+1759007282
+1759007282
+7554878751600925564
+11
+11
+11
+11
+35597
+35597
+35597
+35597
+621644582
+621644582
+621644582
+621644582
+7909788957516073759
+44
+44
+44
+44
+11318
+11318
+11318
+11318
+748196918
+748196918
+748196918
+748196918
+3205919809985877046
+22
+22
+6934
+6934
+1279925014
+1279925014
+4529366056582126358
+9954503291838701602
+12357308770906865267
+2402805479068163665
+2125114435960832
+7731
+12188817612
+761801100
+157
+157
+1949
+1949
+241633181
+241633181
+8492238263944677277
+70
+70
+17951
+17951
+1176443279
+1176443279
+5052785410284037201
+19
+19
+19
+19
+49943
+49943
+49943
+49943
+3273100487
+3273100487
+3273100487
+3273100487
+14056949586658299079
+76
+76
+76
+76
+24332
+24332
+24332
+24332
+520904243
+520904243
+520904243
+520904243
+12702787797632438596
+98
+98
+63586
+63586
+4053334114
+4053334114
+9954505809764874338
+1621309071815082057
+1723400329271102975
+102091257456020918
+459174104956665856
+25
+31437417832448
+468454
+178
+178
+62130
+62130
+873853618
+873853618
+16732386631181791922
+178
+178
+45744
+45744
+2997901267
+2997901267
+12875887899492045800
+106
+106
+106
+106
+26730
+26730
+26730
+26730
+1851740266
+1851740266
+1851740266
+1851740266
+7547563450023497834
+169
+169
+169
+169
+43425
+43425
+43425
+43425
+2101455289
+2101455289
+2101455289
+2101455289
+17965950013469206946
+77
+77
+3405
+3405
+3421113677
+3421113677
+1714357442527759693
+3603442689471156244
+8625492041716717463
+5022049352245561219
+3508116695023616
+3190
+31873791063752704
+452
+232
+232
+12008
+12008
+949366504
+949366504
+14829789197997846248
+232
+232
+59531
+59531
+3901462243
+3901462243
+16756652743795428428
+113
+113
+113
+113
+4477
+4477
+4477
+4477
+293369501
+293369501
+293369501
+293369501
+1494199593354863392
+113
+113
+113
+113
+32017
+32017
+32017
+32017
+2635168886
+2635168886
+2635168886
+2635168886
+11317953933258046582
+23
+23
+53527
+53527
+3345600791
+3345600791
+3616954875711705367
+326537413484775984
+13753707113969351678
+13427169700484575694
+2860906673340416
+162
+70054950478020608
+248
+7
+7
+5383
+5383
+3612873991
+3612873991
+4698914613093733639
+31
+31
+8023
+8023
+525853972
+525853972
+2258525614096536445
+62
+62
+62
+62
+48698
+48698
+48698
+48698
+3188337146
+3188337146
+3188337146
+3188337146
+13704368481913940474
+227
+227
+227
+227
+58283
+58283
+58283
+58283
+2678841506
+2678841506
+2678841506
+2678841506
+2911639430209725179
+248
+248
+60152
+60152
+682093304
+682093304
+13747829460615817976
+13838437181365191080
+17005301369910785979
+3166864188545594899
+480801907712
+458528
+68589662758764544
+60
+70
+70
+32326
+32326
+3825434182
+3825434182
+2176235472869883462
+157
+157
+40321
+40321
+2642493400
+2642493400
+11349422734954083207
+230
+230
+230
+230
+58886
+58886
+58886
+58886
+4060537967
+4060537967
+4060537967
+4060537967
+17439881174881499247
+110
+110
+110
+110
+28256
+28256
+28256
+28256
+1850146592
+1850146592
+1850146592
+1850146592
+6307008842936382237
+185
+185
+33209
+33209
+469533113
+469533113
+16270508600839668153
+2342452348372191252
+8358394274051129151
+6015941925678937899
+45209212304752640
+0
+3311302813417472
+3011
+235
+235
+50411
+50411
+4273915115
+4273915115
+16032019417273386219
+40
+40
+10460
+10460
+685539968
+685539968
+2944371742976196996
+10
+10
+10
+10
+7562
+7562
+7562
+7562
+10526090
+10526090
+10526090
+10526090
+1207362328218082698
+40
+40
+40
+40
+30248
+30248
+30248
+30248
+42104360
+42104360
+42104360
+42104360
+4829449312872330792
+20
+20
+15124
+15124
+21052180
+21052180
+2414724656436165396
+17325621262
+14798202888643261246
+14798202871317639984
+733313557101281280
+0
+25212196716544
+93922
+209
+209
+64721
+64721
+3612015825
+3612015825
+4298327304067284177
+116
+116
+29888
+29888
+1958784276
+1958784276
+8412914409237813795
+139
+139
+139
+139
+32971
+32971
+32971
+32971
+2318221515
+2318221515
+2318221515
+2318221515
+14568371613206991237
+184
+184
+184
+184
+3256
+3256
+3256
+3256
+2731805880
+2731805880
+2731805880
+2731805880
+11733016926797240412
+46
+46
+814
+814
+682951470
+682951470
+14148416769642267438
+81348504353524992
+6603226824504769902
+6521878320151244910
+3121027059712
+2976443
+45438324896
+177493456
+155
+155
+4763
+4763
+1247089307
+1247089307
+12024316569138303643
+38
+38
+9911
+9911
+649549229
+649549229
+2789792698176930970
+145
+145
+145
+145
+37813
+37813
+37813
+37813
+2880803542
+2880803542
+2880803542
+2880803542
+9524874440357548388
+25
+25
+25
+25
+22843
+22843
+22843
+22843
+1496148667
+1496148667
+1496148667
+1496148667
+6419397771235519163
+100
+100
+60772
+60772
+3047877988
+3047877988
+6422427504571247972
+1443477661119811673
+9151274787246865883
+7707797126127054210
+556779145334358016
+30
+135578789009686528
+120
+38
+38
+35366
+35366
+146639398
+146639398
+9917828052165691942
+155
+155
+39854
+39854
+2611888879
+2611888879
+11217977318101432942
+206
+206
+206
+206
+52142
+52142
+52142
+52142
+3485078446
+3485078446
+3485078446
+3485078446
+8627229677644342879
+59
+59
+59
+59
+47918
+47918
+47918
+47918
+3897473854
+3897473854
+3897473854
+3897473854
+16739522674641436126
+217
+217
+30169
+30169
+4148327897
+4148327897
+8528916021543859673
+4715814438428801
+18049844445053974527
+18045128630615545726
+274084593735303168
+0
+33889920232
+529530003
+28
+28
+3100
+3100
+3784444956
+3784444956
+6884375165255420956
+199
+199
+51151
+51151
+3352278648
+3352278648
+14397927163503554053
+124
+124
+124
+124
+32380
+32380
+32380
+32380
+1674428028
+1674428028
+1674428028
+1674428028
+7191613621712894248
+31
+31
+31
+31
+40735
+40735
+40735
+40735
+4084178712
+4084178712
+4084178712
+4084178712
+17541414020595993112
+227
+227
+62435
+62435
+510522339
+510522339
+11562368908454130659
+144689134823686320
+4490035896905062909
+4345346762081376589
+254843125825536
+59335
+900942121312190464
+3
+2
+2
+46594
+46594
+406369794
+406369794
+14534506283139642882
+191
+191
+49042
+49042
+3214074855
+3214074855
+13804346390495679084
+253
+253
+253
+253
+18941
+18941
+18941
+18941
+1241376711
+1241376711
+1241376711
+1241376711
+5331477229887743943
+253
+253
+253
+253
+18941
+18941
+18941
+18941
+1241376711
+1241376711
+1241376711
+1241376711
+1119962300480829003
+253
+253
+18941
+18941
+3888597501
+3888597501
+3912237790569908733
+1252776144170737242
+4287396053938863995
+3034619909768126753
+329623638057680896
+18
+77051564778323968
+17
+133
+133
+8581
+8581
+1839079813
+1839079813
+16613845070920950149
+94
+94
+24187
+24187
+1585153609
+1585153609
+6808182911800702616
+211
+211
+211
+211
+55027
+55027
+55027
+55027
+3566407411
+3566407411
+3566407411
+3566407411
+8400074170318945823
+79
+79
+79
+79
+53083
+53083
+53083
+53083
+1278988114
+1278988114
+1278988114
+1278988114
+5493212057949470162
+122
+122
+56954
+56954
+2455887482
+2455887482
+1832899002788601466
+9225628303838154828
+15059956716671777277
+5834328412833622449
+551429311387664384
+1
+10501792714752
+625955
+179
+179
+28595
+28595
+3267850163
+3267850163
+9153561195016843187
+50
+50
+12809
+12809
+839457980
+839457980
+3605444574377418497
+137
+137
+137
+137
+37385
+37385
+37385
+37385
+2275873289
+2275873289
+2275873289
+2275873289
+10385019896691364361
+98
+98
+98
+98
+33380
+33380
+33380
+33380
+3921969761
+3921969761
+3921969761
+3921969761
+558486734703460964
+76
+76
+36940
+36940
+1027117132
+1027117132
+9293182878692708428
+1498574236833570849
+18369294472364093103
+16870720235530522254
+104194069632
+6359501
+887394160128
+3385140
+86
+86
+6486
+6486
+3480951126
+3480951126
+798168492317284694
+149
+149
+38247
+38247
+2506563852
+2506563852
+10765609770743904047
+212
+212
+212
+212
+21747
+21747
+21747
+21747
+1114854552
+1114854552
+1114854552
+1114854552
+4788264263526055448
+83
+83
+83
+83
+21453
+21453
+21453
+21453
+1382091213
+1382091213
+1382091213
+1382091213
+17897597171627841707
+169
+169
+59049
+59049
+814016169
+814016169
+17648575581392266921
+13517500121612288
+3997894488046398340
+3984376987924786052
+1631150340
+1631150340
+54028969984
+211050664
+251
+251
+40699
+40699
+2663816955
+2663816955
+15908659639865483003
+32
+32
+8326
+8326
+545692806
+545692806
+2343732755875536068
+4
+4
+4
+4
+24836
+24836
+24836
+24836
+1631150340
+1631150340
+1631150340
+1631150340
+2538084433844068612
+4
+4
+4
+4
+24836
+24836
+24836
+24836
+1631150340
+1631150340
+1631150340
+1631150340
+2538084433844068612
+4
+4
+24836
+24836
+1631150340
+1631150340
+2538084433844068612
+16778170041221831936
+18156329980370288606
+1378159939148456670
+9556286373888
+2224
+50627857350656
+188603
+241
+241
+241
+241
+4149149937
+4149149937
+443590535786987761
+112
+112
+28927
+28927
+1895763216
+1895763216
+8142241014807010207
+14
+14
+14
+14
+65294
+65294
+65294
+65294
+4279109808
+4279109808
+4279109808
+4279109808
+919306830223440344
+14
+14
+14
+14
+65294
+65294
+65294
+65294
+4279109808
+4279109808
+4279109808
+4279109808
+18378901835667867824
+14
+14
+65294
+65294
+145817358
+145817358
+18003153537922563854
+10521539439851739904
+18444482867766460413
+7922943427914720509
+53415903120
+208655871
+28504246378823680
+25
+6
+6
+40966
+40966
+956473350
+956473350
+7253658039675428870
+159
+159
+40954
+40954
+2684010339
+2684010339
+11527736630516099801
+159
+159
+159
+159
+65429
+65429
+65429
+65429
+1876295580
+1876295580
+1876295580
+1876295580
+13068679881159999385
+159
+159
+159
+159
+38399
+38399
+38399
+38399
+2624574975
+2624574975
+2624574975
+2624574975
+11075861418588755455
+249
+249
+24569
+24569
+3338493945
+3338493945
+11193086034034122745
+18863222570373441
+3458623775724003317
+3439760553153629876
+430311205371904
+25047
+47616622112
+46500607
+186
+186
+11962
+11962
+1011953338
+1011953338
+18353552381139037882
+162
+162
+41611
+41611
+2727048643
+2727048643
+11712584738880934528
+138
+138
+138
+138
+41611
+41611
+41611
+41611
+2727053149
+2727053149
+2727053149
+2727053149
+11712176624915154781
+162
+162
+162
+162
+59554
+59554
+59554
+59554
+1755505111
+1755505111
+1755505111
+1755505111
+9992609988517986469
+69
+69
+53573
+53573
+3283013957
+3283013957
+93191692570513733
+7100109571339454976
+9214058005065104239
+2113948433725649263
+565574321920
+8629979
+537098785792
+32781908
+184
+184
+9400
+9400
+2085692600
+2085692600
+10119965986901796024
+226
+226
+58075
+58075
+3806033345
+3806033345
+16346788747231457742
+71
+71
+71
+71
+18395
+18395
+18395
+18395
+2933606275
+2933606275
+2933606275
+2933606275
+12599742944139316611
+71
+71
+71
+71
+18395
+18395
+18395
+18395
+1199812315
+1199812315
+1199812315
+1199812315
+10197186238116761256
+71
+71
+56135
+56135
+2209274695
+2209274695
+8326778086807755591
+14220256646812795037
+16680162548119236319
+2459905901306441282
+147855571477856256
+0
+2456098207373983744
+0
+32
+32
+45344
+45344
+4019564832
+4019564832
+4082018195804107040
+251
+251
+64370
+64370
+4218574344
+4218574344
+18118638843900173027
+251
+251
+251
+251
+59867
+59867
+59867
+59867
+3792521691
+3792521691
+3792521691
+3792521691
+9371227608750700610
+254
+254
+254
+254
+30458
+30458
+30458
+30458
+2203219704
+2203219704
+2203219704
+2203219704
+9462756601339187360
+223
+223
+20191
+20191
+275402463
+275402463
+14364725877905444575
+680061909029880400
+9221048768515266554
+8540986859485386154
+1061314101248000
+3
+1042931328745472
+15176
+141
+141
+48525
+48525
+4231708045
+4231708045
+14127023794492718477
+78
+78
+20034
+20034
+1312990144
+1312990144
+5639249731358904284
+114
+114
+114
+114
+29250
+29250
+29250
+29250
+1912849730
+1912849730
+1912849730
+1912849730
+13043485834970133178
+114
+114
+114
+114
+29250
+29250
+29250
+29250
+3309466115
+3309466115
+3309466115
+3309466115
+14214048975735665923
+114
+114
+17010
+17010
+63259250
+63259250
+4319720279216833138
+2343740981914472520
+9126262361944880253
+6782521380030407733
+423753702656
+6465968
+2023165772372639744
+7
+162
+162
+20386
+20386
+2639679394
+2639679394
+14949991418609160098
+186
+186
+47629
+47629
+3121452358
+3121452358
+13406535796860608780
+93
+93
+93
+93
+23984
+23984
+23984
+23984
+2846907746
+2846907746
+2846907746
+2846907746
+12227375451314979682
+93
+93
+93
+93
+23984
+23984
+23984
+23984
+1566747056
+1566747056
+1566747056
+1566747056
+243943904774227702
+93
+93
+45149
+45149
+1655287901
+1655287901
+3496752655100391517
+3463382601507540257
+18012139547625594879
+14548756946118054622
+45575552864
+44507375
+261710676051886080
+14
+4
+4
+57860
+57860
+2870731268
+2870731268
+1038791715183124996
+223
+223
+57272
+57272
+3753387818
+3753387818
+16120677927751690639
+127
+127
+127
+127
+48995
+48995
+48995
+48995
+2625879914
+2625879914
+2625879914
+2625879914
+11278068440602971658
+223
+223
+223
+223
+55535
+55535
+55535
+55535
+3668386031
+3668386031
+3668386031
+3668386031
+9414529760661121987
+251
+251
+7675
+7675
+1424236027
+1424236027
+17407952358526426619
+8365172645207244801
+18255268518741519847
+9890095873534275046
+142720663680
+8710978
+2512984526
+628246131
+254
+254
+24318
+24318
+3179962110
+3179962110
+10081525506710855422
+128
+128
+32901
+32901
+2156244546
+2156244546
+9260999811268405294
+128
+128
+128
+128
+32976
+32976
+32976
+32976
+986742945
+986742945
+986742945
+986742945
+4238028785902746529
+2
+2
+2
+2
+834
+834
+834
+834
+42265410
+42265410
+42265410
+42265410
+17187120746701794931
+1
+1
+41217
+41217
+1115005185
+1115005185
+8365218566998696193
+4093772099937637546
+9142276445491953406
+5048504345554315860
+18125251575808
+67521
+2496422763036672
+0
+69
+69
+35653
+35653
+3188689733
+3188689733
+9450943948828674885
+93
+93
+23854
+23854
+1563299714
+1563299714
+6714321148445846334
+174
+174
+174
+174
+40238
+40238
+40238
+40238
+489590908
+489590908
+489590908
+489590908
+2102793129771094140
+234
+234
+234
+234
+53993
+53993
+53993
+53993
+3538487233
+3538487233
+3538487233
+3538487233
+159041890890150750
+186
+186
+29882
+29882
+1106277562
+1106277562
+8995800124880876730
+9799868181034115140
+16968129619808693735
+7168261438774578595
+116201434304
+113477963
+123728376128
+30207123
+153
+153
+54937
+54937
+663672473
+663672473
+6338569923590018713
+102
+102
+26260
+26260
+1721011739
+1721011739
+7391689136044183573
+204
+204
+204
+204
+11461
+11461
+11461
+11461
+237317339
+237317339
+237317339
+237317339
+79947255924468949
+51
+51
+51
+51
+12619
+12619
+12619
+12619
+918784331
+918784331
+918784331
+918784331
+3837144956011776331
+102
+102
+10598
+10598
+3631294822
+3631294822
+12108174150119532902
+6558797772668143888
+9197942531591995255
+2639144758923851367
+7097113049563136
+1613
+157423257255936
+2290
+205
+205
+46285
+46285
+910800077
+910800077
+9293872740518442189
+76
+76
+19666
+19666
+1288859027
+1288859027
+5535607373875486974
+70
+70
+70
+70
+26185
+26185
+26185
+26185
+1717122761
+1717122761
+1717122761
+1717122761
+18408805190486450352
+145
+145
+145
+145
+37465
+37465
+37465
+37465
+2992215629
+2992215629
+2992215629
+2992215629
+12851465705781976653
+50
+50
+19250
+19250
+3384167218
+3384167218
+9152871333191109426
+1024015932902867968
+5692497151624265060
+4668481218721397092
+55595554304
+217170134
+3311711236
+3311711236
+159
+159
+62111
+62111
+820245151
+820245151
+12810687942026850975
+6
+6
+1712
+1712
+112212211
+112212211
+481947776672001138
+6
+6
+6
+6
+54784
+54784
+54784
+54784
+4055946764
+4055946764
+4055946764
+4055946764
+16389921812085003780
+6
+6
+6
+6
+214
+214
+214
+214
+217170134
+217170134
+217170134
+217170134
+352253508230168790
+96
+96
+3424
+3424
+3474722144
+3474722144
+5636056131682700640
+7937353069166592570
+9112889783114850302
+1175536713948257732
+1091596030966759424
+0
+148374129051959296
+32
+197
+197
+31941
+31941
+3278339269
+3278339269
+10509320600431328453
+92
+92
+23745
+23745
+1556158780
+1556158780
+6683651067905238134
+142
+142
+142
+142
+41166
+41166
+41166
+41166
+2401640654
+2401640654
+2401640654
+2401640654
+11207727905174331598
+232
+232
+232
+232
+3306
+3306
+3306
+3306
+4066512104
+4066512104
+4066512104
+4066512104
+13302949819403341033
+58
+58
+33594
+33594
+1016628026
+1016628026
+7937423473278223162
+49579464086004264
+16428143889388369855
+16378564425302365591
+6916695777280
+1649068
+638142507170922496
+8
+195
+195
+39363
+39363
+917674435
+917674435
+18303696705615468995
+60
+60
+15462
+15462
+1013363347
+1013363347
+4352362435591290752
+225
+225
+225
+225
+58161
+58161
+58161
+58161
+1798432330
+1798432330
+1798432330
+1798432330
+7724201194732033610
+135
+135
+135
+135
+51084
+51084
+51084
+51084
+3348703660
+3348703660
+3348703660
+3348703660
+11121966576826335110
+60
+60
+26172
+26172
+3377292860
+3377292860
+143047368094082620
+9512381418289359872
+17862357839448637438
+8349976421159277566
+64202195360
+250789825
+86966694953615360
+19
+229
+229
+997
+997
+282330085
+282330085
+4223594075218248677
+88
+88
+22591
+22591
+1480578295
+1480578295
+6359035356358330019
+161
+161
+161
+161
+49583
+49583
+49583
+49583
+4072653230
+4072653230
+4072653230
+4072653230
+17491912423654586638
+161
+161
+161
+161
+44993
+44993
+44993
+44993
+2935144385
+2935144385
+2935144385
+2935144385
+1077134099435891833
+26
+26
+64538
+64538
+4012637210
+4012637210
+14223149998491302938
+292075090288898
+14078111407744476022
+14077819332654187124
+7146013912
+446625869
+2005821944758272
+114
+201
+201
+7881
+7881
+2508463817
+2508463817
+18347808177409760969
+108
+108
+27783
+27783
+1820843606
+1820843606
+7820463739802417792
+216
+216
+216
+216
+34011
+34011
+34011
+34011
+2851046617
+2851046617
+2851046617
+2851046617
+395743585199162584
+141
+141
+141
+141
+47181
+47181
+47181
+47181
+2594109517
+2594109517
+2594109517
+2594109517
+9248106010929723469
+54
+54
+57654
+57654
+1786503478
+1786503478
+98935896299790646
+3999340574401895424
+8638963978861281231
+4639623404459385807
+71211820032
+4346424
+770057406208
+11750143
+183
+183
+58295
+58295
+3738624951
+3738624951
+14429389096501044151
+18
+18
+4664
+4664
+305697924
+305697924
+1312962588329444332
+36
+36
+36
+36
+9230
+9230
+9230
+9230
+2492343312
+2492343312
+2492343312
+2492343312
+16159347092531061787
+144
+144
+144
+144
+36920
+36920
+36920
+36920
+2420265528
+2420265528
+2420265528
+2420265528
+10407679127221064248
+72
+72
+7240
+7240
+556342344
+556342344
+4017354977208507464
+5782630717922381826
+17574168754712386175
+11791538036790004349
+19783782640
+309121603
+1531687973513330688
+1
+225
+225
+28129
+28129
+1821994465
+1821994465
+10141793710516039137
+120
+120
+30793
+30793
+2018076361
+2018076361
+8667571972839342798
+240
+240
+240
+240
+37108
+37108
+37108
+37108
+2603913460
+2603913460
+2603913460
+2603913460
+11183723150603510484
+195
+195
+195
+195
+53827
+53827
+53827
+53827
+3530347075
+3530347075
+3530347075
+3530347075
+5939353197262414731
+30
+30
+37406
+37406
+2472972830
+2472972830
+8304950363193512478
+5204085845338130626
+17077647380727065839
+11873561535388935213
+7791339120
+121739673
+36719457517568
+136790
+49
+49
+13105
+13105
+3321049905
+3321049905
+13241532267361415985
+115
+115
+29491
+29491
+1932734556
+1932734556
+8301031713912732690
+118
+118
+118
+118
+26230
+26230
+26230
+26230
+3496371825
+3496371825
+3496371825
+3496371825
+15016802648431330425
+217
+217
+217
+217
+55705
+55705
+55705
+55705
+3342965145
+3342965145
+3342965145
+3342965145
+16663768982029308945
+206
+206
+52430
+52430
+973917390
+973917390
+5205211806348135630
+4921610738360930320
+18257381738698504702
+13335771000337574382
+188948615706705920
+41
+118908612771840
+108
+11
+11
+3851
+3851
+1479413515
+1479413515
+1919316410982338315
+47
+47
+12047
+12047
+789548005
+789548005
+3391082860766870183
+211
+211
+211
+211
+54211
+54211
+54211
+54211
+3533653955
+3533653955
+3533653955
+3533653955
+10565242157228455135
+61
+61
+61
+61
+15676
+15676
+15676
+15676
+4101782825
+4101782825
+4101782825
+4101782825
+17617023158853695785
+244
+244
+61684
+61684
+2815553780
+2815553780
+16527427662727213300
+9272700603837546881
+15848142895132161511
+6575442291294614630
+1272122254
+318030563
+464625651840
+28358499
+56
+56
+31288
+31288
+3658906168
+3658906168
+7804903638686923320
+227
+227
+58273
+58273
+3819018148
+3819018148
+16402558050614310345
+143
+143
+143
+143
+2959
+2959
+2959
+2959
+1272122254
+1272122254
+1272122254
+1272122254
+5463723482399298300
+227
+227
+227
+227
+49891
+49891
+49891
+49891
+2465514211
+2465514211
+2465514211
+2465514211
+1365930870599824575
+199
+199
+34247
+34247
+636061127
+636061127
+10641840435022628295
+1189636698066403354
+13688544693774083035
+12498907995707679681
+423657286964084736
+23
+36408714458038272
+8
+37
+37
+48677
+48677
+1138474533
+1138474533
+7946748534594453029
+91
+91
+23426
+23426
+1535255613
+1535255613
+6593872652901739913
+214
+214
+214
+214
+53774
+53774
+53774
+53774
+3588301326
+3588301326
+3588301326
+3588301326
+9070568571591834578
+91
+91
+91
+91
+15176
+15176
+15176
+15176
+2223520599
+2223520599
+2223520599
+2223520599
+9549948234134145527
+218
+218
+16858
+16858
+3156492762
+3156492762
+10499995539115098586
+765805450751183104
+11455733291060026870
+10689927840308843766
+9613239632
+600827477
+617190459965440
+561
+171
+171
+26283
+26283
+1891657387
+1891657387
+17372370942948304555
+42
+42
+10905
+10905
+714734833
+714734833
+3069762736621557616
+81
+81
+81
+81
+25938
+25938
+25938
+25938
+1023305042
+1023305042
+1023305042
+1023305042
+4395061681632559790
+21
+21
+21
+21
+9813
+9813
+9813
+9813
+600827477
+600827477
+600827477
+600827477
+16415592419597892650
+84
+84
+39252
+39252
+2403309908
+2403309908
+1074373130761247060
+577626452633059328
+12681573028941311808
+12103946576308252480
+3593470208
+3593470208
+3407392320
+3407392320
+255
+255
+65279
+65279
+701497087
+701497087
+8451586948703715071
+0
+0
+128
+128
+8391787
+8391787
+36042452036463953
+0
+0
+0
+0
+256
+256
+256
+256
+3593470208
+3593470208
+3593470208
+3593470208
+9995157125005836544
+0
+0
+0
+0
+256
+256
+256
+256
+3593470208
+3593470208
+3593470208
+3593470208
+9995157125005836544
+0
+0
+256
+256
+3593470208
+3593470208
+9995157125005836544
+10413732463228132610
+18434771035622145383
+8021038572394012773
+181820891392
+11097466
+13013578908
+813348681
+189
+189
+17085
+17085
+2874491581
+2874491581
+3205113210006225597
+66
+66
+17085
+17085
+1119704362
+1119704362
+4809093616538788299
+33
+33
+33
+33
+41310
+41310
+41310
+41310
+1432265002
+1432265002
+1432265002
+1432265002
+6151531616642744874
+132
+132
+132
+132
+34170
+34170
+34170
+34170
+2225689978
+2225689978
+2225689978
+2225689978
+624124008084212301
+66
+66
+48450
+48450
+1420475714
+1420475714
+15241630863703326018
+14780815695101823940
+18439623497458723823
+3658807802356899883
+88686819776
+86608222
+1606367657984
+5984
+49
+49
+54321
+54321
+1523504177
+1523504177
+1322930334774252593
+115
+115
+29652
+29652
+1943309477
+1943309477
+8346450651793860023
+217
+217
+217
+217
+31173
+31173
+31173
+31173
+2787473876
+2787473876
+2787473876
+2787473876
+11972109177557367764
+118
+118
+118
+118
+29022
+29022
+29022
+29022
+1965656414
+1965656414
+1965656414
+1965656414
+17665802052161052686
+206
+206
+11214
+11214
+2771463118
+2771463118
+17123813738935299022
+80257761715159175
+6043610139804187367
+5963352378089028192
+179785974656
+10973265
+459042026368
+28017701
+120
+120
+55160
+55160
+2890389368
+2890389368
+13700188220993034104
+225
+225
+57620
+57620
+3776191946
+3776191946
+16218620913214880642
+195
+195
+195
+195
+17300
+17300
+17300
+17300
+3692315561
+3692315561
+3692315561
+3692315561
+15858374546371621673
+15
+15
+15
+15
+3665
+3665
+3665
+3665
+245854289
+245854289
+245854289
+245854289
+14746878998286155342
+135
+135
+10375
+10375
+1404577927
+1404577927
+4746555852716517511
+3448235534647333
+16933510066058165621
+16930061830523518288
+8950793661054976
+2035
+124364039840
+121449257
+154
+154
+26522
+26522
+26896282
+26896282
+3819780708627015578
+166
+166
+42521
+42521
+2786698879
+2786698879
+11968780551077674835
+172
+172
+172
+172
+3251
+3251
+3251
+3251
+213896371
+213896371
+213896371
+213896371
+916869196684446899
+43
+43
+43
+43
+11459
+11459
+11459
+11459
+750989299
+750989299
+750989299
+750989299
+16955340058431532631
+101
+101
+39013
+39013
+4268071013
+4268071013
+14626963365082536037
+23116704802545945
+6655194303820654427
+6632077599018108482
+55262891984551936
+49
+158526524696297472
+8
+164
+164
+22692
+22692
+2648004772
+2648004772
+16405639801842522276
+218
+218
+56037
+56037
+3672462406
+3672462406
+15773105932272060984
+182
+182
+182
+182
+46926
+46926
+46926
+46926
+3066320206
+3066320206
+3066320206
+3066320206
+775838832367544043
+173
+173
+173
+173
+44499
+44499
+44499
+44499
+357805489
+357805489
+357805489
+357805489
+1536762723960537777
+91
+91
+42843
+42843
+1646962523
+1646962523
+2041104271867029339
+4799570589618307094
+14411485719017028575
+9611915129398721481
+8344969770768007168
+1
+12709779289931776
+722
+105
+105
+27753
+27753
+409037929
+409037929
+13556995799864405097
+105
+105
+27081
+27081
+1774811623
+1774811623
+7622757880097659842
+75
+75
+75
+75
+18891
+18891
+18891
+18891
+1942964683
+1942964683
+1942964683
+1942964683
+17568341808192024594
+45
+45
+45
+45
+10029
+10029
+10029
+10029
+3476891437
+3476891437
+3476891437
+3476891437
+14933135011639443531
+150
+150
+37782
+37782
+3885929366
+3885929366
+4889748273845146518
+18577907080237120
+8646628297674751983
+8628050390594514863
+179838891008
+10976494
+791080912640
+12070936
+151
+151
+34967
+34967
+2889975959
+2889975959
+14745096757008500887
+22
+22
+5870
+5870
+384728522
+384728522
+1652396424008530636
+52
+52
+52
+52
+46139
+46139
+46139
+46139
+3745231913
+3745231913
+3745231913
+3745231913
+12642254694995702809
+208
+208
+208
+208
+53486
+53486
+53486
+53486
+3500637422
+3500637422
+3500637422
+3500637422
+15016898679550737646
+104
+104
+30568
+30568
+1404991336
+1404991336
+3701647316701050728
+1261007906501822976
+6893282008795406239
+5632274102293583263
+204041594432
+49814842
+111921719744135168
+99
+102
+102
+45414
+45414
+1106817382
+1106817382
+17032443079756919142
+153
+153
+39282
+39282
+2574442621
+2574442621
+11057146863745041864
+102
+102
+102
+102
+42579
+42579
+42579
+42579
+2178131567
+2178131567
+2178131567
+2178131567
+16728287318130271812
+102
+102
+102
+102
+25914
+25914
+25914
+25914
+1727536442
+1727536442
+1727536442
+1727536442
+7227857856823303482
+153
+153
+20121
+20121
+3188149913
+3188149913
+1414300993952632473
+8367692656125444096
+8642246520293287386
+274553864167843290
+1194116506
+1194116506
+196204005980897280
+43
+101
+101
+14949
+14949
+3100850789
+3100850789
+10059839340580911717
+89
+89
+22947
+22947
+1503868130
+1503868130
+6459064439447627310
+154
+154
+154
+154
+50586
+50586
+50586
+50586
+1194116506
+1194116506
+1194116506
+1194116506
+8386904733128639898
+154
+154
+154
+154
+50586
+50586
+50586
+50586
+1194116506
+1194116506
+1194116506
+1194116506
+8386904733128639898
+154
+154
+50586
+50586
+1194116506
+1194116506
+8386904733128639898
+1301822188999747586
+2170636614045265503
+868814425045517917
+34357496478957568
+488
+971546123264
+926538
+245
+245
+5109
+5109
+199234549
+199234549
+16856511095167259637
+80
+80
+20535
+20535
+1345845295
+1345845295
+5780361531495909480
+5
+5
+5
+5
+1398
+1398
+1398
+1398
+91885558
+91885558
+91885558
+91885558
+4321784341736392914
+20
+20
+20
+20
+5592
+5592
+5592
+5592
+1071125992
+1071125992
+1071125992
+1071125992
+4600449199162060776
+10
+10
+60426
+60426
+4095732746
+4095732746
+1590232978542291978
+294986875646001232
+4564941346713856855
+4269954471067855623
+4547243608637440
+64
+280754635866112
+65368
+175
+175
+40111
+40111
+3752893615
+3752893615
+17917318903586921647
+10
+10
+2758
+2758
+180810244
+180810244
+776574088094620384
+40
+40
+40
+40
+43057
+43057
+43057
+43057
+2819631025
+2819631025
+2819631025
+2819631025
+12794770185341086834
+160
+160
+160
+160
+41158
+41158
+41158
+41158
+2663817280
+2663817280
+2663817280
+2663817280
+11441007888354166336
+80
+80
+25424
+25424
+542073680
+542073680
+529425170122629968
+10628567278595350624
+16129307705981335551
+5500740427385984927
+1976972880486858752
+6
+10503624180
+656476511
+29
+29
+3357
+3357
+612568349
+612568349
+2624807334429527325
+71
+71
+18255
+18255
+1196375771
+1196375771
+5138394811345357275
+92
+92
+92
+92
+24156
+24156
+24156
+24156
+1534041692
+1534041692
+1534041692
+1534041692
+6589428110837390940
+23
+23
+23
+23
+38679
+38679
+38679
+38679
+3689387798
+3689387798
+3689387798
+3689387798
+15895029471982884630
+226
+226
+62178
+62178
+3682398946
+3682398946
+15821936739280024290
+9881187936779649027
+11505498545892032483
+1624310609112383456
+15523262488
+242550976
+32029265688
+500457276
+252
+252
+47612
+47612
+2354559484
+2354559484
+8526693073526700540
+192
+192
+49250
+49250
+3227653582
+3227653582
+13862666580923045265
+24
+24
+24
+24
+12314
+12314
+12314
+12314
+2638360603
+2638360603
+2638360603
+2638360603
+11331672510532472475
+96
+96
+96
+96
+26816
+26816
+26816
+26816
+1853163712
+1853163712
+1853163712
+1853163712
+7959277539073286970
+3
+3
+17923
+17923
+1940407811
+1940407811
+9920051000182851075
+36320322236448770
+18275466513999698871
+18239146191763250101
+61900497879040
+225
+139041457344
+33945668
+89
+89
+30041
+30041
+4176901465
+4176901465
+11486607643229189465
+101
+101
+25937
+25937
+1699844320
+1699844320
+7300775765593483526
+53
+53
+53
+53
+21812
+21812
+21812
+21812
+1429223500
+1429223500
+1429223500
+1429223500
+17989690612029523130
+212
+212
+212
+212
+53588
+53588
+53588
+53588
+827637985
+827637985
+827637985
+827637985
+3554690387541401825
+166
+166
+35494
+35494
+118065830
+118065830
+6960136430480362150
+581052338635014144
+16067984201583684394
+15486931862948670250
+366347321344
+349376
+3404262154
+3404262154
+223
+223
+65503
+65503
+3937206239
+3937206239
+17577423455482871775
+4
+4
+1024
+1024
+67160744
+67160744
+288453203321554992
+128
+128
+128
+128
+32768
+32768
+32768
+32768
+1275101269
+1275101269
+1275101269
+1275101269
+4740597526061678640
+8
+8
+8
+8
+2048
+2048
+2048
+2048
+134567104
+134567104
+134567104
+134567104
+577309698219660480
+32
+32
+32
+32
+357761056
+357761056
+869320618226679840
+9476523639152082945
+17284641921711275069
+7808118282559192124
+111122280267907072
+98
+95179081504
+92948321
+250
+250
+28666
+28666
+983265274
+983265274
+6662123356644143098
+160
+160
+40969
+40969
+2684954275
+2684954275
+11531790803861426629
+10
+10
+10
+10
+2848
+2848
+2848
+2848
+193644832
+193644832
+193644832
+193644832
+812643289731352864
+130
+130
+130
+130
+712
+712
+712
+712
+2991063778
+2991063778
+2991063778
+2991063778
+14245181813898609361
+5
+5
+36869
+36869
+3311702021
+3311702021
+11784620717065408517
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..8b0fd27618c8
--- /dev/null
+++ b/contrib/bc/tests/bc/decimal.txt
@@ -0,0 +1,65 @@
+0
+0.0
+.00000
+000000000000000000000000.00000000000000000000000
+000000000000000000000000000135482346782356
+000000000000000000000000002
+1
+11
+123
+7505
+1023468723275435238491972521917846
+434347243243170586739207351703827039802735270902738927392073903793796
+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
+2893729837\
+
+29837.29837048
diff --git a/contrib/bc/tests/bc/decimal_results.txt b/contrib/bc/tests/bc/decimal_results.txt
new file mode 100644
index 000000000000..a54a543d8cad
--- /dev/null
+++ b/contrib/bc/tests/bc/decimal_results.txt
@@ -0,0 +1,76 @@
+0
+0
+0
+0
+135482346782356
+2
+1
+11
+123
+7505
+1023468723275435238491972521917846
+434347243243170586739207351703827039802735270902738927392073903793796
+43434724324317058673920735170382703980273527090273892739207390379379\
+60379637893607893607893670530278200795207952702873892786172916728961\
+783907893607418973587857386079679267926737520730925372983782793652793
+-1
+-203
+-57
+-18586
+-31378682943772818461924738352952347258
+-8239456287456735894950672387239865203756982376208346745096273452730\
+96287563846592384526349872634895763257893467523987578690283762897568\
+459072348758071071087813501875908127359018715023841710239872301387278
+.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
+2893729837
+29837.29837048
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/divmod.txt b/contrib/bc/tests/bc/divmod.txt
new file mode 100644
index 000000000000..5a49acdf833f
--- /dev/null
+++ b/contrib/bc/tests/bc/divmod.txt
@@ -0,0 +1,64 @@
+scale = 20
+v = divmod(0, 1, v[]); v[0]; v
+v = divmod(0, 321566, v[]); v[0]; v
+v = divmod(0, 0.3984567238456, v[]); v[0]; v
+v = divmod(1, 1, v[]); v[0]; v
+v = divmod(1, 1287469297356, v[]); v[0]; v
+v = divmod(1, 0.2395672438567234, v[]); v[0]; v
+v = divmod(1, 237586239856.0293596728392360, v[]); v[0]; v
+v = divmod(1249687284356, 3027949207835207, v[]); v[0]; v
+v = divmod(378617298617396719, 35748521, v[]); v[0]; v
+v = divmod(9348576237845624358, 0.9857829375461, v[]); v[0]; v
+v = divmod(35768293846193284, 2374568947.045762839567823, v[]); v[0]; v
+v = divmod(-78987234567812345, 876542837618936, v[]); v[0]; v
+v = divmod(-356789237555535468, 0.3375273860984786903, v[]); v[0]; v
+v = divmod(-5203475364850390, 435742903748307.70869378534043296404530458, v[]); v[0]; v
+v = divmod(-0.37861723347576903, 7385770896, v[]); v[0]; v
+v = divmod(-0.399454682043962, 0.34824389304, v[]); v[0]; v
+v = divmod(-0.6920414523873204, 356489645223.76076045304879030, v[]); v[0]; v
+v = divmod(-35872917389671.7573280963748, 73924708, v[]); v[0]; v
+v = divmod(-78375896314.4836709876983, 0.78356798637817, v[]); v[0]; v
+v = divmod(-2374123896417.143789621437581, 347821469423789.1473856783960, v[]); v[0]; v
+v = divmod(-896729350238549726, -34976289345762, v[]); v[0]; v
+v = divmod(-2374568293458762348596, -0.8792370647234987679, v[]); v[0]; v
+v = divmod(-237584692306721845726038, -21783910782374529637.978102738746189024761, v[]); v[0]; v
+v = divmod(-0.23457980123576298375682, -1375486293874612, v[]); v[0]; v
+v = divmod(-0.173897061862478951264, -0.8179327486017634987516298745, v[]); v[0]; v
+v = divmod(-0.9186739823576829347586, -0.235678293458756239846, v[]); v[0]; v
+v = divmod(-0.9375896183746982374568, -13784962873546.0928729395476283745, v[]); v[0]; v
+v = divmod(-2930754618923467.12323745862937465, -734869238465, v[]); v[0]; v
+v = divmod(-23745861923467.874675129834675, -0.23542357869124756, v[]); v[0]; v
+v = divmod(-3878923750692883.7238596702834756902, -7384192674957215364986723.9738461923487621983, v[]); v[0]; v
+v = divmod(1, 0.00000000000000000000000000000000000000000002346728372937352457354204563027, v[]); v[0]; v
+scale = 0
+v = divmod(0, 1, v[]); v[0]; v
+v = divmod(0, 321566, v[]); v[0]; v
+v = divmod(0, 0.3984567238456, v[]); v[0]; v
+v = divmod(1, 1, v[]); v[0]; v
+v = divmod(1, 1287469297356, v[]); v[0]; v
+v = divmod(1, 0.2395672438567234, v[]); v[0]; v
+v = divmod(1, 237586239856.0293596728392360, v[]); v[0]; v
+v = divmod(1249687284356, 3027949207835207, v[]); v[0]; v
+v = divmod(378617298617396719, 35748521, v[]); v[0]; v
+v = divmod(9348576237845624358, 0.9857829375461, v[]); v[0]; v
+v = divmod(35768293846193284, 2374568947.045762839567823, v[]); v[0]; v
+v = divmod(-78987234567812345, 876542837618936, v[]); v[0]; v
+v = divmod(-356789237555535468, 0.3375273860984786903, v[]); v[0]; v
+v = divmod(-5203475364850390, 435742903748307.70869378534043296404530458, v[]); v[0]; v
+v = divmod(-0.37861723347576903, 7385770896, v[]); v[0]; v
+v = divmod(-0.399454682043962, 0.34824389304, v[]); v[0]; v
+v = divmod(-0.6920414523873204, 356489645223.76076045304879030, v[]); v[0]; v
+v = divmod(-35872917389671.7573280963748, 73924708, v[]); v[0]; v
+v = divmod(-78375896314.4836709876983, 0.78356798637817, v[]); v[0]; v
+v = divmod(-2374123896417.143789621437581, 347821469423789.1473856783960, v[]); v[0]; v
+v = divmod(-896729350238549726, -34976289345762, v[]); v[0]; v
+v = divmod(-2374568293458762348596, -0.8792370647234987679, v[]); v[0]; v
+v = divmod(-237584692306721845726038, -21783910782374529637.978102738746189024761, v[]); v[0]; v
+v = divmod(-0.23457980123576298375682, -1375486293874612, v[]); v[0]; v
+v = divmod(-0.173897061862478951264, -0.8179327486017634987516298745, v[]); v[0]; v
+v = divmod(-0.9186739823576829347586, -0.235678293458756239846, v[]); v[0]; v
+v = divmod(-0.9375896183746982374568, -13784962873546.0928729395476283745, v[]); v[0]; v
+v = divmod(-2930754618923467.12323745862937465, -734869238465, v[]); v[0]; v
+v = divmod(-23745861923467.874675129834675, -0.23542357869124756, v[]); v[0]; v
+v = divmod(-3878923750692883.7238596702834756902, -7384192674957215364986723.9738461923487621983, v[]); v[0]; v
+v = divmod(1, 0.00000000000000000000000000000000000000000002346728372937352457354204563027, v[]); v[0]; v
diff --git a/contrib/bc/tests/bc/divmod_results.txt b/contrib/bc/tests/bc/divmod_results.txt
new file mode 100644
index 000000000000..c55e9303d935
--- /dev/null
+++ b/contrib/bc/tests/bc/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/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..f89a3ca699ff
--- /dev/null
+++ b/contrib/bc/tests/bc/errors.txt
@@ -0,0 +1,304 @@
+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
+2^340282366920938463463374607431768211456)
+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)
+for (i = 0; i < 10; ++i) { print 4, 5 define
+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[])
+abs("string")
+abs(a[])
+scale("string")
+v = "s"; scale(v)
+v += "string"
+scale(b[])
+sqrt("string")
+sqrt(c[])
+sqrt
+length
+abs
+sqrt(1
+length(1
+abs(1
+divmod 24
+modexp 23
+divmod(if
+modexp(if
+divmod(24)
+modexp(24)
+divmod(24 24)
+modexp(24 24)
+divmod(24,)
+modexp(24,)
+divmod(24,
+modexp(24,
+divmod(24,5
+modexp(24,5
+divmod(24,5)
+modexp(24,5)
+divmod(24,5,)
+modexp(24,5,)
+divmod(24,5,
+modexp(24,5,
+divmod(24,5,4
+modexp(24,5,4
+divmod(24,5,a
+modexp(24,5,a
+divmod(24,5,a[]
+divmod(24,5,a[
+divmod(24,5,a[2
+divmod(24,5,a[2]
+divmod(24,5,a[];
+modexp(24,5,a;
+divmod(24,5,a[];)
+modexp(24,5,a;)
+divmod(24,5,4)
+scale(4.5) modexp(25,5,5)
+scale(.2093
+a2(0,0)
+v = "stuff" + "other"
+v = "stuff"; v + v
+v = "stuff"; v * 3
+v = "stuff"; v - 3
+v = "stuff"; v / 3
+v = "stuff"; divmod(v, 3, a[])
+v = "stuff"; modexp(v, 3, 2)
+define f(x) { x * x }; f("stuff")
+define f(x) { x * x }; v = "stuff"; f(v)
+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/errors/25.txt b/contrib/bc/tests/bc/errors/25.txt
new file mode 100644
index 000000000000..973dd948b9e5
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/25.txt
@@ -0,0 +1,4 @@
+define void g(x) {
+ print x
+ return x
+}
diff --git a/contrib/bc/tests/bc/errors/26.txt b/contrib/bc/tests/bc/errors/26.txt
new file mode 100644
index 000000000000..88de6bbf4605
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/26.txt
Binary files differ
diff --git a/contrib/bc/tests/bc/errors/27.txt b/contrib/bc/tests/bc/errors/27.txt
new file mode 100644
index 000000000000..6231bd30f57a
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/27.txt
@@ -0,0 +1 @@
+g^gggg<grgggggg[ggg^gggggggguggggg8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888gggggg[ggg^gggg<grgggggg[ggg^gggggggguggggg88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888gg@gggggMggggg[ggg^gl2(4)58)
diff --git a/contrib/bc/tests/bc/errors/28.txt b/contrib/bc/tests/bc/errors/28.txt
new file mode 100644
index 000000000000..84cb0db8103f
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/28.txt
@@ -0,0 +1,2 @@
+
+l(l22(nllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllLlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll0( \ No newline at end of file
diff --git a/contrib/bc/tests/bc/errors/29.txt b/contrib/bc/tests/bc/errors/29.txt
new file mode 100644
index 000000000000..36368adfaa7d
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/29.txt
@@ -0,0 +1,20 @@
+uobase = obaseseed=273546
+seed=N7273546
+read()@546
+seed=946
+read()@546
+seed=99999G9999999CDDDDDDDCDDDDDDDN7273546
+eed=273546
+seed=N7273546
+read()@546
+seez=9999CDDDDDDDN7"73546
+eed=273546
+seed=N727354546
+seed=99999G99999999999999N7273546
+eed=273546
+seed=N7273546
+read()@546
+seed=9"99CDDDDDDDN7273546
+eed=273546
+seed=N72tuinj46
+seed=99999G9999999999999C \ No newline at end of file
diff --git a/contrib/bc/tests/bc/errors/30.txt b/contrib/bc/tests/bc/errors/30.txt
new file mode 100644
index 000000000000..1f3a7d215c50
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/30.txt
@@ -0,0 +1,3 @@
+ale--#80)
+ezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
+zzzzzzzzzzzzzzzzzzzzzzzzzzzzdzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzfzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz[zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz \ No newline at end of file
diff --git a/contrib/bc/tests/bc/errors/31.txt b/contrib/bc/tests/bc/errors/31.txt
new file mode 100644
index 000000000000..621ad12fc4fd
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/31.txt
@@ -0,0 +1,3 @@
+l(ezzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzizzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz^zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzint( zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz^zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzpp=pm =x=p
+p^pv =x=pv =x= "striu(v)zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzhzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzZzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzbzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzpp=pm =x=p
+p^pv =x=pv =x= "striu(v)zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzhzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzZzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz( \ No newline at end of file
diff --git a/contrib/bc/tests/bc/errors/32.txt b/contrib/bc/tests/bc/errors/32.txt
new file mode 100644
index 000000000000..198aa1a6ba0d
--- /dev/null
+++ b/contrib/bc/tests/bc/errors/32.txt
Binary files differ
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/leadingzero.txt b/contrib/bc/tests/bc/leadingzero.txt
new file mode 100644
index 000000000000..77c7dcd08ef9
--- /dev/null
+++ b/contrib/bc/tests/bc/leadingzero.txt
@@ -0,0 +1,12 @@
+plznl(0.01)
+plznl(-0.01)
+plznl(.01)
+plznl(-.01)
+plznl(1.01)
+plznl(-1.01)
+pnlznl(0.01)
+pnlznl(-0.01)
+pnlznl(.01)
+pnlznl(-.01)
+pnlznl(1.01)
+pnlznl(-1.01)
diff --git a/contrib/bc/tests/bc/leadingzero_results.txt b/contrib/bc/tests/bc/leadingzero_results.txt
new file mode 100644
index 000000000000..4b542860a773
--- /dev/null
+++ b/contrib/bc/tests/bc/leadingzero_results.txt
@@ -0,0 +1,12 @@
+0.01
+-0.01
+0.01
+-0.01
+1.01
+-1.01
+.01
+-.01
+.01
+-.01
+1.01
+-1.01
diff --git a/contrib/bc/tests/bc/length.txt b/contrib/bc/tests/bc/length.txt
new file mode 100644
index 000000000000..feb4134ffabd
--- /dev/null
+++ b/contrib/bc/tests/bc/length.txt
@@ -0,0 +1,132 @@
+length(0)
+length(0.0000)
+length(0.00000000)
+length(0.00000000000)
+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..3501dea2a063
--- /dev/null
+++ b/contrib/bc/tests/bc/length_results.txt
@@ -0,0 +1,130 @@
+1
+4
+8
+11
+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..0032da1966ff
--- /dev/null
+++ b/contrib/bc/tests/bc/lib2.txt
@@ -0,0 +1,476 @@
+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(0, 3)
+root(0, 4)
+root(0, 5)
+root(0.0000000000000, 3)
+root(0.0000000000000, 4)
+root(0.0000000000000, 5)
+root(16, 4)
+root(3125, 5)
+root(-3125, 5)
+gcd(285, 35)
+gcd(1, 6)
+gcd(5, 1)
+gcd(8, 12)
+gcd(40, 4096)
+lcm(40, 4096)
+lcm(555, 55)
+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..f0753aff31a4
--- /dev/null
+++ b/contrib/bc/tests/bc/lib2_results.txt
@@ -0,0 +1,711 @@
+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
+0
+0
+0
+0
+0
+0
+2.00000000000000000000
+5.00000000000000000000
+-5.00000000000000000000
+5
+1
+1
+4
+8
+20480
+6105
+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/modexp.txt b/contrib/bc/tests/bc/modexp.txt
new file mode 100644
index 000000000000..31acab7e6af8
--- /dev/null
+++ b/contrib/bc/tests/bc/modexp.txt
@@ -0,0 +1,103 @@
+modexp(0, 0, 1)
+modexp(1, 0, 1)
+modexp(1, 0, 2)
+modexp(0, 10, 1)
+modexp(1, 293, 1)
+modexp(1, 2789365, 2)
+modexp(100, 8, 7)
+modexp(10922384, 15031007, 201)
+modexp(3346529, 189, 254)
+modexp(4113416930, 197, 14)
+modexp(7709, 5887, 111)
+modexp(5487406, 3252, 128)
+modexp(2080527, 2279453822, 219)
+modexp(48895, 50678, 232)
+modexp(1535808383, 2902995144, 18)
+modexp(8437837, 2882198, 69)
+modexp(35363, 25806, 2)
+modexp(3221177403, 1560419989, 189)
+modexp(227, 42775, 163)
+modexp(2811398069, 37500, 173)
+modexp(15046850, 3859895697, 195)
+modexp(15770756, 3621999893, 119)
+modexp(6937927, 3719297189, 183)
+modexp(12573, 43819, 209)
+modexp(42098463, 7584603, 136)
+modexp(8656683, 1328292415, 226)
+modexp(209, 81, 157)
+modexp(141, 13317429, 26)
+modexp(809485795, 60745, 101)
+modexp(4882, 1388217898, 38)
+modexp(750704, 78, 119)
+modexp(668879580, 2888860497, 179)
+modexp(1152725844, 15295742, 154)
+modexp(16160694, 8981529, 154)
+modexp(216, 102, 3)
+modexp(3691227289, 5344109, 232)
+modexp(2195559299, 61, 222)
+modexp(2478990626, 13007440, 30)
+modexp(45083, 44, 117)
+modexp(224, 55824, 53)
+modexp(1372700133, 89, 94)
+modexp(205, 10422, 48)
+modexp(11887, 12, 73)
+modexp(5955, 24353, 114)
+modexp(1201697310, 789722419, 6)
+modexp(56577, 231, 229)
+modexp(96, 38841, 189)
+modexp(6529661, 5636520, 209)
+modexp(11005, 15955685, 27)
+modexp(9709, 231, 132)
+modexp(59790, 1034579699, 166)
+modexp(47892, 14536879, 79)
+modexp(48, 208, 21)
+modexp(33036, 3877, 65)
+modexp(164, 6527085, 249)
+modexp(12146850, 224, 37)
+modexp(218, 16425679, 62)
+modexp(51, 27641, 95)
+modexp(3076735605, 49154, 32)
+modexp(515652717, 4117874315, 143)
+modexp(300672671, 720768884, 110)
+modexp(9422066, 206, 5)
+modexp(43, 97, 13)
+modexp(545174510, 65319, 126)
+modexp(3317462730, 704990271, 51)
+modexp(47316, 23231, 202)
+modexp(7236571, 4379567, 106)
+modexp(2584584521, 2459274189, 29)
+modexp(61562, 5035178, 178)
+modexp(65302, 112, 151)
+modexp(63040, 2168854052, 213)
+modexp(9039611, 2370306559, 62)
+modexp(16414384, 1020652061, 83)
+modexp(7491, 3853569905, 172)
+modexp(1180322494, 46670, 84)
+modexp(3823343557, 3865107254, 127)
+modexp(6240872, 55335, 39)
+modexp(2281401897, 1098411, 251)
+modexp(61, 2949190429, 231)
+modexp(8981024, 162, 43)
+modexp(1, 3568883218, 212)
+modexp(4217100969, 3471787779, 8)
+modexp(3232237, 13, 243)
+modexp(29280, 3972452706, 100)
+modexp(13077, 6431923, 216)
+modexp(104, 3098510775, 140)
+modexp(9503298, 174, 242)
+modexp(3424695712, 12184, 23)
+modexp(184, 15066347, 151)
+modexp(2935856, 14003205, 184)
+modexp(1386637762, 2128151420, 71)
+modexp(154, 11960656, 12)
+modexp(743976432, 4004778779, 136)
+modexp(3909160595, 3575680922, 21)
+modexp(26133, 3580, 147)
+modexp(409154, 170, 68)
+modexp(149, 55629, 40)
+modexp(5753, 13776176, 32)
+modexp(3831447473, 658273178, 98)
+modexp(1527252003, 2300622, 207)
+modexp(3363824553, 8244645, 215)
+modexp(20, 145, 101)
+modexp(4005077294, 2196555621, 94)
diff --git a/contrib/bc/tests/bc/modexp_results.txt b/contrib/bc/tests/bc/modexp_results.txt
new file mode 100644
index 000000000000..5bf0f146e967
--- /dev/null
+++ b/contrib/bc/tests/bc/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/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..01a9e4b4c482
--- /dev/null
+++ b/contrib/bc/tests/bc/pi_results.txt
@@ -0,0 +1,134 @@
+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.1415926535897932384626433832795028841971693993751058209749445923076
+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..d880600f7bb1
--- /dev/null
+++ b/contrib/bc/tests/bc/posix_errors.txt
@@ -0,0 +1,32 @@
+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()
+v = "stuff"
diff --git a/contrib/bc/tests/bc/power.txt b/contrib/bc/tests/bc/power.txt
new file mode 100644
index 000000000000..2e0760b23374
--- /dev/null
+++ b/contrib/bc/tests/bc/power.txt
@@ -0,0 +1,86 @@
+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
+0 ^ 0.0
+0 ^ 1.00
+0 ^ 1894.000
+1 ^ 0.0000
+39746823 ^ 0.00000
+0.238672983047682 ^ 0.000000
+18394762374689237468.97354862973846 ^ 0.0000000
+1 ^ 1.00000000
+2 ^ 1.000000000
+18927361346 ^ 1.0000000000
+0.23523785962738592635777 ^ 1.00000000000
+328956734869213746.89782398457234 ^ 1.000000000000
+8937 ^ 98.0000000000000
+0.124876812394 ^ 2396.00000000000000
+93762.2836 ^ 13.000000000000000
+1 ^ -1.0000000000000000
+2 ^ -1.00000000000000000
+10 ^ -1.000000000000000000
+683734768 ^ -1.0000000000000000000
+38579623756.897937568235 ^ -1.00000000000000000000
+1 ^ -32467.000000000000000000000
+2 ^ -53.0000000000000000000000
+23897 ^ -213.00000000000000000000000
+-1 ^ 1.000000000000000000000000
+-1 ^ 2.0000000000000000000000000
+-2 ^ 1.00000000000000000000000000
+-2 ^ 2.000000000000000000000000000
+-237 ^ 294.0000000000000000000000000000
+-3746 ^ 28.00000000000000000000000000000
+-0.3548 ^ 35.000000000000000000000000000000
+-4267.234 ^ 37.0000000000000000000000000000000
+-326.3246 ^ 78.00000000000000000000000000000000
+-1 ^ -1.000000000000000000000000000000000
+-1 ^ -2.0000000000000000000000000000000000
+-2 ^ -1.00000000000000000000000000000000000
+-2 ^ -2.000000000000000000000000000000000000
+-237 ^ -293.0000000000000000000000000000000000000
+-784 ^ -23.00000000000000000000000000000000000000
+-86 ^ -7.000000000000000000000000000000000000000
+-0.23424398 ^ -781.0000000000000000000000000000000000000000
+-178.234786 ^ -879.00000000000000000000000000000000000000000
+-1274.346 ^ -768.000000000000000000000000000000000000000000
+-0.2959371298 ^ 227.0000000000000000000000000000000000000000000
diff --git a/contrib/bc/tests/bc/power_results.txt b/contrib/bc/tests/bc/power_results.txt
new file mode 100644
index 000000000000..a4c1232cfe5d
--- /dev/null
+++ b/contrib/bc/tests/bc/power_results.txt
@@ -0,0 +1,144 @@
+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
+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/recursive_arrays.txt b/contrib/bc/tests/bc/recursive_arrays.txt
new file mode 100644
index 000000000000..35dab0529a93
--- /dev/null
+++ b/contrib/bc/tests/bc/recursive_arrays.txt
@@ -0,0 +1,353 @@
+asontheuastoheustnahosenutahosentuhaosentuhasonteuhansoetuhaoseuthaosenuthaoseutnahoesutnaoheusnatoeuhasoentuhaosenutahoeusntahoeusantoheuasotne[
+abcdefghijklmnopqrstuvwxyz0[
+abcdefghijklmnopqrstuvwxyz1[
+abcdefghijklmnopqrstuvwxyz2[
+abcdefghijklmnopqrstuvwxyz3[
+abcdefghijklmnopqrstuvwxyz4[
+abcdefghijklmnopqrstuvwxyz5[
+abcdefghijklmnopqrstuvwxyz6[
+abcdefghijklmnopqrstuvwxyz7[
+abcdefghijklmnopqrstuvwxyz8[
+abcdefghijklmnopqrstuvwxyz9[
+abcdefghijklmnopqrstuvwxyz10[
+abcdefghijklmnopqrstuvwxyz11[
+abcdefghijklmnopqrstuvwxyz12[
+abcdefghijklmnopqrstuvwxyz13[
+abcdefghijklmnopqrstuvwxyz14[
+abcdefghijklmnopqrstuvwxyz15[
+abcdefghijklmnopqrstuvwxyz16[
+abcdefghijklmnopqrstuvwxyz17[
+abcdefghijklmnopqrstuvwxyz18[
+abcdefghijklmnopqrstuvwxyz19[
+abcdefghijklmnopqrstuvwxyz20[
+abcdefghijklmnopqrstuvwxyz21[
+abcdefghijklmnopqrstuvwxyz22[
+abcdefghijklmnopqrstuvwxyz23[
+abcdefghijklmnopqrstuvwxyz24[
+abcdefghijklmnopqrstuvwxyz25[
+abcdefghijklmnopqrstuvwxyz26[
+abcdefghijklmnopqrstuvwxyz27[
+abcdefghijklmnopqrstuvwxyz28[
+abcdefghijklmnopqrstuvwxyz29[
+abcdefghijklmnopqrstuvwxyz30[
+abcdefghijklmnopqrstuvwxyz31[
+abcdefghijklmnopqrstuvwxyz32[
+abcdefghijklmnopqrstuvwxyz33[
+abcdefghijklmnopqrstuvwxyz34[
+abcdefghijklmnopqrstuvwxyz35[
+abcdefghijklmnopqrstuvwxyz36[
+abcdefghijklmnopqrstuvwxyz37[
+abcdefghijklmnopqrstuvwxyz38[
+abcdefghijklmnopqrstuvwxyz39[
+abcdefghijklmnopqrstuvwxyz40[
+abcdefghijklmnopqrstuvwxyz41[
+abcdefghijklmnopqrstuvwxyz42[
+abcdefghijklmnopqrstuvwxyz43[
+abcdefghijklmnopqrstuvwxyz44[
+abcdefghijklmnopqrstuvwxyz45[
+abcdefghijklmnopqrstuvwxyz46[
+abcdefghijklmnopqrstuvwxyz47[
+abcdefghijklmnopqrstuvwxyz48[
+abcdefghijklmnopqrstuvwxyz49[
+abcdefghijklmnopqrstuvwxyz50[
+abcdefghijklmnopqrstuvwxyz51[
+abcdefghijklmnopqrstuvwxyz52[
+abcdefghijklmnopqrstuvwxyz53[
+abcdefghijklmnopqrstuvwxyz54[
+abcdefghijklmnopqrstuvwxyz55[
+abcdefghijklmnopqrstuvwxyz56[
+abcdefghijklmnopqrstuvwxyz57[
+abcdefghijklmnopqrstuvwxyz58[
+abcdefghijklmnopqrstuvwxyz59[
+abcdefghijklmnopqrstuvwxyz60[
+abcdefghijklmnopqrstuvwxyz61[
+abcdefghijklmnopqrstuvwxyz62[
+abcdefghijklmnopqrstuvwxyz63[
+abcdefghijklmnopqrstuvwxyz64[
+abcdefghijklmnopqrstuvwxyz65[
+abcdefghijklmnopqrstuvwxyz66[
+abcdefghijklmnopqrstuvwxyz67[
+abcdefghijklmnopqrstuvwxyz68[
+abcdefghijklmnopqrstuvwxyz69[
+abcdefghijklmnopqrstuvwxyz70[
+abcdefghijklmnopqrstuvwxyz71[
+abcdefghijklmnopqrstuvwxyz72[
+abcdefghijklmnopqrstuvwxyz73[
+abcdefghijklmnopqrstuvwxyz74[
+abcdefghijklmnopqrstuvwxyz75[
+abcdefghijklmnopqrstuvwxyz76[
+abcdefghijklmnopqrstuvwxyz77[
+abcdefghijklmnopqrstuvwxyz78[
+abcdefghijklmnopqrstuvwxyz79[
+abcdefghijklmnopqrstuvwxyz80[
+abcdefghijklmnopqrstuvwxyz81[
+abcdefghijklmnopqrstuvwxyz82[
+abcdefghijklmnopqrstuvwxyz83[
+abcdefghijklmnopqrstuvwxyz84[
+abcdefghijklmnopqrstuvwxyz85[
+abcdefghijklmnopqrstuvwxyz86[
+abcdefghijklmnopqrstuvwxyz87[
+abcdefghijklmnopqrstuvwxyz88[
+abcdefghijklmnopqrstuvwxyz89[
+abcdefghijklmnopqrstuvwxyz90[
+abcdefghijklmnopqrstuvwxyz91[
+abcdefghijklmnopqrstuvwxyz92[
+abcdefghijklmnopqrstuvwxyz93[
+abcdefghijklmnopqrstuvwxyz94[
+abcdefghijklmnopqrstuvwxyz95[
+abcdefghijklmnopqrstuvwxyz96[
+abcdefghijklmnopqrstuvwxyz97[
+abcdefghijklmnopqrstuvwxyz98[
+abcdefghijklmnopqrstuvwxyz99[
+abcdefghijklmnopqrstuvwxyz100[
+abcdefghijklmnopqrstuvwxyz101[
+abcdefghijklmnopqrstuvwxyz102[
+abcdefghijklmnopqrstuvwxyz103[
+abcdefghijklmnopqrstuvwxyz104[
+abcdefghijklmnopqrstuvwxyz105[
+abcdefghijklmnopqrstuvwxyz106[
+abcdefghijklmnopqrstuvwxyz107[
+abcdefghijklmnopqrstuvwxyz108[
+abcdefghijklmnopqrstuvwxyz109[
+abcdefghijklmnopqrstuvwxyz110[
+abcdefghijklmnopqrstuvwxyz111[
+abcdefghijklmnopqrstuvwxyz112[
+abcdefghijklmnopqrstuvwxyz113[
+abcdefghijklmnopqrstuvwxyz114[
+abcdefghijklmnopqrstuvwxyz115[
+abcdefghijklmnopqrstuvwxyz116[
+abcdefghijklmnopqrstuvwxyz117[
+abcdefghijklmnopqrstuvwxyz118[
+abcdefghijklmnopqrstuvwxyz119[
+abcdefghijklmnopqrstuvwxyz120[
+abcdefghijklmnopqrstuvwxyz121[
+abcdefghijklmnopqrstuvwxyz122[
+abcdefghijklmnopqrstuvwxyz123[
+abcdefghijklmnopqrstuvwxyz124[
+abcdefghijklmnopqrstuvwxyz125[
+abcdefghijklmnopqrstuvwxyz126[
+abcdefghijklmnopqrstuvwxyz127[
+abcdefghijklmnopqrstuvwxyz128[
+abcdefghijklmnopqrstuvwxyz129[
+abcdefghijklmnopqrstuvwxyz130[
+abcdefghijklmnopqrstuvwxyz131[
+abcdefghijklmnopqrstuvwxyz132[
+abcdefghijklmnopqrstuvwxyz133[
+abcdefghijklmnopqrstuvwxyz134[
+abcdefghijklmnopqrstuvwxyz135[
+abcdefghijklmnopqrstuvwxyz136[
+abcdefghijklmnopqrstuvwxyz137[
+abcdefghijklmnopqrstuvwxyz138[
+abcdefghijklmnopqrstuvwxyz139[
+abcdefghijklmnopqrstuvwxyz140[
+abcdefghijklmnopqrstuvwxyz141[
+abcdefghijklmnopqrstuvwxyz142[
+abcdefghijklmnopqrstuvwxyz143[
+abcdefghijklmnopqrstuvwxyz144[
+abcdefghijklmnopqrstuvwxyz145[
+abcdefghijklmnopqrstuvwxyz146[
+abcdefghijklmnopqrstuvwxyz147[
+abcdefghijklmnopqrstuvwxyz148[
+abcdefghijklmnopqrstuvwxyz149[
+abcdefghijklmnopqrstuvwxyz150[
+abcdefghijklmnopqrstuvwxyz151[
+abcdefghijklmnopqrstuvwxyz152[
+abcdefghijklmnopqrstuvwxyz153[
+abcdefghijklmnopqrstuvwxyz154[
+abcdefghijklmnopqrstuvwxyz155[
+abcdefghijklmnopqrstuvwxyz156[
+abcdefghijklmnopqrstuvwxyz157[
+abcdefghijklmnopqrstuvwxyz158[
+abcdefghijklmnopqrstuvwxyz159[
+abcdefghijklmnopqrstuvwxyz160[
+abcdefghijklmnopqrstuvwxyz161[
+abcdefghijklmnopqrstuvwxyz162[
+abcdefghijklmnopqrstuvwxyz163[
+abcdefghijklmnopqrstuvwxyz164[
+abcdefghijklmnopqrstuvwxyz165[
+abcdefghijklmnopqrstuvwxyz166[
+abcdefghijklmnopqrstuvwxyz167[
+abcdefghijklmnopqrstuvwxyz168[
+abcdefghijklmnopqrstuvwxyz169[
+abcdefghijklmnopqrstuvwxyz170[
+abcdefghijklmnopqrstuvwxyz171[
+abcdefghijklmnopqrstuvwxyz172[
+abcdefghijklmnopqrstuvwxyz173[
+abcdefghijklmnopqrstuvwxyz174[
+abcdefghijklmnopqrstuvwxyz175[
+abcdefghijklmnopqrstuvwxyz176[
+abcdefghijklmnopqrstuvwxyz177[
+abcdefghijklmnopqrstuvwxyz178[
+abcdefghijklmnopqrstuvwxyz179[
+abcdefghijklmnopqrstuvwxyz180[
+abcdefghijklmnopqrstuvwxyz181[
+abcdefghijklmnopqrstuvwxyz182[
+abcdefghijklmnopqrstuvwxyz183[
+abcdefghijklmnopqrstuvwxyz184[
+abcdefghijklmnopqrstuvwxyz185[
+abcdefghijklmnopqrstuvwxyz186[
+abcdefghijklmnopqrstuvwxyz187[
+abcdefghijklmnopqrstuvwxyz188[
+abcdefghijklmnopqrstuvwxyz189[
+abcdefghijklmnopqrstuvwxyz190[
+abcdefghijklmnopqrstuvwxyz191[
+abcdefghijklmnopqrstuvwxyz192[
+abcdefghijklmnopqrstuvwxyz193[
+abcdefghijklmnopqrstuvwxyz194[
+abcdefghijklmnopqrstuvwxyz195[
+abcdefghijklmnopqrstuvwxyz196[
+abcdefghijklmnopqrstuvwxyz197[
+abcdefghijklmnopqrstuvwxyz198[
+abcdefghijklmnopqrstuvwxyz199[
+abcdefghijklmnopqrstuvwxyz200[
+abcdefghijklmnopqrstuvwxyz201[
+abcdefghijklmnopqrstuvwxyz202[
+abcdefghijklmnopqrstuvwxyz203[
+abcdefghijklmnopqrstuvwxyz204[
+abcdefghijklmnopqrstuvwxyz205[
+abcdefghijklmnopqrstuvwxyz206[
+abcdefghijklmnopqrstuvwxyz207[
+abcdefghijklmnopqrstuvwxyz208[
+abcdefghijklmnopqrstuvwxyz209[
+abcdefghijklmnopqrstuvwxyz210[
+abcdefghijklmnopqrstuvwxyz211[
+abcdefghijklmnopqrstuvwxyz212[
+abcdefghijklmnopqrstuvwxyz213[
+abcdefghijklmnopqrstuvwxyz214[
+abcdefghijklmnopqrstuvwxyz215[
+abcdefghijklmnopqrstuvwxyz216[
+abcdefghijklmnopqrstuvwxyz217[
+abcdefghijklmnopqrstuvwxyz218[
+abcdefghijklmnopqrstuvwxyz219[
+abcdefghijklmnopqrstuvwxyz220[
+abcdefghijklmnopqrstuvwxyz221[
+abcdefghijklmnopqrstuvwxyz222[
+abcdefghijklmnopqrstuvwxyz223[
+abcdefghijklmnopqrstuvwxyz224[
+abcdefghijklmnopqrstuvwxyz225[
+abcdefghijklmnopqrstuvwxyz226[
+abcdefghijklmnopqrstuvwxyz227[
+abcdefghijklmnopqrstuvwxyz228[
+abcdefghijklmnopqrstuvwxyz229[
+abcdefghijklmnopqrstuvwxyz230[
+abcdefghijklmnopqrstuvwxyz231[
+abcdefghijklmnopqrstuvwxyz232[
+abcdefghijklmnopqrstuvwxyz233[
+abcdefghijklmnopqrstuvwxyz234[
+abcdefghijklmnopqrstuvwxyz235[
+abcdefghijklmnopqrstuvwxyz236[
+abcdefghijklmnopqrstuvwxyz237[
+abcdefghijklmnopqrstuvwxyz238[
+abcdefghijklmnopqrstuvwxyz239[
+abcdefghijklmnopqrstuvwxyz240[
+abcdefghijklmnopqrstuvwxyz241[
+abcdefghijklmnopqrstuvwxyz242[
+abcdefghijklmnopqrstuvwxyz243[
+abcdefghijklmnopqrstuvwxyz244[
+abcdefghijklmnopqrstuvwxyz245[
+abcdefghijklmnopqrstuvwxyz246[
+abcdefghijklmnopqrstuvwxyz247[
+abcdefghijklmnopqrstuvwxyz248[
+abcdefghijklmnopqrstuvwxyz249[
+abcdefghijklmnopqrstuvwxyz250[
+abcdefghijklmnopqrstuvwxyz251[
+abcdefghijklmnopqrstuvwxyz252[
+abcdefghijklmnopqrstuvwxyz253[
+abcdefghijklmnopqrstuvwxyz254[
+abcdefghijklmnopqrstuvwxyz255[
+abcdefghijklmnopqrstuvwxyz256[
+abcdefghijklmnopqrstuvwxyz257[
+abcdefghijklmnopqrstuvwxyz258[
+abcdefghijklmnopqrstuvwxyz259[
+abcdefghijklmnopqrstuvwxyz260[
+abcdefghijklmnopqrstuvwxyz261[
+abcdefghijklmnopqrstuvwxyz262[
+abcdefghijklmnopqrstuvwxyz263[
+abcdefghijklmnopqrstuvwxyz264[
+abcdefghijklmnopqrstuvwxyz265[
+abcdefghijklmnopqrstuvwxyz266[
+abcdefghijklmnopqrstuvwxyz267[
+abcdefghijklmnopqrstuvwxyz268[
+abcdefghijklmnopqrstuvwxyz269[
+abcdefghijklmnopqrstuvwxyz270[
+abcdefghijklmnopqrstuvwxyz271[
+abcdefghijklmnopqrstuvwxyz272[
+abcdefghijklmnopqrstuvwxyz273[
+abcdefghijklmnopqrstuvwxyz274[
+abcdefghijklmnopqrstuvwxyz275[
+abcdefghijklmnopqrstuvwxyz276[
+abcdefghijklmnopqrstuvwxyz277[
+abcdefghijklmnopqrstuvwxyz278[
+abcdefghijklmnopqrstuvwxyz279[
+abcdefghijklmnopqrstuvwxyz280[
+abcdefghijklmnopqrstuvwxyz281[
+abcdefghijklmnopqrstuvwxyz282[
+abcdefghijklmnopqrstuvwxyz283[
+abcdefghijklmnopqrstuvwxyz284[
+abcdefghijklmnopqrstuvwxyz285[
+abcdefghijklmnopqrstuvwxyz286[
+abcdefghijklmnopqrstuvwxyz287[
+abcdefghijklmnopqrstuvwxyz288[
+abcdefghijklmnopqrstuvwxyz289[
+abcdefghijklmnopqrstuvwxyz290[
+abcdefghijklmnopqrstuvwxyz291[
+abcdefghijklmnopqrstuvwxyz292[
+abcdefghijklmnopqrstuvwxyz293[
+abcdefghijklmnopqrstuvwxyz294[
+abcdefghijklmnopqrstuvwxyz295[
+abcdefghijklmnopqrstuvwxyz296[
+abcdefghijklmnopqrstuvwxyz297[
+abcdefghijklmnopqrstuvwxyz298[
+abcdefghijklmnopqrstuvwxyz299[
+abcdefghijklmnopqrstuvwxyz300[
+abcdefghijklmnopqrstuvwxyz301[
+abcdefghijklmnopqrstuvwxyz302[
+abcdefghijklmnopqrstuvwxyz303[
+abcdefghijklmnopqrstuvwxyz304[
+abcdefghijklmnopqrstuvwxyz305[
+abcdefghijklmnopqrstuvwxyz306[
+abcdefghijklmnopqrstuvwxyz307[
+abcdefghijklmnopqrstuvwxyz308[
+abcdefghijklmnopqrstuvwxyz309[
+abcdefghijklmnopqrstuvwxyz310[
+abcdefghijklmnopqrstuvwxyz311[
+abcdefghijklmnopqrstuvwxyz312[
+abcdefghijklmnopqrstuvwxyz313[
+abcdefghijklmnopqrstuvwxyz314[
+abcdefghijklmnopqrstuvwxyz315[
+abcdefghijklmnopqrstuvwxyz316[
+abcdefghijklmnopqrstuvwxyz317[
+abcdefghijklmnopqrstuvwxyz318[
+abcdefghijklmnopqrstuvwxyz319[
+abcdefghijklmnopqrstuvwxyz320[
+abcdefghijklmnopqrstuvwxyz321[
+abcdefghijklmnopqrstuvwxyz322[
+abcdefghijklmnopqrstuvwxyz323[
+abcdefghijklmnopqrstuvwxyz324[
+abcdefghijklmnopqrstuvwxyz325[
+abcdefghijklmnopqrstuvwxyz326[
+abcdefghijklmnopqrstuvwxyz327[
+abcdefghijklmnopqrstuvwxyz328[
+abcdefghijklmnopqrstuvwxyz329[
+abcdefghijklmnopqrstuvwxyz330[
+abcdefghijklmnopqrstuvwxyz331[
+abcdefghijklmnopqrstuvwxyz332[
+abcdefghijklmnopqrstuvwxyz333[
+abcdefghijklmnopqrstuvwxyz334[
+abcdefghijklmnopqrstuvwxyz335[
+abcdefghijklmnopqrstuvwxyz336[
+abcdefghijklmnopqrstuvwxyz337[
+abcdefghijklmnopqrstuvwxyz338[
+abcdefghijklmnopqrstuvwxyz339[
+abcdefghijklmnopqrstuvwxyz340[
+abcdefghijklmnopqrstuvwxyz341[
+abcdefghijklmnopqrstuvwxyz342[
+abcdefghijklmnopqrstuvwxyz343[
+abcdefghijklmnopqrstuvwxyz344[
+abcdefghijklmnopqrstuvwxyz345[
+abcdefghijklmnopqrstuvwxyz346[
+abcdefghijklmnopqrstuvwxyz347[
+abcdefghijklmnopqrstuvwxyz348[
+abcdefghijklmnopqrstuvwxyz349[
+0
+]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
diff --git a/contrib/bc/tests/bc/recursive_arrays_results.txt b/contrib/bc/tests/bc/recursive_arrays_results.txt
new file mode 100644
index 000000000000..573541ac9702
--- /dev/null
+++ b/contrib/bc/tests/bc/recursive_arrays_results.txt
@@ -0,0 +1 @@
+0
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..9cffa2c28750
--- /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[i] + a[j]
+ }
+}
diff --git a/contrib/bc/tests/bc/scripts/all.txt b/contrib/bc/tests/bc/scripts/all.txt
new file mode 100644
index 000000000000..4ebfe5643c3d
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/all.txt
@@ -0,0 +1,16 @@
+multiply.bc
+divide.bc
+subtract.bc
+add.bc
+print.bc
+parse.bc
+array.bc
+atan.bc
+bessel.bc
+functions.bc
+globals.bc
+len.bc
+rand.bc
+references.bc
+screen.bc
+strings2.bc
diff --git a/contrib/bc/tests/bc/scripts/array.bc b/contrib/bc/tests/bc/scripts/array.bc
new file mode 100644
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 100644
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 100644
index 000000000000..c2229e50bc8e
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/bessel.bc
@@ -0,0 +1,48 @@
+#! /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
+t[15] = 0.0000000000000000
+
+l = 16
+
+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]
+ if (a[i] == 0 && scale(a[i]) > 0) print ".0000000000000000"
+ print ", ", a[j]
+ if (a[j] == 0 && scale(a[j]) > 0) print ".0000000000000000"
+ print ")\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..51a4c0082d6a
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/divide.bc
@@ -0,0 +1,23 @@
+#! /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[i] / 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 100644
index 000000000000..30ff9074387e
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/globals.bc
@@ -0,0 +1,27 @@
+#! /usr/bin/bc -gq
+
+if (!global_stacks()) {
+ sqrt(-1)
+}
+
+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..3aa64cc5e031
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/multiply.bc
@@ -0,0 +1,20 @@
+#! /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[i] * 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 100644
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 100644
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 100644
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 100644
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/strings2.bc b/contrib/bc/tests/bc/scripts/strings2.bc
new file mode 100644
index 000000000000..766fe11e40b9
--- /dev/null
+++ b/contrib/bc/tests/bc/scripts/strings2.bc
@@ -0,0 +1,7 @@
+#! /usr/bin/bc -q
+
+for (i = 0; i < 120; ++i) {
+ print "print \qabcdefghijklmnop", i, "\\n\q\n"
+}
+
+halt
diff --git a/contrib/bc/tests/bc/scripts/subtract.bc b/contrib/bc/tests/bc/scripts/subtract.bc
new file mode 100644
index 000000000000..1e592942cab3
--- /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[i] - 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..8808043b5dae
--- /dev/null
+++ b/contrib/bc/tests/bc/strings.txt
@@ -0,0 +1,77 @@
+"string"
+"another string"
+"yet
+another
+string"
+"noescapes\n"
+"newline
+"
+print "string"
+print "newline\n"
+
+"atsnoheusntaohetisanhoest;nhqktseuhstasatohutsaotnesh;qtsethusanthaotsehnustanhoestnuhstaohentisthtseahustnaohaotenhuastnoehtnxthatonehuatosnehp"
+"
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+"
+print "\n"
+
+print "\\\e\n"
+print "\d\n"
+"abc\\
+def
+"
+v = "string"
+v
+"stuff"
+print "\n"
+
+define v(v) {
+ print v, "\n"
+}
+
+v("stuff")
+v(v)
+
+length("ouch")
+length(v)
+
+v = u = "test assign\n"
+print v, u
+
+define t() {
+ return "return test\n"
+}
+
+v = t()
+print v
diff --git a/contrib/bc/tests/bc/strings_results.txt b/contrib/bc/tests/bc/strings_results.txt
new file mode 100644
index 000000000000..1951f6cf7df7
--- /dev/null
+++ b/contrib/bc/tests/bc/strings_results.txt
@@ -0,0 +1,53 @@
+stringanother stringyet
+another
+stringnoescapes\nnewline
+stringnewline
+atsnoheusntaohetisanhoest;nhqktseuhstasatohutsaotnesh;qtsethusanthaotsehnustanhoestnuhstaohentisthtseahustnaohaotenhuastnoehtnxthatonehuatosnehp
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+\\
+\d
+abc\\
+def
+string
+stuff
+stuff
+0
+string
+0
+4
+6
+test assign
+test assign
+return test
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..45e10c77bdf4
--- /dev/null
+++ b/contrib/bc/tests/bc/timeconst.sh
@@ -0,0 +1,116 @@
+#! /bin/sh
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# 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")
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir/..}
+
+# Gets the timeconst script, which could be a command-line argument.
+if [ "$#" -gt 0 ]; then
+ timeconst="$1"
+ shift
+else
+ timeconst="$testdir/scripts/timeconst.bc"
+fi
+
+# Gets the executable, which could also be a command-line argument.
+if [ "$#" -gt 0 ]; then
+ bc="$1"
+ shift
+else
+ bc="$testdir/../../bin/bc"
+fi
+
+#
+out1="$outputdir/bc_outputs/bc_timeconst.txt"
+out2="$outputdir/bc_outputs/bc_timeconst_results.txt"
+
+outdir=$(dirname "$out1")
+
+# Make sure the directory exists.
+if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+fi
+
+base=$(basename "$timeconst")
+
+# If the script does not exist, just skip. Running this test is not necessary.
+if [ ! -f "$timeconst" ]; then
+ printf 'Warning: %s does not exist\n' "$timeconst"
+ printf 'Skipping...\n'
+ exit 0
+fi
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+printf 'Running %s...' "$base"
+
+# Get a list of numbers. Funny how bc can help with that.
+nums=$(printf 'for (i = 0; i <= 1000; ++i) { i }\n' | bc)
+
+# Run each number through the script.
+for i in $nums; do
+
+ # Run the GNU bc on the test.
+ printf '%s\n' "$i" | bc -q "$timeconst" > "$out1"
+
+ err="$?"
+
+ # If the other bc failed, it's not GNU bc, or this bc.
+ if [ "$err" -ne 0 ]; then
+ printf '\nOther bc is not GNU compatible. Skipping...\n'
+ exit 0
+ fi
+
+ # Run the built bc on the test.
+ printf '%s\n' "$i" | "$bc" "$@" -q "$timeconst" > "$out2"
+
+ diff "$out1" "$out2"
+
+ error="$?"
+
+ # If fail, bail.
+ if [ "$error" -ne 0 ]; then
+ printf '\nFailed on input: %s\n' "$i"
+ exit "$error"
+ fi
+
+done
+
+rm -f "$out1"
+rm -f "$out2"
+
+exec 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..3d6b35773f90
--- /dev/null
+++ b/contrib/bc/tests/bc/vars_results.txt
@@ -0,0 +1,11 @@
+1609746610419572350599.59456175545
+.0000772397688552681359718594121969204138521230712049526233926741658\
+845368495051158801794834809672994
+34895734996363239667509709873808371507.681955808509709884214811338345
+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..e1d527ad8721
--- /dev/null
+++ b/contrib/bc/tests/bcl.c
@@ -0,0 +1,356 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * Tests for bcl(3).
+ *
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <bcl.h>
+
+/**
+ * Takes an error code and aborts if it actually is an error.
+ * @param e The error code.
+ */
+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;
+
+ // We do this twice to test the reference counting code.
+ e = bcl_init();
+ err(e);
+ e = bcl_init();
+ err(e);
+
+ // If bcl is set to abort on fatal error, that is a bug because it should
+ // default to off.
+ if (bcl_abortOnFatalError()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ bcl_setAbortOnFatalError(true);
+
+ // Now it *should* be set.
+ if (!bcl_abortOnFatalError()) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ // We do this twice to test the context stack.
+ ctxt = bcl_ctxt_create();
+ bcl_pushContext(ctxt);
+ ctxt = bcl_ctxt_create();
+ bcl_pushContext(ctxt);
+
+ // Ensure that the scale is properly set.
+ 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);
+
+ // Now the obase.
+ bcl_ctxt_setObase(ctxt, scale);
+ scale = bcl_ctxt_obase(ctxt);
+ if (scale != 16) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ // Set the back for the tests
+ bcl_ctxt_setIbase(ctxt, 10);
+ scale = bcl_ctxt_ibase(ctxt);
+ if (scale != 10) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+ bcl_ctxt_setObase(ctxt, 10);
+ scale = bcl_ctxt_obase(ctxt);
+ if (scale != 10) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ // Ensure that creating, duping, and copying works.
+ n = bcl_num_create();
+ n2 = bcl_dup(n);
+ bcl_copy(n, n2);
+
+ // Ensure that parsing works.
+ n3 = bcl_parse("2938");
+ err(bcl_err(n3));
+ n4 = bcl_parse("-28390.9108273");
+ err(bcl_err(n4));
+
+ // We also want to be sure that negatives work. This is a special case
+ // because bc and dc generate a negative instruction; they don't actually
+ // parse numbers as negative.
+ if (!bcl_num_neg(n4)) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ // Add them and check the result.
+ 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);
+
+ // We want to ensure all memory gets freed because we run this under
+ // Valgrind.
+ free(res);
+
+ // Ensure that divmod, a special case, works.
+ 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);
+
+ // Ensure that sqrt works. This is also a special case. The reason is
+ // because it is a one-argument function. Since all binary operators go
+ // through the same code (basically), we can test add and be done. However,
+ // sqrt does not, so we want to specifically test it.
+ 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);
+
+ // We want to check that numbers are properly extended...
+ 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);
+
+ // ...and truncated.
+ 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);
+
+ // Check conversion to hardware integers...
+ e = bcl_bigdig(n4, &b);
+ err(e);
+
+ if (b != 94538) err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ // ...and back.
+ 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);
+
+ // Check rand.
+ n4 = bcl_frand(10);
+ err(bcl_err(n4));
+
+ // Check that no asserts fire in shifting.
+ n4 = bcl_lshift(n4, bcl_bigdig2num(10));
+ err(bcl_err(n4));
+
+ // Repeat.
+ n3 = bcl_irand(n4);
+ err(bcl_err(n3));
+
+ // Repeat.
+ n2 = bcl_ifrand(bcl_dup(n3), 10);
+ err(bcl_err(n2));
+
+ // Still checking asserts.
+ e = bcl_rand_seedWithNum(n3);
+ err(e);
+
+ // Still checking asserts.
+ n4 = bcl_rand_seed2num();
+ err(bcl_err(n4));
+
+ // Finally, check modexp, yet another special case.
+ n5 = bcl_parse("10");
+ err(bcl_err(n5));
+
+ n6 = bcl_modexp(bcl_dup(n5), bcl_dup(n5), bcl_dup(n5));
+ err(bcl_err(n6));
+
+ // Clean up.
+ bcl_num_free(n);
+
+ // Test leading zeroes.
+ if (bcl_leadingZeroes())
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ n = bcl_parse("0.01");
+ err(bcl_err(n));
+
+ n2 = bcl_parse("-0.01");
+ err(bcl_err(n2));
+
+ n3 = bcl_parse("1.01");
+ err(bcl_err(n3));
+
+ n4 = bcl_parse("-1.01");
+ err(bcl_err(n4));
+
+ res = bcl_string(bcl_dup(n));
+ if (strcmp(res, ".01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(bcl_dup(n2));
+ if (strcmp(res, "-.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(bcl_dup(n3));
+ if (strcmp(res, "1.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(bcl_dup(n4));
+ if (strcmp(res, "-1.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ bcl_setLeadingZeroes(true);
+
+ if (!bcl_leadingZeroes())
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ res = bcl_string(bcl_dup(n));
+ if (strcmp(res, "0.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(bcl_dup(n2));
+ if (strcmp(res, "-0.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(bcl_dup(n3));
+ if (strcmp(res, "1.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(bcl_dup(n4));
+ if (strcmp(res, "-1.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ bcl_setLeadingZeroes(false);
+
+ if (bcl_leadingZeroes())
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ res = bcl_string(n);
+ if (strcmp(res, ".01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(n2);
+ if (strcmp(res, "-.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(n3);
+ if (strcmp(res, "1.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ res = bcl_string(n4);
+ if (strcmp(res, "-1.01"))
+ err(BCL_ERROR_FATAL_UNKNOWN_ERR);
+
+ free(res);
+
+ bcl_ctxt_freeNums(ctxt);
+
+ bcl_gc();
+
+ // We need to pop both contexts and free them.
+ bcl_popContext();
+
+ bcl_ctxt_free(ctxt);
+
+ ctxt = bcl_context();
+
+ bcl_popContext();
+
+ bcl_ctxt_free(ctxt);
+
+ // Decrement the reference counter to ensure all is freed.
+ 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..8942e087768b
--- /dev/null
+++ b/contrib/bc/tests/dc/all.txt
@@ -0,0 +1,25 @@
+decimal
+length
+stack_len
+exec_stack_len
+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..fdc628c857e0
--- /dev/null
+++ b/contrib/bc/tests/dc/decimal.txt
@@ -0,0 +1,41 @@
+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
+2893.982.28937pRpR
+198273\
+.192837pR
+1892.238907\
+.3982739pRpR
diff --git a/contrib/bc/tests/dc/decimal_results.txt b/contrib/bc/tests/dc/decimal_results.txt
new file mode 100644
index 000000000000..ec9124c06eff
--- /dev/null
+++ b/contrib/bc/tests/dc/decimal_results.txt
@@ -0,0 +1,54 @@
+0
+0
+0
+0
+135482346782356
+2
+1
+11
+123
+7505
+1023468723275435238491972521917846
+43434724324317058673920735170382703980273527090273892739207390379379\
+60379637893607893607893670530278200795207952702873892786172916728961\
+783907893607418973587857386079679267926737520730925372983782793652793
+-1
+-203
+-57
+-18586
+-31378682943772818461924738352952347258
+-8239456287456735894950672387239865203756982376208346745096273452730\
+96287563846592384526349872634895763257893467523987578690283762897568\
+459072348758071071087813501875908127359018715023841710239872301387278
+.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
+.28937
+2893.982
+198273.192837
+.3982739
+1892.238907
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..95fff37d915f
--- /dev/null
+++ b/contrib/bc/tests/dc/errors.txt
@@ -0,0 +1,39 @@
+p
+P
+x
+R
+d
+r
+1r
+b
+4 100000|
+_
+]
+0s
+y
+L
+La
+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
+.
+ga
+gb
+gd
+@
+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+p86+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
+1093+p2+p
+63+p
+64+p
+65+p
+66+p
+67
+73+p
+74+p
+75+p
+76+p
+77+p
+78+p
+79+p80+p
+81+p
+82+p
+83+p
+84+p
+85+p86+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
+1093+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/errors/30.txt b/contrib/bc/tests/dc/errors/30.txt
new file mode 100644
index 000000000000..e072e71617d8
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/30.txt
@@ -0,0 +1 @@
+0;0[]0:b;bs0l0x;0
diff --git a/contrib/bc/tests/dc/errors/31.txt b/contrib/bc/tests/dc/errors/31.txt
new file mode 100644
index 000000000000..9bada9d07d0e
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/31.txt
@@ -0,0 +1 @@
+0;0[]0:b;bS0l0x;0
diff --git a/contrib/bc/tests/dc/errors/32.txt b/contrib/bc/tests/dc/errors/32.txt
new file mode 100644
index 000000000000..c537acf7257d
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/32.txt
@@ -0,0 +1,20 @@
+0 1(pR
+1;;;;;pR
+1
+0 18d[0000000
+000000000000000000000000000000]sM[liv1-si0li!<0pR
+_1 0{pR
+_1 _1{pR
+_1 f0070000000000.0000000000000_10000000000006.00000000000005|pRpR
+_23745860900000.070000000000000 _0.20542357869124050~pRpR
+_3000000000000000.0000000700000006002 _7000000000000005000000000.000F000000000000003~pRpR20000000 300000000003.00000000000000030~pRpR
+_30000000000000000000000000
+1 0.001.00000000030
+1 0.000000000000000000000000000000000000000000000000000000000000000000002x30000000000000000000000000000000000000$80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000<0800000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000.000F000000000000003~pRpR20000000 300000000003.00000000000000030~pRpR
+_30000000000000.00000000000
+1 0.070.70000000000
+1 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000$80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000<080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000S8800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Z800000000000
+_10pR
+=390NpR
+_2000
+40000 5000C 2i>0eM]s01@sil0x
diff --git a/contrib/bc/tests/dc/errors/33.txt b/contrib/bc/tests/dc/errors/33.txt
new file mode 100644
index 000000000000..7d01c535c665
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/33.txt
Binary files differ
diff --git a/contrib/bc/tests/dc/errors/34.txt b/contrib/bc/tests/dc/errors/34.txt
new file mode 100644
index 000000000000..902a38bcbe37
--- /dev/null
+++ b/contrib/bc/tests/dc/errors/34.txt
@@ -0,0 +1,117 @@
+0 lip1-si0l0+2o0sx_9lq+pR 0900pR
+_100900pR
+_10900p0bpR
+1bp0
+.20bpR
+100000.0000005bpR
+_10bpR
+_.1000[l0;0;rpRl01+s0l010>x]dsxx0sx0s0
+1 2+p+p
+3+p
+4+p
+5+p
+6+p
+7+p
+8+p
+9+p
+16+p
+17+p
+18+p
+19.p
+20+p
+21+0+p
+71+xx0sx0s0
+1 2+p+p
+3o
+70+p
+70+p
+70+p
+70+p
+22+p
+20+p
+20+p
+20+p
+20+p
+x0+p
+20+p
+0 lip1-si0{0+2i0l0+200sx0.1009
+40+1+p
+4000pR
+_10900p0bpR
+1bp0
+.20bpR
+100000.002+p
+20+p
+20+p
+20+p
+20+p
+x0+p
+2000005bpR
+_10bpR
+_.10yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy00[l0;0;rpRl01+s0l010>x]dsxx0sx0s0
+1 2+p+p
+3+p
+4+p
+5+p
+6+p
+7+p
+8+p
+9+p
+10p
++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+xx0sx0s0
+1 2+p+p
+3o
+70+p
+70+p
+70+p
+70+p
+22+p
+20+p
+
+20+p
+30+p
+30+p
+30+p
+0b30+p
+30+p
+30+p
+30+p
+30+p
+30+p
+30+p
+40"1+p
+40+p
+40+p
+40+p
+40+p
+40+p
+40+p
+40+p
+40+p
+50+p
+50+p
+50+p
+50+p
+50+p
+50+p
+50+p
+50+p
+50+p
+5pR
+100000.0070000bpR
+^20+pR
+_.10100000.0070000bpR
+^20+pR
+_.1000Kl0;0;rpRl0
diff --git a/contrib/bc/tests/dc/exec_stack_len.txt b/contrib/bc/tests/dc/exec_stack_len.txt
new file mode 100644
index 000000000000..27e8bf7ff3e3
--- /dev/null
+++ b/contrib/bc/tests/dc/exec_stack_len.txt
@@ -0,0 +1,6 @@
+,pR
+[,pR]x
+[[,pR]x]x
+[[[,pR]x]x]x
+[[[,pR]x ,pR]x]x
+[[[[,p1-Q]x]x]x]x ,pQ
diff --git a/contrib/bc/tests/dc/exec_stack_len_results.txt b/contrib/bc/tests/dc/exec_stack_len_results.txt
new file mode 100644
index 000000000000..0d3e1d1553a3
--- /dev/null
+++ b/contrib/bc/tests/dc/exec_stack_len_results.txt
@@ -0,0 +1,8 @@
+1
+2
+3
+4
+4
+3
+5
+1
diff --git a/contrib/bc/tests/dc/length.txt b/contrib/bc/tests/dc/length.txt
new file mode 100644
index 000000000000..55905b7a495f
--- /dev/null
+++ b/contrib/bc/tests/dc/length.txt
@@ -0,0 +1,131 @@
+0ZpR
+0.0000ZpR
+0.00000000ZpR
+0.00000000000ZpR
+1ZpR
+12ZpR
+123ZpR
+1234ZpR
+12345ZpR
+123456ZpR
+1234567ZpR
+12345678ZpR
+123456789ZpR
+1234567890ZpR
+1.0ZpR
+12.0ZpR
+123.0ZpR
+1234.0ZpR
+12345.0ZpR
+123456.0ZpR
+1234567.0ZpR
+12345678.0ZpR
+123456789.0ZpR
+1234567890.0ZpR
+.1ZpR
+.12ZpR
+.123ZpR
+.1234ZpR
+.12345ZpR
+.123456ZpR
+.1234567ZpR
+.12345678ZpR
+.123456789ZpR
+.1234567890ZpR
+.01ZpR
+.012ZpR
+.0123ZpR
+.01234ZpR
+.012345ZpR
+.0123456ZpR
+.01234567ZpR
+.012345678ZpR
+.0123456789ZpR
+.01234567890ZpR
+.001ZpR
+.0012ZpR
+.00123ZpR
+.001234ZpR
+.0012345ZpR
+.00123456ZpR
+.001234567ZpR
+.0012345678ZpR
+.00123456789ZpR
+.001234567890ZpR
+.0001ZpR
+.00012ZpR
+.000123ZpR
+.0001234ZpR
+.00012345ZpR
+.000123456ZpR
+.0001234567ZpR
+.00012345678ZpR
+.000123456789ZpR
+.0001234567890ZpR
+.00001ZpR
+.000012ZpR
+.0000123ZpR
+.00001234ZpR
+.000012345ZpR
+.0000123456ZpR
+.00001234567ZpR
+.000012345678ZpR
+.0000123456789ZpR
+.00001234567890ZpR
+.000001ZpR
+.0000012ZpR
+.00000123ZpR
+.000001234ZpR
+.0000012345ZpR
+.00000123456ZpR
+.000001234567ZpR
+.0000012345678ZpR
+.00000123456789ZpR
+.000001234567890ZpR
+.0000001ZpR
+.00000012ZpR
+.000000123ZpR
+.0000001234ZpR
+.00000012345ZpR
+.000000123456ZpR
+.0000001234567ZpR
+.00000012345678ZpR
+.000000123456789ZpR
+.0000001234567890ZpR
+.00000001ZpR
+.000000012ZpR
+.0000000123ZpR
+.00000001234ZpR
+.000000012345ZpR
+.0000000123456ZpR
+.00000001234567ZpR
+.000000012345678ZpR
+.0000000123456789ZpR
+.00000001234567890ZpR
+.000000001ZpR
+.0000000012ZpR
+.00000000123ZpR
+.000000001234ZpR
+.0000000012345ZpR
+.00000000123456ZpR
+.000000001234567ZpR
+.0000000012345678ZpR
+.00000000123456789ZpR
+.000000001234567890ZpR
+.0000000001ZpR
+.00000000012ZpR
+.000000000123ZpR
+.0000000001234ZpR
+.00000000012345ZpR
+.000000000123456ZpR
+.0000000001234567ZpR
+.00000000012345678ZpR
+.000000000123456789ZpR
+.0000000001234567890ZpR
+289.29837ZpR
+2893.00000ZpR
+289.0ZpR
+1802973.0000000238ZpR
+.000000000000000093182394080000000000ZpR
+YapR
+5 15:aYapR
diff --git a/contrib/bc/tests/dc/length_results.txt b/contrib/bc/tests/dc/length_results.txt
new file mode 100644
index 000000000000..d6c33b9f5f0c
--- /dev/null
+++ b/contrib/bc/tests/dc/length_results.txt
@@ -0,0 +1,131 @@
+1
+4
+8
+11
+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
+1
+16
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..240473b0bbca
--- /dev/null
+++ b/contrib/bc/tests/dc/scientific.txt
@@ -0,0 +1,55 @@
+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
+82938.29873e8.82\
+937pRpR
+2893e2\
+.389pRpR
+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..25fb0756cad0
--- /dev/null
+++ b/contrib/bc/tests/dc/scientific_results.txt
@@ -0,0 +1,54 @@
+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
+.82937
+8293829873000
+.389
+289300
+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/all.txt b/contrib/bc/tests/dc/scripts/all.txt
new file mode 100644
index 000000000000..e15dae5e15ff
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/all.txt
@@ -0,0 +1,9 @@
+prime.dc
+asciify.dc
+stream.dc
+array.dc
+else.dc
+factorial.dc
+loop.dc
+quit.dc
+weird.dc
diff --git a/contrib/bc/tests/dc/scripts/array.dc b/contrib/bc/tests/dc/scripts/array.dc
new file mode 100644
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 100644
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/easter.sh b/contrib/bc/tests/dc/scripts/easter.sh
new file mode 100755
index 000000000000..27dfe34580ea
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/easter.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+if test $# -lt 2
+then
+ echo usage: $0 dc_exec year [options...]
+ exit 1
+fi
+
+dc_exec="$1"
+shift
+
+year="$1"
+shift
+
+echo $year '
+[
+ ddsf
+ [
+ lfp
+ [too early
+ ]P
+ q
+ ]s@
+ 1583>@
+ ddd19%1+sg100/1+d3*4/12-sx8*5+25/5-sz5*4/lx-10-sdlg11*20+lz+lx-30%
+ d
+ [30+]s@
+ 0>@d
+ [
+ [1+]s@
+ lg11<@
+ ]s@
+ 25=@d
+ [1+]s@
+ 24=@se44le-d
+ [30+]s@
+ 21>@dld+7%-7+
+ [March ]sm
+ d
+ [
+ 31-
+ [April ]sm
+ ]s@
+ 31<@psnlmPpsn1z>p
+]sp
+lpx' | "$dc_exec" "$@" | tr '\012' ' '
+echo ''
diff --git a/contrib/bc/tests/dc/scripts/else.dc b/contrib/bc/tests/dc/scripts/else.dc
new file mode 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 000000000000..1f8684debecc
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/stream.dc
@@ -0,0 +1 @@
+0si[liPli1+sili65536>x]ddsxPx
diff --git a/contrib/bc/tests/dc/scripts/stream.txt b/contrib/bc/tests/dc/scripts/stream.txt
new file mode 100644
index 000000000000..c45beb2b2346
--- /dev/null
+++ b/contrib/bc/tests/dc/scripts/stream.txt
Binary files differ
diff --git a/contrib/bc/tests/dc/scripts/weird.dc b/contrib/bc/tests/dc/scripts/weird.dc
new file mode 100644
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/stack_len.txt b/contrib/bc/tests/dc/stack_len.txt
new file mode 100644
index 000000000000..1b367f3affa8
--- /dev/null
+++ b/contrib/bc/tests/dc/stack_len.txt
@@ -0,0 +1,15 @@
+zp
+zp
+zp
+zp
+sa
+yap
+Sa
+yap
+Sa
+yapR
+La
+yapR
+La
+yap
+zp
diff --git a/contrib/bc/tests/dc/stack_len_results.txt b/contrib/bc/tests/dc/stack_len_results.txt
new file mode 100644
index 000000000000..3805e42f60fb
--- /dev/null
+++ b/contrib/bc/tests/dc/stack_len_results.txt
@@ -0,0 +1,10 @@
+0
+1
+2
+3
+1
+2
+3
+2
+1
+6
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..460976abbd9e
--- /dev/null
+++ b/contrib/bc/tests/dc/strings.txt
@@ -0,0 +1,51 @@
+[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
+[[10pR]si]x [[lix]x]x
diff --git a/contrib/bc/tests/dc/strings_results.txt b/contrib/bc/tests/dc/strings_results.txt
new file mode 100644
index 000000000000..deb19e09bae0
--- /dev/null
+++ b/contrib/bc/tests/dc/strings_results.txt
@@ -0,0 +1,52 @@
+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\
+\
+\
+10
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/error.sh b/contrib/bc/tests/error.sh
new file mode 100755
index 000000000000..c76dcdf113dd
--- /dev/null
+++ b/contrib/bc/tests/error.sh
@@ -0,0 +1,99 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir}
+
+# Command-line processing.
+if [ "$#" -lt 2 ]; then
+ printf 'usage: %s dir test [exec args...]\n' "$script"
+ exit 1
+else
+ d="$1"
+ shift
+
+ t="$1"
+ shift
+fi
+
+if [ "$#" -lt 1 ]; then
+ exe="$testdir/../bin/$d"
+else
+ exe="$1"
+ shift
+fi
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+out="$outputdir/${d}_outputs/error_results_${t}"
+outdir=$(dirname "$out")
+
+# Make sure the directory exists.
+if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+fi
+
+# Set stuff for the correct calculator.
+if [ "$d" = "bc" ]; then
+ opts="-l"
+ halt="halt"
+ read_call="read()"
+ read_expr="${read_call}\n5+5;"
+else
+ opts="-x"
+ halt="q"
+fi
+
+testfile="$testdir/$d/errors/$t"
+
+printf 'Running %s error file %s...' "$d" "$t"
+
+printf '%s\n' "$halt" | "$exe" "$@" $opts "$testfile" 2> "$out" > /dev/null
+err="$?"
+
+checkerrtest "$d" "$err" "$testfile" "$out" "$exebase" > /dev/null
+
+printf 'pass\n'
+
+printf 'Running %s error file %s through cat...' "$d" "$t"
+
+cat "$testfile" | "$exe" "$@" $opts 2> "$out" > /dev/null
+err="$?"
+
+checkcrash "$d" "$err" "$testfile"
+
+printf 'pass\n'
diff --git a/contrib/bc/tests/errors.sh b/contrib/bc/tests/errors.sh
new file mode 100755
index 000000000000..4acc978b9e5a
--- /dev/null
+++ b/contrib/bc/tests/errors.sh
@@ -0,0 +1,149 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# WARNING: Test files cannot have empty lines!
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir}
+
+# Command-line processing.
+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
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+out="$outputdir/${d}_outputs/errors_results.txt"
+outdir=$(dirname "$out")
+
+# Make sure the directory exists.
+if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+fi
+
+exebase=$(basename "$exe")
+
+# These are the filenames for the extra tests.
+posix="posix_errors"
+read_errors="read_errors"
+
+# Set stuff for the correct calculator.
+if [ "$d" = "bc" ]; then
+ opts="-l"
+ halt="halt"
+ read_call="read()"
+ read_expr="${read_call}\n5+5;"
+else
+ opts="-x"
+ halt="q"
+fi
+
+printf 'Running %s command-line error tests...' "$d"
+
+printf '%s\n' "$halt" | "$exe" "$@" -e "1+1" -f- -e "2+2" 2> "$out" > /dev/null
+err="$?"
+
+checkerrtest "$d" "$err" "command-line -e test" "$out" "$exebase"
+
+printf '%s\n' "$halt" | "$exe" "$@" -e "1+1" -f- -f "$testdir/$d/decimal.txt" 2> "$out" > /dev/null
+err="$?"
+
+checkerrtest "$d" "$err" "command-line -f test" "$out" "$exebase"
+
+printf 'pass\n'
+
+# Now test the error files in the standard tests directory.
+for testfile in $testdir/$d/*errors.txt; do
+
+ if [ -z "${testfile##*$read_errors*}" ]; then
+ # We don't test read errors here. Skip.
+ continue
+ fi
+
+ # Test bc POSIX errors and warnings.
+ if [ -z "${testfile##*$posix*}" ]; then
+
+ # Just test warnings.
+ 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
+
+ checkerrtest "$d" "1" "$line" "$out" "$exebase"
+
+ # Set the options for standard mode.
+ options="-ls"
+
+ else
+ options="$opts"
+ fi
+
+ # Output something pretty.
+ base=$(basename "$testfile")
+ base="${base%.*}"
+ printf 'Running %s %s...' "$d" "$base"
+
+ # Test errors on each line of the file. Yes, each line has a separate error
+ # case.
+ while read -r line; do
+
+ rm -f "$out"
+
+ printf '%s\n' "$line" | "$exe" "$@" "$options" 2> "$out" > /dev/null
+ err="$?"
+
+ checkerrtest "$d" "$err" "$line" "$out" "$exebase"
+
+ done < "$testfile"
+
+ printf 'pass\n'
+
+done
diff --git a/contrib/bc/tests/extra_required.txt b/contrib/bc/tests/extra_required.txt
new file mode 100644
index 000000000000..e36d95a1305b
--- /dev/null
+++ b/contrib/bc/tests/extra_required.txt
@@ -0,0 +1,9 @@
+engineering
+lib2
+places
+rand
+scientific
+shift
+trunc
+bitfuncs
+leadingzero
diff --git a/contrib/bc/tests/history.py b/contrib/bc/tests/history.py
new file mode 100755
index 000000000000..17006c93ef2d
--- /dev/null
+++ b/contrib/bc/tests/history.py
@@ -0,0 +1,1153 @@
+#! /usr/bin/python
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+import os, sys
+import time
+import signal
+import traceback
+
+try:
+ import pexpect
+except ImportError:
+ print("Could not find pexpect. Skipping...")
+ sys.exit(0)
+
+# Housekeeping.
+script = sys.argv[0]
+testdir = os.path.dirname(script)
+
+if "BC_TEST_OUTPUT_DIR" in os.environ:
+ outputdir = os.environ["BC_TEST_OUTPUT_DIR"]
+else:
+ outputdir = testdir
+
+prompt = ">>> "
+
+# This array is for escaping characters that are necessary to escape when
+# outputting to pexpect. Since pexpect takes regexes, these characters confuse
+# it unless we escape them.
+escapes = [
+ ']',
+ '[',
+ '+',
+]
+
+# UTF-8 stress tests.
+utf8_stress1 = "ᆬḰ䋔䗅㜲ತ咡䒢岤䳰稨⣡嶣㷡嶏ⵐ䄺嵕ਅ奰痚㆜䊛拂䅙૩➋䛿ቬ竳Ϳᅠ❄产翷䮊௷Ỉ䷒䳜㛠➕傎ᗋᏯਕ䆐悙癐㺨"
+utf8_stress2 = "韠싧돳넨큚ꉿ뮴픷ꉲ긌�최릙걆鳬낽ꪁ퍼鈴핐黙헶ꪈ뮩쭀锻끥鉗겉욞며뛯꬐�ﻼ�度錐�"
+utf8_stress3 = "곻�䣹昲蜴Ὓ桢㎏⚦珢畣갴ﭱ鶶ๅ⶛뀁彻ꖒ䔾ꢚﱤ햔햞㐹�鼳뵡▿ⶾ꠩�纞⊐佧�ⵟ霘紳㱔籠뎼⊓搧硤"
+utf8_stress4 = "ᄀ𖢾🏴��"
+
+# An easy array for UTF-8 tests.
+utf8_stress_strs = [
+ utf8_stress1,
+ utf8_stress2,
+ utf8_stress3,
+ utf8_stress4,
+]
+
+
+def expect(child, data):
+ child.expect(data)
+
+
+# Eats all of the child's data.
+# @param child The child whose data should be eaten.
+def eat(child):
+ while child.buffer is not None and len(child.buffer) > 0:
+ expect(child, ".+")
+
+
+# Send data to a child. This makes sure the buffers are empty first.
+# @param child The child to send data to.
+# @param data The data to send.
+def send(child, data):
+ eat(child)
+ child.send(data)
+
+
+def wait(child):
+ if child.isalive():
+ child.sendeof()
+ time.sleep(1)
+ if child.isalive():
+ child.kill(signal.SIGTERM)
+ time.sleep(1)
+ if child.isalive():
+ child.kill(signal.SIGKILL)
+ child.wait()
+
+
+# Check that the child output the expected line. If history is false, then
+# the output should change.
+def check_line(child, expected, prompt=">>> ", history=True):
+ send(child, "\n")
+ prefix = "\r\n" if history else ""
+ expect(child, prefix + expected + "\r\n" + prompt)
+
+
+# Write a string to output, checking all of the characters are output,
+# one-by-one.
+def write_str(child, s):
+ for c in s:
+ send(child, c)
+ if c in escapes:
+ expect(child, "\\{}".format(c))
+ else:
+ expect(child, c)
+
+
+# Check the bc banner.
+# @param child The child process.
+def bc_banner(child):
+ bc_banner1 = "bc [0-9]+\.[0-9]+\.[0-9]+\r\n"
+ bc_banner2 = "Copyright \(c\) 2018-[2-9][0-9][0-9][0-9] Gavin D. Howard and contributors\r\n"
+ bc_banner3 = "Report bugs at: https://git.yzena.com/gavin/bc\r\n\r\n"
+ bc_banner4 = "This is free software with ABSOLUTELY NO WARRANTY.\r\n\r\n"
+ expect(child, bc_banner1)
+ expect(child, bc_banner2)
+ expect(child, bc_banner3)
+ expect(child, bc_banner4)
+ expect(child, prompt)
+
+
+# Common UTF-8 testing function. The index is the index into utf8_stress_strs
+# for which stress string to use.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+# @param idx The index of the UTF-8 stress string.
+def test_utf8(exe, args, env, idx, bc=True):
+
+ # Because both bc and dc use this, make sure the banner doesn't pop.
+ env["BC_BANNER"] = "0"
+
+ child = pexpect.spawn(exe, args=args, env=env, encoding='utf-8', codec_errors='ignore')
+
+ try:
+
+ # Write the stress string.
+ send(child, utf8_stress_strs[idx])
+ send(child, "\n")
+
+ if bc:
+ send(child, "quit")
+ else:
+ send(child, "q")
+
+ send(child, "\n")
+
+ wait(child)
+
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+# A random UTF-8 test with insert.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_utf8_0(exe, args, env, bc=True):
+
+ # Because both bc and dc use this, make sure the banner doesn't pop.
+ env["BC_BANNER"] = "0"
+
+ child = pexpect.spawn(exe, args=args, env=env, encoding='utf-8', codec_errors='ignore')
+
+ try:
+
+ # Just random UTF-8 I generated somewhow, plus ensuring that insert works.
+ write_str(child, "ﴪáá̵̗🈐ã")
+ send(child, "\x1b[D\x1b[D\x1b[D\x1b\x1b[Aℐ")
+ send(child, "\n")
+
+ if bc:
+ send(child, "quit")
+ else:
+ send(child, "q")
+
+ send(child, "\n")
+ eat(child)
+
+ wait(child)
+
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+def test_utf8_1(exe, args, env, bc=True):
+ return test_utf8(exe, args, env, 0, bc)
+
+
+def test_utf8_2(exe, args, env, bc=True):
+ return test_utf8(exe, args, env, 1, bc)
+
+
+def test_utf8_3(exe, args, env, bc=True):
+ return test_utf8(exe, args, env, 2, bc)
+
+
+def test_utf8_4(exe, args, env, bc=True):
+ return test_utf8(exe, args, env, 3, bc)
+
+
+# This tests a SIGINT with reset followed by a SIGQUIT.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_sigint_sigquit(exe, args, env):
+
+ # Because both bc and dc use this, make sure the banner doesn't pop.
+ env["BC_BANNER"] = "0"
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ send(child, "\t")
+ expect(child, " ")
+ send(child, "\x03")
+ send(child, "\x1c")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Test for EOF.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_eof(exe, args, env):
+
+ # Because both bc and dc use this, make sure the banner doesn't pop.
+ env["BC_BANNER"] = "0"
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ send(child, "\t")
+ expect(child, " ")
+ send(child, "\x04")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Test for quiting SIGINT.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_sigint(exe, args, env):
+
+ # Because both bc and dc use this, make sure the banner doesn't pop.
+ env["BC_BANNER"] = "0"
+
+ env["BC_SIGINT_RESET"] = "0"
+ env["DC_SIGINT_RESET"] = "0"
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ send(child, "\t")
+ expect(child, " ")
+ send(child, "\x03")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Test for SIGTSTP.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_sigtstp(exe, args, env):
+
+ # This test does not work on FreeBSD, so skip.
+ if sys.platform.startswith("freebsd"):
+ sys.exit(0)
+
+ # Because both bc and dc use this, make sure the banner doesn't pop.
+ env["BC_BANNER"] = "0"
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ send(child, "\t")
+ expect(child, " ")
+ send(child, "\x13")
+ time.sleep(1)
+ if not child.isalive():
+ print("child exited early")
+ print(str(child))
+ print(str(child.buffer))
+ sys.exit(1)
+ child.kill(signal.SIGCONT)
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Test for SIGSTOP.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_sigstop(exe, args, env):
+
+ # Because both bc and dc use this, make sure the banner doesn't pop.
+ env["BC_BANNER"] = "0"
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ send(child, "\t")
+ expect(child, " ")
+ send(child, "\x14")
+ time.sleep(1)
+ if not child.isalive():
+ print("child exited early")
+ print(str(child))
+ print(str(child.buffer))
+ sys.exit(1)
+ send(child, "\x13")
+ time.sleep(1)
+ if not child.isalive():
+ print("child exited early")
+ print(str(child))
+ print(str(child.buffer))
+ sys.exit(1)
+ child.kill(signal.SIGCONT)
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+def test_bc_utf8_0(exe, args, env):
+ return test_utf8_0(exe, args, env, True)
+
+
+def test_bc_utf8_1(exe, args, env):
+ return test_utf8_1(exe, args, env, True)
+
+
+def test_bc_utf8_2(exe, args, env):
+ return test_utf8_2(exe, args, env, True)
+
+
+def test_bc_utf8_3(exe, args, env):
+ return test_utf8_3(exe, args, env, True)
+
+
+def test_bc_utf8_4(exe, args, env):
+ return test_utf8_4(exe, args, env, True)
+
+
+# Basic bc test.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc1(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ write_str(child, "1")
+ check_line(child, "1")
+ write_str(child, "1")
+ check_line(child, "1")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# SIGINT with no history.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc2(exe, args, env):
+
+ env["TERM"] = "dumb"
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ child.sendline("1")
+ check_line(child, "1", history=False)
+ time.sleep(1)
+ child.sendintr()
+ child.sendline("quit")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Left and right arrows.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc3(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "\x1b[D\x1b[D\x1b[C\x1b[C")
+ send(child, "\n")
+ expect(child, prompt)
+ send(child, "12\x1b[D3\x1b[C4\x1bOD5\x1bOC6")
+ send(child, "\n")
+ check_line(child, "132546")
+ send(child, "12\x023\x064")
+ send(child, "\n")
+ check_line(child, "1324")
+ send(child, "12\x1b[H3\x1bOH\x01\x1b[H45\x1bOF6\x05\x1b[F7\x1bOH8")
+ send(child, "\n")
+ check_line(child, "84531267")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Up and down arrows.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc4(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "\x1b[A\x1bOA\x1b[B\x1bOB")
+ send(child, "\n")
+ expect(child, prompt)
+ write_str(child, "15")
+ check_line(child, "15")
+ write_str(child, "2^16")
+ check_line(child, "65536")
+ send(child, "\x1b[A\x1bOA")
+ send(child, "\n")
+ check_line(child, "15")
+ send(child, "\x1b[A\x1bOA\x1b[A\x1b[B")
+ check_line(child, "65536")
+ send(child, "\x1b[A\x1bOA\x0e\x1b[A\x1b[A\x1b[A\x1b[B\x10\x1b[B\x1b[B\x1bOB\x1b[B\x1bOA")
+ send(child, "\n")
+ check_line(child, "65536")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Clear screen.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc5(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "\x0c")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Printed material without a newline.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc6(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "print \"Enter number: \"")
+ send(child, "\n")
+ expect(child, "Enter number: ")
+ send(child, "4\x1b[A\x1b[A")
+ send(child, "\n")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Word start and word end.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc7(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "\x1bb\x1bb\x1bf\x1bf")
+ send(child, "\n")
+ expect(child, prompt)
+ send(child, "\x1b[0~\x1b[3a")
+ send(child, "\n")
+ expect(child, prompt)
+ send(child, "\x1b[0;4\x1b[0A")
+ send(child, "\n")
+ expect(child, prompt)
+ send(child, " ")
+ send(child, "\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb")
+ send(child, "\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf")
+ send(child, "\n")
+ expect(child, prompt)
+ write_str(child, "12 + 34 + 56 + 78 + 90")
+ check_line(child, "270")
+ send(child, "\x1b[A")
+ send(child, "\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb\x1bb")
+ send(child, "\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf\x1bf")
+ check_line(child, "270")
+ send(child, "\x1b[A")
+ send(child, "\x1bh\x1bh\x1bf + 14 ")
+ send(child, "\n")
+ check_line(child, "284")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Backspace.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc8(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "12\x1b[D3\x1b[C4\x08\x7f")
+ send(child, "\n")
+ check_line(child, "13")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Backspace and delete words.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc9(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "\x1b[0;5D\x1b[0;5D\x1b[0;5D\x1b[0;5C\x1b[0;5D\x1bd\x1b[3~\x1b[d\x1b[d\x1b[d\x1b[d\x7f\x7f\x7f")
+ send(child, "\n")
+ expect(child, prompt)
+ write_str(child, "12 + 34 + 56 + 78 + 90")
+ check_line(child, "270")
+ send(child, "\x1b[A")
+ send(child, "\x1b[0;5D\x1b[0;5D\x1b[0;5D\x1b[0;5C\x1b[0;5D\x1bd\x1b[3~\x1b[d\x1b[d\x1b[d\x1b[d\x7f\x7f\x7f")
+ send(child, "\n")
+ check_line(child, "102")
+ send(child, "\x1b[A")
+ send(child, "\x17\x17")
+ send(child, "\n")
+ check_line(child, "46")
+ send(child, "\x17\x17")
+ send(child, "\n")
+ expect(child, prompt)
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Backspace and delete words 2.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc10(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "\x1b[3~\x1b[3~")
+ send(child, "\n")
+ expect(child, prompt)
+ send(child, " \x1b[3~\x1b[3~")
+ send(child, "\n")
+ expect(child, prompt)
+ write_str(child, "12 + 34 + 56 + 78 + 90")
+ check_line(child, "270")
+ send(child, "\x1b[A\x1b[A\x1b[A\x1b[B\x1b[B\x1b[B\x1b[A")
+ send(child, "\n")
+ check_line(child, "270")
+ send(child, "\x1b[A\x1b[0;5D\x1b[0;5D\x0b")
+ send(child, "\n")
+ check_line(child, "180")
+ send(child, "\x1b[A\x1521")
+ check_line(child, "21")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Swap.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc11(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "\x1b[A\x02\x14")
+ send(child, "\n")
+ expect(child, prompt)
+ write_str(child, "12 + 34 + 56 + 78")
+ check_line(child, "180")
+ send(child, "\x1b[A\x02\x14")
+ check_line(child, "189")
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Non-fatal error.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_bc12(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ bc_banner(child)
+ send(child, "12 +")
+ send(child, "\n")
+ time.sleep(1)
+ if not child.isalive():
+ print("child exited early")
+ print(str(child))
+ print(str(child.buffer))
+ sys.exit(1)
+ send(child, "quit")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+def test_dc_utf8_0(exe, args, env):
+ return test_utf8_0(exe, args, env, False)
+
+
+def test_dc_utf8_1(exe, args, env):
+ return test_utf8_1(exe, args, env, False)
+
+
+def test_dc_utf8_2(exe, args, env):
+ return test_utf8_2(exe, args, env, False)
+
+
+def test_dc_utf8_3(exe, args, env):
+ return test_utf8_3(exe, args, env, False)
+
+
+def test_dc_utf8_4(exe, args, env):
+ return test_utf8_4(exe, args, env, False)
+
+
+# Basic dc test.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_dc1(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ write_str(child, "1pR")
+ check_line(child, "1")
+ write_str(child, "1pR")
+ check_line(child, "1")
+ write_str(child, "q")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# SIGINT with quit.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_dc2(exe, args, env):
+
+ env["TERM"] = "dumb"
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ child.sendline("1pR")
+ check_line(child, "1", history=False)
+ time.sleep(1)
+ child.sendintr()
+ child.sendline("q")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# Execute string.
+# @param exe The executable.
+# @param args The arguments to pass to the executable.
+# @param env The environment.
+def test_dc3(exe, args, env):
+
+ child = pexpect.spawn(exe, args=args, env=env)
+
+ try:
+ write_str(child, "[1 15+pR]x")
+ check_line(child, "16")
+ write_str(child, "1pR")
+ check_line(child, "1")
+ write_str(child, "q")
+ send(child, "\n")
+ wait(child)
+ except pexpect.TIMEOUT:
+ traceback.print_tb(sys.exc_info()[2])
+ print("timed out")
+ print(str(child))
+ sys.exit(2)
+ except pexpect.EOF:
+ print("EOF")
+ print(str(child))
+ print(str(child.buffer))
+ print(str(child.before))
+ sys.exit(2)
+
+ return child
+
+
+# The array of bc tests.
+bc_tests = [
+ test_bc_utf8_0,
+ test_bc_utf8_1,
+ test_bc_utf8_2,
+ test_bc_utf8_3,
+ test_bc_utf8_4,
+ test_sigint_sigquit,
+ test_eof,
+ test_sigint,
+ test_sigtstp,
+ test_sigstop,
+ test_bc1,
+ test_bc2,
+ test_bc3,
+ test_bc4,
+ test_bc5,
+ test_bc6,
+ test_bc7,
+ test_bc8,
+ test_bc9,
+ test_bc10,
+ test_bc11,
+ test_bc12,
+]
+
+# The array of dc tests.
+dc_tests = [
+ test_dc_utf8_0,
+ test_dc_utf8_1,
+ test_dc_utf8_2,
+ test_dc_utf8_3,
+ test_sigint_sigquit,
+ test_eof,
+ test_sigint,
+ test_dc1,
+ test_dc2,
+ test_dc3,
+]
+
+
+# Print the usage and exit with an error.
+def usage():
+ print("usage: {} [-t] dir [-a] test_idx [exe options...]".format(script))
+ print(" The valid values for dir are: 'bc' and 'dc'.")
+ print(" The max test_idx for bc is {}.".format(len(bc_tests) - 1))
+ print(" The max test_idx for dc is {}.".format(len(dc_tests) - 1))
+ print(" If -a is given, the number of tests for dir is printed.")
+ print(" No tests are run.")
+ sys.exit(1)
+
+
+# Must run this script alone.
+if __name__ != "__main__":
+ usage()
+
+if len(sys.argv) < 2:
+ usage()
+
+idx = 1
+
+exedir = sys.argv[idx]
+
+idx += 1
+
+if exedir == "-t":
+ do_test = True
+ exedir = sys.argv[idx]
+ idx += 1
+else:
+ do_test = False
+
+test_idx = sys.argv[idx]
+
+idx += 1
+
+if test_idx == "-a":
+ if exedir == "bc":
+ l = len(bc_tests)
+ else:
+ l = len(dc_tests)
+ print("{}".format(l))
+ sys.exit(0)
+
+test_idx = int(test_idx)
+
+# Set a default executable unless we have one.
+if len(sys.argv) >= idx + 1:
+ exe = sys.argv[idx]
+else:
+ exe = testdir + "/../bin/" + exedir
+
+exebase = os.path.basename(exe)
+
+# Use the correct options.
+if exebase == "bc":
+ halt = "halt\n"
+ options = "-l"
+ test_array = bc_tests
+else:
+ halt = "q\n"
+ options = "-x"
+ test_array = dc_tests
+
+# More command-line processing.
+if len(sys.argv) > idx + 1:
+ exe = [ exe, sys.argv[idx + 1:], options ]
+else:
+ exe = [ exe, options ]
+
+# This is the environment necessary for most tests.
+env = {
+ "BC_BANNER": "1",
+ "BC_PROMPT": "1",
+ "DC_PROMPT": "1",
+ "BC_TTY_MODE": "1",
+ "DC_TTY_MODE": "1",
+ "BC_SIGINT_RESET": "1",
+ "DC_SIGINT_RESET": "1",
+}
+
+# Make sure to include the outside environment.
+env.update(os.environ)
+env.pop("BC_ENV_ARGS", None)
+env.pop("BC_LINE_LENGTH", None)
+env.pop("DC_ENV_ARGS", None)
+env.pop("DC_LINE_LENGTH", None)
+
+# Run the correct test.
+child = test_array[test_idx](exe[0], exe[1:], env)
+
+child.close()
+
+exit = child.exitstatus
+
+if exit is not None and exit != 0:
+ print("child failed; expected exit code 0, got {}".format(exit))
+ print(str(child))
+ sys.exit(1)
diff --git a/contrib/bc/tests/history.sh b/contrib/bc/tests/history.sh
new file mode 100755
index 000000000000..92db985a4f86
--- /dev/null
+++ b/contrib/bc/tests/history.sh
@@ -0,0 +1,110 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+script="$0"
+
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+# usage: history.sh dir -a|idx [exe args...]
+
+# If Python does not exist, then just skip.
+py=$(command -v python3)
+err=$?
+
+if [ "$err" -ne 0 ]; then
+
+ py=$(command -v python)
+ err=$?
+
+ if [ "$err" -ne 0 ]; then
+ printf 'Could not find Python 3.\n'
+ printf 'Skipping %s history tests...\n' "$d"
+ exit 0
+ fi
+fi
+
+# d is "bc" or "dc"
+d="$1"
+shift
+
+# idx is either an index of the test to run or "-a". If it is "-a", then all
+# tests are run.
+idx="$1"
+shift
+
+if [ "$#" -gt 0 ]; then
+
+ # exe is the executable to run.
+ exe="$1"
+ shift
+
+else
+ exe="$testdir/../bin/$d"
+fi
+
+if [ "$d" = "bc" ]; then
+ flip="! %s"
+ addone="%s + 1"
+else
+ flip="%s Np"
+ addone="%s 1+p"
+fi
+
+# Set the test range correctly for all tests or one test. st is the start index.
+if [ "$idx" = "-a" ]; then
+ idx=$("$py" "$testdir/history.py" "$d" -a)
+ idx=$(printf '%s - 1\n' "$idx" | bc)
+ st=0
+else
+ st="$idx"
+fi
+
+# Run all of the tests.
+for i in $(seq "$st" "$idx"); do
+
+ printf 'Running %s history test %d...' "$d" "$i"
+
+ for j in $(seq 1 3); do
+
+ "$py" "$testdir/history.py" "$d" "$i" "$exe" "$@"
+ err="$?"
+
+ if [ "$err" -eq 0 ]; then
+ break
+ fi
+
+ done
+
+ checktest_retcode "$d" "$err" "$d history test $i"
+
+ printf 'pass\n'
+
+done
diff --git a/contrib/bc/tests/other.sh b/contrib/bc/tests/other.sh
new file mode 100755
index 000000000000..bd0014641846
--- /dev/null
+++ b/contrib/bc/tests/other.sh
@@ -0,0 +1,411 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir}
+
+# Command-line processing.
+if [ "$#" -ge 2 ]; then
+
+ d="$1"
+ shift
+
+ extra_math="$1"
+ shift
+
+else
+ err_exit "usage: $script dir extra_math [exec args...]" 1
+fi
+
+if [ "$#" -lt 1 ]; then
+ exe="$testdir/../bin/$d"
+else
+ exe="$1"
+ shift
+fi
+
+if [ "$d" = "bc" ]; then
+ halt="quit"
+else
+ halt="q"
+fi
+
+# For tests later.
+num=100000000000000000000000000000000000000000000000000000000000000000000000000000
+num2="$num"
+numres="$num"
+num70="10000000000000000000000000000000000000000000000000000000000000000000\\
+0000000000"
+
+# Set stuff for the correct calculator.
+if [ "$d" = "bc" ]; then
+ halt="halt"
+ opt="x"
+ lopt="extended-register"
+ line_var="BC_LINE_LENGTH"
+ lltest="line_length()"
+else
+ halt="q"
+ opt="l"
+ lopt="mathlib"
+ line_var="DC_LINE_LENGTH"
+ num="$num pR"
+ lltest="glpR"
+fi
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+set +e
+
+printf '\nRunning %s quit test...' "$d"
+
+printf '%s\n' "$halt" | "$exe" "$@" > /dev/null 2>&1
+
+checktest_retcode "$d" "$?" "quit"
+
+# bc has two halt or quit commands, so test the second as well.
+if [ "$d" = bc ]; then
+
+ printf '%s\n' "quit" | "$exe" "$@" > /dev/null 2>&1
+
+ checktest_retcode "$d" "$?" quit
+
+ two=$("$exe" "$@" -e 1+1 -e quit)
+
+ checktest_retcode "$d" "$?" quit
+
+ if [ "$two" != "2" ]; then
+ err_exit "$d failed test quit" 1
+ fi
+fi
+
+printf 'pass\n'
+
+base=$(basename "$exe")
+
+printf 'Running %s environment var tests...' "$d"
+
+if [ "$d" = "bc" ]; then
+
+ export BC_ENV_ARGS=" '-l' '' -q"
+
+ printf 's(.02893)\n' | "$exe" "$@" > /dev/null
+
+ checktest_retcode "$d" "$?" "environment var"
+
+ "$exe" "$@" -e 4 > /dev/null
+
+ err="$?"
+ checktest_retcode "$d" "$?" "environment var"
+
+ printf 'pass\n'
+
+ printf 'Running keyword redefinition test...'
+
+ unset BC_ENV_ARGS
+
+ redefine_res="$outputdir/bc_outputs/redefine.txt"
+ redefine_out="$outputdir/bc_outputs/redefine_results.txt"
+
+ outdir=$(dirname "$easter_out")
+
+ if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+ fi
+
+ printf '5\n0\n' > "$redefine_res"
+
+ "$exe" "$@" --redefine=print -e 'define print(x) { x }' -e 'print(5)' > "$redefine_out"
+
+ checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out"
+
+ "$exe" "$@" -r "abs" -r "else" -e 'abs = 5;else = 0' -e 'abs;else' > "$redefine_out"
+
+ checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out"
+
+ if [ "$extra_math" -ne 0 ]; then
+
+ "$exe" "$@" -lr abs -e "perm(5, 1)" -e "0" > "$redefine_out"
+
+ checktest "$d" "$err" "keyword not redefined in builtin library" "$redefine_res" "$redefine_out"
+
+ fi
+
+ "$exe" "$@" -r "break" -e 'define break(x) { x }' 2> "$redefine_out"
+ err="$?"
+
+ checkerrtest "$d" "$err" "keyword redefinition error" "$redefine_out" "$d"
+
+ "$exe" "$@" -e 'define read(x) { x }' 2> "$redefine_out"
+ err="$?"
+
+ checkerrtest "$d" "$err" "Keyword redefinition error without BC_REDEFINE_KEYWORDS" "$redefine_out" "$d"
+
+ printf 'pass\n'
+
+else
+
+ export DC_ENV_ARGS="'-x'"
+ export DC_EXPR_EXIT="1"
+
+ printf '4s stuff\n' | "$exe" "$@" > /dev/null
+
+ checktest_retcode "$d" "$?" "environment var"
+
+ "$exe" "$@" -e 4pR > /dev/null
+
+ checktest_retcode "$d" "$?" "environment var"
+
+ printf 'pass\n'
+
+ set +e
+
+ # dc has an extra test for a case that someone found running this easter.dc
+ # script. It went into an infinite loop, so we want to check that we did not
+ # regress.
+ printf 'three\n' | cut -c1-3 > /dev/null
+ err=$?
+
+ if [ "$err" -eq 0 ]; then
+
+ printf 'Running dc Easter script...'
+
+ easter_res="$outputdir/dc_outputs/easter.txt"
+ easter_out="$outputdir/dc_outputs/easter_results.txt"
+
+ outdir=$(dirname "$easter_out")
+
+ if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+ fi
+
+ printf '4 April 2021\n' > "$easter_res"
+
+ "$testdir/dc/scripts/easter.sh" "$exe" 2021 "$@" | cut -c1-12 > "$easter_out"
+ err="$?"
+
+ checktest "$d" "$err" "Easter script" "$easter_res" "$easter_out"
+
+ printf 'pass\n'
+ fi
+
+fi
+
+out1="$outputdir/${d}_outputs/${d}_other.txt"
+out2="$outputdir/${d}_outputs/${d}_other_test.txt"
+
+printf 'Running %s line length tests...' "$d"
+
+printf '%s\n' "$numres" > "$out1"
+
+export "$line_var"=80
+printf '%s\n' "$num" | "$exe" "$@" > "$out2"
+
+checktest "$d" "$?" "line length" "$out1" "$out2"
+
+printf '%s\n' "$num70" > "$out1"
+
+export "$line_var"=2147483647
+printf '%s\n' "$num" | "$exe" "$@" > "$out2"
+
+checktest "$d" "$?" "line length 2" "$out1" "$out2"
+
+printf '%s\n' "$num2" > "$out1"
+
+export "$line_var"=62
+printf '%s\n' "$num" | "$exe" "$@" -L > "$out2"
+
+checktest "$d" "$?" "line length 3" "$out1" "$out2"
+
+printf '0\n' > "$out1"
+printf '%s\n' "$lltest" | "$exe" "$@" -L > "$out2"
+
+checktest "$d" "$?" "line length 3" "$out1" "$out2"
+
+printf 'pass\n'
+
+printf '%s\n' "$numres" > "$out1"
+export "$line_var"=2147483647
+
+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"
+
+checktest "$d" "$?" "arg" "$out1" "$out2"
+
+printf '%s\n' "$halt" | "$exe" "$@" -- "$f" "$f" "$f" "$f" > "$out2"
+
+checktest "$d" "$?" "arg" "$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
+checktest_retcode "$d" "$?" "arg"
+printf '%s\n' "$halt" | "$exe" "$@" -P > /dev/null
+checktest_retcode "$d" "$?" "arg"
+printf '%s\n' "$halt" | "$exe" "$@" -R > /dev/null
+checktest_retcode "$d" "$?" "arg"
+printf '%s\n' "$halt" | "$exe" "$@" -v > /dev/null
+checktest_retcode "$d" "$?" "arg"
+printf '%s\n' "$halt" | "$exe" "$@" -V > /dev/null
+checktest_retcode "$d" "$?" "arg"
+
+out=$(printf '0.1\n-0.1\n1.1\n-1.1\n0.1\n-0.1\n')
+printf '%s\n' "$out" > "$out1"
+
+if [ "$d" = "bc" ]; then
+ data=$(printf '0.1\n-0.1\n1.1\n-1.1\n.1\n-.1\n')
+else
+ data=$(printf '0.1pR\n_0.1pR\n1.1pR\n_1.1pR\n.1pR\n_.1pR\n')
+fi
+
+printf '%s\n' "$data" | "$exe" "$@" -z > "$out2"
+checktest "$d" "$?" "leading zero" "$out1" "$out2"
+
+if [ "$d" = "bc" ] && [ "$extra_math" -ne 0 ]; then
+
+ printf '%s\n' "$halt" | "$exe" "$@" -lz "$testdir/bc/leadingzero.txt" > "$out2"
+
+ checktest "$d" "$?" "leading zero script" "$testdir/bc/leadingzero_results.txt" "$out2"
+
+fi
+
+"$exe" "$@" -f "saotehasotnehasthistohntnsahxstnhalcrgxgrlpyasxtsaosysxsatnhoy.txt" > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "invalid file argument" "$out2" "$d"
+
+"$exe" "$@" "-$opt" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "invalid option argument" "$out2" "$d"
+
+"$exe" "$@" "--$lopt" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "invalid long option argument" "$out2" "$d"
+
+"$exe" "$@" "-u" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "unrecognized option argument" "$out2" "$d"
+
+"$exe" "$@" "--uniform" -e "$exprs" > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "unrecognized long option argument" "$out2" "$d"
+
+"$exe" "$@" -f > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "missing required argument to short option" "$out2" "$d"
+
+"$exe" "$@" --file > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "missing required argument to long option" "$out2" "$d"
+
+"$exe" "$@" --version=5 > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "given argument to long option with no argument" "$out2" "$d"
+
+"$exe" "$@" -: > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "colon short option" "$out2" "$d"
+
+"$exe" "$@" --: > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$d" "$err" "colon long option" "$out2" "$d"
+
+printf 'pass\n'
+
+printf 'Running %s directory test...' "$d"
+
+"$exe" "$@" "$testdir" > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$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="$?"
+
+checkerrtest "$d" "$err" "binary file" "$out2" "$d"
+
+printf 'pass\n'
+
+printf 'Running %s binary stdin test...' "$d"
+
+cat "$bin" | "$exe" "$@" > /dev/null 2> "$out2"
+err="$?"
+
+checkerrtest "$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
+
+ checktest_retcode "$d" "$?" "limits"
+
+ if [ ! -s "$out2" ]; then
+ err_exit "$d did not produce output on the limits test" 1
+ fi
+
+ exec printf 'pass\n'
+
+fi
diff --git a/contrib/bc/tests/read.sh b/contrib/bc/tests/read.sh
new file mode 100755
index 000000000000..a1915eb271ac
--- /dev/null
+++ b/contrib/bc/tests/read.sh
@@ -0,0 +1,140 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+
+script="$0"
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir}
+
+# Command-line processing.
+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="$outputdir/${d}_outputs/read_results.txt"
+outdir=$(dirname "$out")
+
+# Make sure the directory exists.
+if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+fi
+
+exebase=$(basename "$exe")
+
+# Set stuff for the correct calculator.
+if [ "$d" = "bc" ]; then
+ options="-lq"
+ halt="halt"
+ read_call="read()"
+ read_expr="${read_call}\n5+5;"
+else
+ options="-x"
+ halt="q"
+ read_call="?"
+ read_expr="${read_call}"
+fi
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+printf 'Running %s read...' "$d"
+
+set +e
+
+# Run read() on every line.
+while read line; do
+
+ printf '%s\n%s\n' "$read_call" "$line" | "$exe" "$@" "$options" > "$out"
+ checktest "$d" "$?" 'read' "$results" "$out"
+
+done < "$name"
+
+printf 'pass\n'
+
+printf 'Running %s read errors...' "$d"
+
+# Run read on every line.
+while read line; do
+
+ printf '%s\n%s\n' "$read_call" "$line" | "$exe" "$@" "$options" 2> "$out" > /dev/null
+ err="$?"
+
+ checkerrtest "$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="$?"
+
+checkerrtest "$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="$?"
+
+checkerrtest "$d" "$err" "$read_test" "$out" "$exebase"
+
+exec printf 'pass\n'
diff --git a/contrib/bc/tests/script.sed b/contrib/bc/tests/script.sed
new file mode 100644
index 000000000000..e266b8690168
--- /dev/null
+++ b/contrib/bc/tests/script.sed
@@ -0,0 +1,9 @@
+/[^\\]$/ {
+ p;
+}
+/\\$/ {
+ N;
+ s/\\\n\([0-9]\)$/\1/g;
+ p;
+}
+d;
diff --git a/contrib/bc/tests/script.sh b/contrib/bc/tests/script.sh
new file mode 100755
index 000000000000..162437af8f22
--- /dev/null
+++ b/contrib/bc/tests/script.sh
@@ -0,0 +1,185 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+
+script="$0"
+
+testdir=$(dirname "${script}")
+
+. "$testdir/../scripts/functions.sh"
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir}
+
+# Command-line processing.
+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
+
+# Set stuff for the correct calculator.
+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%.*}"
+
+# We specifically want to skip this because it is handled specially.
+if [ "$f" = "timeconst.bc" ]; then
+ exit 0
+fi
+
+# Skip the tests that require extra math if we don't have it.
+if [ "$run_extra_tests" -eq 0 ]; then
+ if [ "$f" = "rand.bc" ]; then
+ printf 'Skipping %s script: %s\n' "$d" "$f"
+ exit 0
+ fi
+fi
+
+# Skip the tests that require global stacks flag if we are not allowed to run
+# them.
+if [ "$run_stack_tests" -eq 0 ]; then
+
+ if [ "$f" = "globals.bc" ] || [ "$f" = "references.bc" ] || [ "$f" = "rand.bc" ]; then
+ printf 'Skipping %s script: %s\n' "$d" "$f"
+ exit 0
+ fi
+
+fi
+
+out="$outputdir/${d}_outputs/${name}_script_results.txt"
+outdir=$(dirname "$out")
+
+# Make sure the directory exists.
+if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+fi
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+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" "$f"
+ exit 0
+else
+ # This sed, and the script, are to remove an incompatibility with GNU bc,
+ # where GNU bc is wrong. See the development manual
+ # (manuals/development.md#script-tests) for more information.
+ printf 'Generating %s results...' "$f"
+ printf '%s\n' "$halt" | "$d" "$s" | sed -n -f "$testdir/script.sed" > "$results"
+ printf 'done\n'
+ res="$results"
+fi
+
+set +e
+
+printf 'Running %s script %s...' "$d" "$f"
+
+# Yes this is poor timing, but it works.
+if [ "$time_tests" -ne 0 ]; then
+ printf '\n'
+ printf '%s\n' "$halt" | /usr/bin/time -p "$exe" "$@" $options "$s" > "$out"
+ err="$?"
+ printf '\n'
+else
+ printf '%s\n' "$halt" | "$exe" "$@" $options "$s" > "$out"
+ err="$?"
+fi
+
+checktest "$d" "$err" "script $f" "$res" "$out"
+
+rm -f "$out"
+
+exec printf 'pass\n'
diff --git a/contrib/bc/tests/scripts.sh b/contrib/bc/tests/scripts.sh
new file mode 100755
index 000000000000..46aa7e761170
--- /dev/null
+++ b/contrib/bc/tests/scripts.sh
@@ -0,0 +1,132 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+script="$0"
+
+testdir=$(dirname "${script}")
+
+pids=""
+
+# We need to figure out if we should run stuff in parallel.
+pll=1
+
+while getopts "n" opt; do
+
+ case "$opt" in
+ n) pll=0 ; shift ; set -e ;;
+ ?) usage "Invalid option: $opt" ;;
+ esac
+
+done
+
+# Command-line processing.
+if [ "$#" -eq 0 ]; then
+ printf 'usage: %s [-n] 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"
+
+scripts=$(cat "$scriptdir/all.txt")
+
+# Run each script test individually.
+for s in $scripts; do
+
+ f=$(basename "$s")
+
+ if [ "$pll" -ne 0 ]; then
+ sh "$testdir/script.sh" "$d" "$f" "$run_extra_tests" "$run_stack_tests" \
+ "$generate" "$time_tests" "$exe" "$@" &
+ pids="$pids $!"
+ else
+ sh "$testdir/script.sh" "$d" "$f" "$run_extra_tests" "$run_stack_tests" \
+ "$generate" "$time_tests" "$exe" "$@"
+ fi
+
+done
+
+if [ "$pll" -ne 0 ]; then
+
+ exit_err=0
+
+ for p in $pids; do
+
+ wait "$p"
+ err="$?"
+
+ if [ "$err" -ne 0 ]; then
+ printf 'A script failed!\n'
+ exit_err=1
+ fi
+
+ done
+
+ if [ "$exit_err" -ne 0 ]; then
+ exit 1
+ fi
+
+fi
diff --git a/contrib/bc/tests/stdin.sh b/contrib/bc/tests/stdin.sh
new file mode 100755
index 000000000000..c9e02253c30a
--- /dev/null
+++ b/contrib/bc/tests/stdin.sh
@@ -0,0 +1,103 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+
+script="$0"
+
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir}
+
+# Command-line processing.
+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="$outputdir/${d}_outputs/stdin_results.txt"
+outdir=$(dirname "$out")
+
+# Make sure the directory exists.
+if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+fi
+
+# Set stuff for the correct calculator.
+if [ "$d" = "bc" ]; then
+ options="-lq"
+else
+ options="-x"
+fi
+
+rm -f "$out"
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+set +e
+
+printf 'Running %s stdin tests...' "$d"
+
+# Run the file through stdin.
+cat "$testdir/$d/stdin.txt" | "$exe" "$@" "$options" > "$out" 2> /dev/null
+checktest "$d" "$?" "stdin" "$testdir/$d/stdin_results.txt" "$out"
+
+# bc has some more tests; run those.
+if [ "$d" = "bc" ]; then
+
+ cat "$testdir/$d/stdin1.txt" | "$exe" "$@" "$options" > "$out" 2> /dev/null
+ checktest "$d" "$?" "stdin" "$testdir/$d/stdin1_results.txt" "$out"
+
+ cat "$testdir/$d/stdin2.txt" | "$exe" "$@" "$options" > "$out" 2> /dev/null
+ checktest "$d" "$?" "stdin" "$testdir/$d/stdin2_results.txt" "$out"
+fi
+
+rm -f "$out"
+
+exec printf 'pass\n'
diff --git a/contrib/bc/tests/test.sh b/contrib/bc/tests/test.sh
new file mode 100755
index 000000000000..9d557a715dc0
--- /dev/null
+++ b/contrib/bc/tests/test.sh
@@ -0,0 +1,151 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+set -e
+
+script="$0"
+
+testdir=$(dirname "$script")
+
+. "$testdir/../scripts/functions.sh"
+
+outputdir=${BC_TEST_OUTPUT_DIR:-$testdir}
+
+# Command-line processing.
+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="$outputdir/${d}_outputs/${t}_results.txt"
+outdir=$(dirname "$out")
+
+# Make sure the directory exists.
+if [ ! -d "$outdir" ]; then
+ mkdir -p "$outdir"
+fi
+
+# I use these, so unset them to make the tests work.
+unset BC_ENV_ARGS
+unset BC_LINE_LENGTH
+unset DC_ENV_ARGS
+unset DC_LINE_LENGTH
+
+# Set stuff for the correct calculator.
+if [ "$d" = "bc" ]; then
+ options="-lq"
+ var="BC_LINE_LENGTH"
+ halt="halt"
+else
+ options=""
+ var="DC_LINE_LENGTH"
+ halt="q"
+fi
+
+# If the test does not exist...
+if [ ! -f "$name" ]; then
+
+ # Skip if we can't generate.
+ if [ "$generate_tests" -eq 0 ]; then
+ printf 'Skipping %s %s test\n' "$d" "$t"
+ exit 0
+ fi
+
+ # Generate.
+ printf 'Generating %s %s...' "$d" "$t"
+ "$d" "$testdir/$d/scripts/$t.$d" > "$name"
+ printf 'done\n'
+fi
+
+# If the results do not exist, generate..
+if [ ! -f "$results" ]; then
+ printf 'Generating %s %s results...' "$d" "$t"
+ printf '%s\n' "$halt" | "$d" $options "$name" > "$results"
+ printf 'done\n'
+fi
+
+# We set this here because GNU dc does not have it.
+if [ "$d" = "dc" ]; then
+ options="-x"
+fi
+
+export $var=string
+
+set +e
+
+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"
+ err="$?"
+ printf '\n'
+else
+ printf '%s\n' "$halt" | "$exe" "$@" $options "$name" > "$out"
+ err="$?"
+fi
+
+checktest "$d" "$err" "$t" "$results" "$out"
+
+rm -f "$out"
+
+exec printf 'pass\n'
diff --git a/contrib/bc/vs/bc.sln b/contrib/bc/vs/bc.sln
new file mode 100644
index 000000000000..daf1a4a12bd8
--- /dev/null
+++ b/contrib/bc/vs/bc.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31515.178
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bc", "bc.vcxproj", "{4450D61F-2535-4085-B1B1-F96ACD23CC9F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Debug|x64.ActiveCfg = Debug|x64
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Debug|x64.Build.0 = Debug|x64
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Debug|x86.ActiveCfg = Debug|Win32
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Debug|x86.Build.0 = Debug|Win32
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Release|x64.ActiveCfg = Release|x64
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Release|x64.Build.0 = Release|x64
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Release|x86.ActiveCfg = Release|Win32
+ {4450D61F-2535-4085-B1B1-F96ACD23CC9F}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {99364EF5-C65F-4658-A3FA-19EAC64BE8B9}
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/bc/vs/bc.vcxproj b/contrib/bc/vs/bc.vcxproj
new file mode 100644
index 000000000000..19b53d66a405
--- /dev/null
+++ b/contrib/bc/vs/bc.vcxproj
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectGuid>{4450d61f-2535-4085-b1b1-f96acd23cc9f}</ProjectGuid>
+ <RootNamespace>bc</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>bin\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>bin\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>bin\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets>
+ <GenerateManifest>false</GenerateManifest>
+ <OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>bin\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PostBuildEvent>
+ <Command>copy /b /y $(OutDir)bc.exe $(OutDir)dc.exe</Command>
+ </PostBuildEvent>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PostBuildEvent>
+ <Command>copy /b /y $(OutDir)bc.exe $(OutDir)dc.exe</Command>
+ </PostBuildEvent>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PostBuildEvent>
+ <Command>copy /b /y $(OutDir)bc.exe $(OutDir)dc.exe</Command>
+ </PostBuildEvent>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalDependencies>bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PostBuildEvent>
+ <Command>copy /b /y $(OutDir)bc.exe $(OutDir)dc.exe</Command>
+ </PostBuildEvent>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\include\args.h" />
+ <ClInclude Include="..\include\bc.h" />
+ <ClInclude Include="..\include\bcl.h" />
+ <ClInclude Include="..\include\dc.h" />
+ <ClInclude Include="..\include\file.h" />
+ <ClInclude Include="..\include\history.h" />
+ <ClInclude Include="..\include\lang.h" />
+ <ClInclude Include="..\include\lex.h" />
+ <ClInclude Include="..\include\library.h" />
+ <ClInclude Include="..\include\num.h" />
+ <ClInclude Include="..\include\opt.h" />
+ <ClInclude Include="..\include\parse.h" />
+ <ClInclude Include="..\include\program.h" />
+ <ClInclude Include="..\include\rand.h" />
+ <ClInclude Include="..\include\read.h" />
+ <ClInclude Include="..\include\status.h" />
+ <ClInclude Include="..\include\vector.h" />
+ <ClInclude Include="..\include\version.h" />
+ <ClInclude Include="..\include\vm.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\gen\strgen.c">
+ <FileType>CppCode</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">cl.exe /Fo:$(OutDir)strgen.obj /Fe:$(OutDir)strgen.exe %(Identity)</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)strgen.exe</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">cl.exe /Fo:$(OutDir)strgen.obj /Fe:$(OutDir)strgen.exe %(Identity)</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)strgen.exe</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl.exe /Fo:$(OutDir)strgen.obj /Fe:$(OutDir)strgen.exe %(Identity)</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)strgen.exe</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl.exe /Fo:$(OutDir)strgen.obj /Fe:$(OutDir)strgen.exe %(Identity)</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)strgen.exe</Outputs>
+ </CustomBuild>
+ <ClCompile Include="src2\bc_help.c" />
+ <ClCompile Include="src2\dc_help.c" />
+ <ClCompile Include="src2\lib.c" />
+ <ClCompile Include="src2\lib2.c" />
+ <ClCompile Include="..\src\args.c" />
+ <ClCompile Include="..\src\bc.c" />
+ <ClCompile Include="..\src\bc_lex.c" />
+ <ClCompile Include="..\src\bc_parse.c" />
+ <ClCompile Include="..\src\data.c" />
+ <ClCompile Include="..\src\dc.c" />
+ <ClCompile Include="..\src\dc_lex.c" />
+ <ClCompile Include="..\src\dc_parse.c" />
+ <ClCompile Include="..\src\file.c" />
+ <ClCompile Include="..\src\lang.c" />
+ <ClCompile Include="..\src\lex.c" />
+ <ClCompile Include="..\src\library.c" />
+ <ClCompile Include="..\src\main.c" />
+ <ClCompile Include="..\src\num.c" />
+ <ClCompile Include="..\src\opt.c" />
+ <ClCompile Include="..\src\parse.c" />
+ <ClCompile Include="..\src\program.c" />
+ <ClCompile Include="..\src\rand.c" />
+ <ClCompile Include="..\src\read.c" />
+ <ClCompile Include="..\src\vector.c" />
+ <ClCompile Include="..\src\vm.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\gen\lib.bc">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)strgen.exe %(Identity) src2\lib.c bc_lib bc_lib_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">src2\lib.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)strgen.exe %(Identity) src2\lib.c bc_lib bc_lib_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">src2\lib.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)strgen.exe %(Identity) src2\lib.c bc_lib bc_lib_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">src2\lib.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)strgen.exe %(Identity) src2\lib.c bc_lib bc_lib_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">src2\lib.c</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\gen\lib2.bc">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)strgen.exe %(Identity) src2\lib2.c bc_lib2 bc_lib2_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">src2\lib2.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)strgen.exe %(Identity) src2\lib2.c bc_lib2 bc_lib2_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">src2\lib2.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)strgen.exe %(Identity) src2\lib2.c bc_lib2 bc_lib2_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">src2\lib2.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)strgen.exe %(Identity) src2\lib2.c bc_lib2 bc_lib2_name BC_ENABLED 1</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">src2\lib2.c</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\gen\dc_help.txt">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)strgen.exe %(Identity) src2\dc_help.c dc_help "" DC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">src2\dc_help.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)strgen.exe %(Identity) src2\dc_help.c dc_help "" DC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">src2\dc_help.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)strgen.exe %(Identity) src2\dc_help.c dc_help "" DC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">src2\dc_help.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)strgen.exe %(Identity) src2\dc_help.c dc_help "" DC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">src2\dc_help.c</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\gen\bc_help.txt">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)strgen.exe %(Identity) src2\bc_help.c bc_help "" BC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">src2\bc_help.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)strgen.exe %(Identity) src2\bc_help.c bc_help "" BC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">src2\bc_help.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)strgen.exe %(Identity) src2\bc_help.c bc_help "" BC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">src2\bc_help.c</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)strgen.exe %(Identity) src2\bc_help.c bc_help "" BC_ENABLED</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">src2\bc_help.c</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/contrib/bc/vs/bc.vcxproj.filters b/contrib/bc/vs/bc.vcxproj.filters
new file mode 100644
index 000000000000..f26387253f27
--- /dev/null
+++ b/contrib/bc/vs/bc.vcxproj.filters
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{ef855c5b-fc2c-4736-bb38-346aae9184f7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include">
+ <UniqueIdentifier>{df4ea0e1-2549-4c13-bf11-79ba8ba4cad9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="gen">
+ <UniqueIdentifier>{1bbcb2e0-c1a0-417e-88bf-8eda8a53714e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src2">
+ <UniqueIdentifier>{c384b486-4ea2-473a-8b04-86f2f5f7bb69}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\include\args.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\bc.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\bcl.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\dc.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\file.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\history.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\lang.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\lex.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\library.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\num.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\opt.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\parse.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\program.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\rand.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\read.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\status.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\vector.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\version.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\vm.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\args.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\bc.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\bc_lex.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\bc_parse.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\data.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\dc.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\dc_lex.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\dc_parse.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\file.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\history.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\lang.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\lex.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\library.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\main.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\num.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\opt.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\parse.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\program.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\rand.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\read.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\vector.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\vm.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="src2\bc_help.c">
+ <Filter>src2</Filter>
+ </ClCompile>
+ <ClCompile Include="src2\dc_help.c">
+ <Filter>src2</Filter>
+ </ClCompile>
+ <ClCompile Include="src2\lib.c">
+ <Filter>src2</Filter>
+ </ClCompile>
+ <ClCompile Include="src2\lib2.c">
+ <Filter>src2</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\gen\lib.bc">
+ <Filter>gen</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\gen\lib2.bc">
+ <Filter>gen</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\gen\dc_help.txt">
+ <Filter>gen</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\gen\bc_help.txt">
+ <Filter>gen</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\gen\strgen.c">
+ <Filter>gen</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/contrib/bc/vs/bcl.sln b/contrib/bc/vs/bcl.sln
new file mode 100644
index 000000000000..bc6d37a72360
--- /dev/null
+++ b/contrib/bc/vs/bcl.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31515.178
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bcl", "bcl.vcxproj", "{76B451C9-72BF-45B2-B78D-B3515410F99F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ ReleaseMD|x64 = ReleaseMD|x64
+ ReleaseMD|x86 = ReleaseMD|x86
+ ReleaseMT|x64 = ReleaseMT|x64
+ ReleaseMT|x86 = ReleaseMT|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.Debug|x64.ActiveCfg = Debug|x64
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.Debug|x64.Build.0 = Debug|x64
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.Debug|x86.ActiveCfg = Debug|Win32
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.Debug|x86.Build.0 = Debug|Win32
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMD|x64.ActiveCfg = ReleaseMD|x64
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMD|x64.Build.0 = ReleaseMD|x64
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMD|x86.ActiveCfg = ReleaseMD|Win32
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMD|x86.Build.0 = ReleaseMD|Win32
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMT|x64.Build.0 = ReleaseMT|x64
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMT|x86.ActiveCfg = ReleaseMT|Win32
+ {76B451C9-72BF-45B2-B78D-B3515410F99F}.ReleaseMT|x86.Build.0 = ReleaseMT|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C943D6A7-81EA-47C8-90D6-7DB528C262E7}
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/bc/vs/bcl.vcxproj b/contrib/bc/vs/bcl.vcxproj
new file mode 100644
index 000000000000..a8de10e9f10b
--- /dev/null
+++ b/contrib/bc/vs/bcl.vcxproj
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseMD|Win32">
+ <Configuration>ReleaseMD</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseMD|x64">
+ <Configuration>ReleaseMD</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseMT|Win32">
+ <Configuration>ReleaseMT</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseMT|x64">
+ <Configuration>ReleaseMT</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectGuid>{76b451c9-72bf-45b2-b78d-b3515410f99f}</ProjectGuid>
+ <RootNamespace>bcl</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>lib\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>lib\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>lib\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>lib\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>lib\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>lib\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>lib\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>lib\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>lib\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>lib\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>lib\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>lib\$(Platform)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMD|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\data.c" />
+ <ClCompile Include="..\src\library.c" />
+ <ClCompile Include="..\src\num.c" />
+ <ClCompile Include="..\src\rand.c" />
+ <ClCompile Include="..\src\vector.c" />
+ <ClCompile Include="..\src\vm.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\include\args.h" />
+ <ClInclude Include="..\include\bc.h" />
+ <ClInclude Include="..\include\bcl.h" />
+ <ClInclude Include="..\include\dc.h" />
+ <ClInclude Include="..\include\file.h" />
+ <ClInclude Include="..\include\history.h" />
+ <ClInclude Include="..\include\lang.h" />
+ <ClInclude Include="..\include\lex.h" />
+ <ClInclude Include="..\include\library.h" />
+ <ClInclude Include="..\include\num.h" />
+ <ClInclude Include="..\include\opt.h" />
+ <ClInclude Include="..\include\parse.h" />
+ <ClInclude Include="..\include\program.h" />
+ <ClInclude Include="..\include\rand.h" />
+ <ClInclude Include="..\include\read.h" />
+ <ClInclude Include="..\include\status.h" />
+ <ClInclude Include="..\include\vector.h" />
+ <ClInclude Include="..\include\version.h" />
+ <ClInclude Include="..\include\vm.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/contrib/bc/vs/bcl.vcxproj.filters b/contrib/bc/vs/bcl.vcxproj.filters
new file mode 100644
index 000000000000..b62d1899e2bf
--- /dev/null
+++ b/contrib/bc/vs/bcl.vcxproj.filters
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{4eccf85f-77c4-4ebd-b89c-3920075c5b2d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include">
+ <UniqueIdentifier>{48fc3219-18c1-42d7-b9f4-da5f65ab1ccc}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\data.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\library.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\num.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\rand.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\vector.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\vm.c">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\include\args.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\bc.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\bcl.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\dc.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\file.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\history.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\lang.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\lex.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\library.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\num.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\opt.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\parse.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\program.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\rand.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\read.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\status.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\vector.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\version.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\vm.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/contrib/bc/vs/bin/some.txt b/contrib/bc/vs/bin/some.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/bc/vs/bin/some.txt
diff --git a/contrib/bc/vs/tests/some.txt b/contrib/bc/vs/tests/some.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/bc/vs/tests/some.txt
diff --git a/contrib/bc/vs/tests/tests_bc.bat b/contrib/bc/vs/tests/tests_bc.bat
new file mode 100644
index 000000000000..5fbd4e35fc3a
--- /dev/null
+++ b/contrib/bc/vs/tests/tests_bc.bat
@@ -0,0 +1,104 @@
+@echo off
+
+set scripts=..\..\tests\bc
+set bc=%~dp0\bc.exe
+set args=-ql
+
+del /f /q *.txt > NUL
+
+
+rem excluded: all, errors, read_errors, posix_errors, misc6, misc7, recursive_arrays
+
+for %%i in (
+abs
+add
+arctangent
+arrays
+assignments
+bitfuncs
+boolean
+comp
+cosine
+decimal
+divide
+divmod
+engineering
+exponent
+functions
+globals
+length
+letters
+lib2
+log
+misc
+misc1
+misc2
+misc3
+misc4
+misc5
+modexp
+modulus
+multiply
+pi
+places
+power
+print2
+rand
+read
+scale
+scientific
+shift
+sine
+sqrt
+stdin
+stdin1
+stdin2
+strings
+subtract
+trunc
+vars
+void
+leadingzero
+) do (
+if exist "%scripts%\%%i.txt" (
+ "%bc%" "%args%" < "%scripts%\%%i.txt" > "%%i_results.txt"
+
+ if errorlevel 1 (
+ echo FAIL_RUNTIME: %%i
+ goto :eof
+ )
+
+ fc.exe "%scripts%\%%i_results.txt" "%%i_results.txt" > NUL
+
+ if errorlevel 1 (
+ echo FAIL_RESULTS: %%i
+ goto :eof
+ )
+
+ echo PASS: %%i
+) else (
+ echo FAIL_NOT_EXIST: %%i
+ goto :eof
+)
+)
+
+if exist "%scripts%\leadingzero.txt" (
+ "%bc%" "%args%" -z < "%scripts%\leadingzero.txt" > "leadingzero_z_results.txt"
+
+ if errorlevel 1 (
+ echo FAIL_RUNTIME: leadingzero_z
+ goto :eof
+ )
+
+ fc.exe "%scripts%\leadingzero_results.txt" "leadingzero_z_results.txt" > NUL
+
+ if errorlevel 1 (
+ echo FAIL_RESULTS: leadingzero_z
+ goto :eof
+ )
+
+ echo PASS: leadingzero_z
+) else (
+ echo FAIL_NOT_EXIST: leadingzero_z
+ goto :eof
+) \ No newline at end of file
diff --git a/contrib/bc/vs/tests/tests_dc.bat b/contrib/bc/vs/tests/tests_dc.bat
new file mode 100644
index 000000000000..36c97daa4e11
--- /dev/null
+++ b/contrib/bc/vs/tests/tests_dc.bat
@@ -0,0 +1,61 @@
+@echo off
+
+set scripts=..\..\tests\dc
+set dc=%~dp0\dc.exe
+set args=-x
+
+del /f /q *.txt > NUL
+
+
+rem excluded: all, errors, read_errors
+
+for %%i in (
+abs
+add
+boolean
+decimal
+divide
+divmod
+engineering
+exec_stack_len
+length
+misc
+modexp
+modulus
+multiply
+negate
+places
+power
+rand
+read
+scientific
+shift
+sqrt
+stack_len
+stdin
+strings
+subtract
+trunc
+vars
+) do (
+if exist "%scripts%\%%i.txt" (
+ "%dc%" "%args%" < "%scripts%\%%i.txt" > "%%i_results.txt"
+
+ if errorlevel 1 (
+ echo FAIL_RUNTIME: %%i
+ goto :eof
+ )
+
+ fc.exe "%scripts%\%%i_results.txt" "%%i_results.txt" > NUL
+
+ if errorlevel 1 (
+ echo FAIL_RESULTS: %%i
+ goto :eof
+ )
+
+ echo PASS: %%i
+) else (
+ echo FAIL_NOT_EXIST: %%i
+ goto :eof
+)
+) \ No newline at end of file