diff options
126 files changed, 226 insertions, 15951 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000000..845db62a72e6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,152 @@ +--- +Language:        Cpp +# BasedOnStyle:  LLVM +AccessModifierOffset: 1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: true +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: AllIfsAndElse +AllowShortLambdasOnASingleLine: Empty +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: All +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +#AttributeMacros: [] +BinPackArguments: true +BinPackParameters: true +#BitFieldColonSpacing: Both +BreakBeforeBraces: Custom +BraceWrapping: +  AfterCaseLabel:        true +  AfterClass:            true +  AfterControlStatement: true +  AfterEnum:             true +  AfterFunction:         true +  AfterNamespace:        true +  AfterObjCDeclaration:  true +  AfterStruct:           true +  AfterUnion:            true +  AfterExternBlock:      true +  BeforeCatch:           true +  BeforeElse:            true +  BeforeLambdaBody:      false +  BeforeWhile:           true +  IndentBraces:          false +  SplitEmptyFunction:    false +  SplitEmptyRecord:      false +  SplitEmptyNamespace:   false +BreakAfterJavaFieldAnnotations: true +BreakBeforeBinaryOperators: None +#BreakBeforeConceptDeclarations: true +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterColon +BreakStringLiterals: false +ColumnLimit:     80 +CommentPragmas:  '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DeriveLineEnding: false +DerivePointerAlignment: false +DisableFormat:   false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: +  - foreach +  - Q_FOREACH +  - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: +  - Regex:           '^<(sys|arpa|net|netinet)/.*\.h>' +    Priority:        2 +  - Regex:           '^<(args|bc|bcl|dc|file|history|lang|lex|library|num|opt|parse|program|rand|read|status|vector|version|vm)\.h>' +    Priority:        3 +  - Regex:           '^<.*\.h>' +    Priority:        0 +  - Regex:           '^<.*>' +    Priority:        1 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentExternBlock: NoIndent +IndentGotoLabels: false +IndentPPDirectives: None +#IndentPragmas: false +#IndentRequires: true +IndentWidth:     4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaImportGroups: [] +JavaScriptQuotes: Double +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MacroBlockBegin: '' +MacroBlockEnd:   '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +NamespaceMacros: [] +ObjCBinPackProtocolList: Always +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 1000 +PenaltyBreakBeforeFirstCallParameter: 429496720 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 42949672 +PenaltyBreakString: 10000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 42949672 +PenaltyIndentedWhitespace: 1 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +#RawStringFormats: +# This is used to get spaces around a bitwise and operator. +ReferenceAlignment: Middle +ReflowComments:  true +SortIncludes:    false +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +#SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles:  false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard:       Latest +TabWidth:       4 +TypenameMacros: [] +UseCRLF:        false +UseTab:         ForIndentation +WhitespaceSensitiveMacros: [] +... diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000000..04e13de763a2 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,43 @@ +Checks:            'clang-diagnostic-*,clang-analyzer-*' +WarningsAsErrors:  'clang-diagnostic-*,clang-analyzer-*' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle:     file +CheckOptions: +  - key:             llvm-else-after-return.WarnOnConditionVariables +    value:           'false' +  - key:             modernize-loop-convert.MinConfidence +    value:           reasonable +  - key:             modernize-replace-auto-ptr.IncludeStyle +    value:           llvm +  - key:             cert-str34-c.DiagnoseSignedUnsignedCharComparisons +    value:           'false' +  - key:             google-readability-namespace-comments.ShortNamespaceLines +    value:           '10' +  - key:             cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField +    value:           'false' +  - key:             cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic +    value:           'true' +  - key:             cert-dcl16-c.NewSuffixes +    value:           'L;LL;LU;LLU' +  - key:             google-readability-braces-around-statements.ShortStatementLines +    value:           '1' +  - key:             modernize-pass-by-value.IncludeStyle +    value:           llvm +  - key:             google-readability-namespace-comments.SpacesBeforeComments +    value:           '2' +  - key:             modernize-loop-convert.MaxCopySize +    value:           '16' +  - key:             cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors +    value:           'true' +  - key:             modernize-use-nullptr.NullMacros +    value:           'NULL' +  - key:             llvm-qualified-auto.AddConstToQualified +    value:           'false' +  - key:             modernize-loop-convert.NamingStyle +    value:           CamelCase +  - key:             llvm-else-after-return.WarnOnUnfixable +    value:           'false' +  - key:             google-readability-function-size.StatementThreshold +    value:           '800' +... @@ -1,5 +1,12 @@  # News +## 5.3.2 + +This is a production release that fixes prompt bugs with editline and readline +where the `BC_PROMPT` environment variable was not being respected. + +This also fixes editline and readline output on `EOF`. +  ## 5.3.1  This is a production release that fixes a build problem in the FreeBSD base diff --git a/benchmarks/bc/add.bc b/benchmarks/bc/add.bc deleted file mode 100644 index 90a83e4758d9..000000000000 --- a/benchmarks/bc/add.bc +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/bc -lq - -print "scale = 20\n" -print "x = 1234567890 / scale\n" -print "len = length(x) + 1 + scale\n" -print "len *= 2\n" - -scale = 20 -x = 1234567890 / scale -len = length(x) + 1 + scale -len *= 2 - -for (i = 0; i <= len; ++i) { -	print "a[", i, "] = x * (10^", i, ")\n" -} - -for (i = 1; i <= 10000; ++i) { -	for (j = 0; j < len; ++j) { -		print "v = a[", i, "] + a[", j, "]\n" -	} -} diff --git a/benchmarks/bc/arrays.bc b/benchmarks/bc/arrays.bc deleted file mode 100644 index cc0276d6ad20..000000000000 --- a/benchmarks/bc/arrays.bc +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/bc -# -# 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. -# - -max = 1000000 - -for (i = 0; i < max; ++i) { -	print "a", i, "[0] = ", i, "\n" -} - -print "halt\n" - -halt diff --git a/benchmarks/bc/arrays_and_constants.bc b/benchmarks/bc/arrays_and_constants.bc deleted file mode 100644 index 9a2172ece5be..000000000000 --- a/benchmarks/bc/arrays_and_constants.bc +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/bc -# -# 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. -# - -max = 1000000 - -for (i = 0; i < max; ++i) { -	print "b", i, "[100] = ", i, "\n" -} - -print "halt\n" - -halt diff --git a/benchmarks/bc/bitfuncs.bc b/benchmarks/bc/bitfuncs.bc deleted file mode 100644 index 69d357c2ce8a..000000000000 --- a/benchmarks/bc/bitfuncs.bc +++ /dev/null @@ -1,18 +0,0 @@ -#! /usr/bin/bc -lq - -scale = 0 -max = 10000 - -print "scale = 0\n" - -for (i = 0; i < max; ++i) { - -	a = rand() -	b = rand() - -	print "band(", a, ", ", b, ")\n" -	print "bor(", a, ", ", b, ")\n" -	print "bxor(", a, ", ", b, ")\n" -	print "bshl(", a, ", ", b % 32, ")\n" -	print "bshr(", a, ", ", b % 32, ")\n" -} diff --git a/benchmarks/bc/constants.bc b/benchmarks/bc/constants.bc deleted file mode 100644 index 1f7b92d47566..000000000000 --- a/benchmarks/bc/constants.bc +++ /dev/null @@ -1,41 +0,0 @@ -#! /usr/bin/bc -# -# 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. -# - -max = 1000 -max2 = 1000 - -for (i = 0; i < max; ++i) { - -	print "c = ", i, "\n" -	print "e = 0.", i, "\n" - -	for (j = 0; j < max2; ++j) { -		print "d = ", i, ".", j, "\n" -	} -} diff --git a/benchmarks/bc/divide.bc b/benchmarks/bc/divide.bc deleted file mode 100644 index 227794badbcb..000000000000 --- a/benchmarks/bc/divide.bc +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/bc -lq - -print "scale = 20\n" -print "x = 1234567890 * 10^(-scale)\n" -print "len = 1 + 2 * scale\n" -print "scale += 10\n" - -scale = 20 -x = 1234567890 * 10^(-scale) -len = 1 + 2 * scale - -scale += 10 - -for (i = 0; i <= len; ++i) { -	print "a[", i, "] = x * (10^", i, ")\n" -} - -for (i = 1; i <= 10000; ++i) { -	for (j = 0; j < len; ++j) { -		print "v = a[0] / a[", j, "]\n" -		print "v = a[", i, "] / a[", j, "]\n" -		print "v = (a[0] * ", i, ") / a[", j, "]\n" -		print "v = a[0] / (a[", j, "] * ", i, ")\n" -		print "v = (a[0] * ", i, ") / (a[", j, "] * ", i, ")\n" -	} -} diff --git a/benchmarks/bc/functions.bc b/benchmarks/bc/functions.bc deleted file mode 100644 index 7848c8df0c9f..000000000000 --- a/benchmarks/bc/functions.bc +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/bc -# -# 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. -# - -max = 1000000 - -for (i = 0; i < max; ++i) { -	print "define etsna", i, "(n) {\n\tn\n}\n" -} - -print "halt\n" - -halt diff --git a/benchmarks/bc/irand_long.bc b/benchmarks/bc/irand_long.bc deleted file mode 100644 index 2d2404942f83..000000000000 --- a/benchmarks/bc/irand_long.bc +++ /dev/null @@ -1,12 +0,0 @@ -#! /usr/bin/bc -lq - -start = 2^256 -end = start + 10000000 - -for (i = start; i < end; ++i) { -	print "irand(", i, ")\n" -} - -print "halt\n" - -halt diff --git a/benchmarks/bc/irand_short.bc b/benchmarks/bc/irand_short.bc deleted file mode 100644 index a53d407879f3..000000000000 --- a/benchmarks/bc/irand_short.bc +++ /dev/null @@ -1,9 +0,0 @@ -#! /usr/bin/bc -lq - -for (i = 2; i < 10000000; ++i) { -	print "irand(", i, ")\n" -} - -print "halt\n" - -halt diff --git a/benchmarks/bc/lib.bc b/benchmarks/bc/lib.bc deleted file mode 100644 index fb7cd1b93354..000000000000 --- a/benchmarks/bc/lib.bc +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/bc -lq - -print "for (i = 100; i < 1000; ++i) {\n" -print "    v = pi(i)\n" -print "    v = e(v)\n" -print "    v = l(v)\n" -print "}\n" - -print "halt\n" - -halt diff --git a/benchmarks/bc/multiply.bc b/benchmarks/bc/multiply.bc deleted file mode 100644 index d4ed08e055c8..000000000000 --- a/benchmarks/bc/multiply.bc +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/bc -lq - -print "scale = 20\n" -print "x = 1234567890 / scale\n" -print "len = length(x) + 1 + scale\n" - -scale = 20 -x = 1234567890 / scale -len = length(x) + 1 + scale - -for (i = 0; i <= len; ++i) { -	print "a[", i, "] = x * (10^", i, ")\n" -} - -for (i = 1; i <= 10000; ++i) { -	for (j = 0; j < len; ++j) { -		print "v = a[0] * a[", j, "]\n" -		print "v = a[", i, "] * a[", j, "]\n" -		print "v = (a[0] * ", i, ") * a[", j, "]\n" -		print "v = a[0] * (a[", j, "] * ", i, ")\n" -		print "v = (a[0] * ", i, ") * (a[", j, "] * ", i, ")\n" -	} -} diff --git a/benchmarks/bc/postfix_incdec.bc b/benchmarks/bc/postfix_incdec.bc deleted file mode 100644 index 2437f4c4c820..000000000000 --- a/benchmarks/bc/postfix_incdec.bc +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/bc -lq - -max = 1000000 - -for (i = 0; i < max; ++i) { -	print "i++\ni--\n" -} - -print "halt\n" - -halt diff --git a/benchmarks/bc/power.bc b/benchmarks/bc/power.bc deleted file mode 100644 index b067aa732d10..000000000000 --- a/benchmarks/bc/power.bc +++ /dev/null @@ -1,2 +0,0 @@ -#! /usr/bin/bc -lq - diff --git a/benchmarks/bc/strings.bc b/benchmarks/bc/strings.bc deleted file mode 100644 index a97017ea78b4..000000000000 --- a/benchmarks/bc/strings.bc +++ /dev/null @@ -1,40 +0,0 @@ -#! /usr/bin/bc -# -# 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. -# - -max = 1000000 - -print "\qasotehnuasnotehustnaoheusntaoheustnaoheusntaoehunsatoheuastoehuaosnetuhaosetnuhaosentuahoesntuahoeuhstoeunhatoehusanotehusatnoheus\q\n" - -for (i = 0; i < max; ++i) { -	print "\qabc", i, " = ", i, "\\n\q\n" -} - -print "halt\n" - -halt diff --git a/benchmarks/bc/subtract.bc b/benchmarks/bc/subtract.bc deleted file mode 100644 index b88bd60e935c..000000000000 --- a/benchmarks/bc/subtract.bc +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/bc -lq - -print "scale = 20\n" -print "x = 1234567890 / scale\n" -print "len = length(x) + 1 + scale\n" -print "len *= 2\n" - -scale = 20 -x = 1234567890 / scale -len = length(x) + 1 + scale -len *= 2 - -for (i = 0; i <= len; ++i) { -	print "a[", i, "] = x * (10^", i, ")\n" -} - -for (i = 1; i <= 10000; ++i) { -	for (j = 0; j < len; ++j) { -		print "v = a[", i, "] - a[", j, "]\n" -	} -} - diff --git a/benchmarks/dc/modexp.dc b/benchmarks/dc/modexp.dc deleted file mode 100644 index 48f304cb92da..000000000000 --- a/benchmarks/dc/modexp.dc +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/dc -# -# 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. - -[ ]ss -[|]so -100sm 0si -[ -	li1+si 0sj -	[ -		lj1+sj 0sk -		[ -			lk1+sk lin lsn ljn lsn lkn lsn lon 10P lk lm !<z -		]dszx -		lj lm !<y -	]dsyx -	li lm !<x -]dsxx diff --git a/include/version.h b/include/version.h index d460ebfa2d10..63578e0fe8f0 100644 --- a/include/version.h +++ b/include/version.h @@ -37,6 +37,6 @@  #define BC_VERSION_H  /// The current version. -#define VERSION 5.3.1 +#define VERSION 5.3.2  #endif // BC_VERSION_H diff --git a/manuals/bc.1.md.in b/manuals/bc.1.md.in deleted file mode 100644 index e5ca807dbe39..000000000000 --- a/manuals/bc.1.md.in +++ /dev/null @@ -1,2476 +0,0 @@ -<!--- - -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**. - -{{ A H N HN }} -This bc(1) is a drop-in replacement for *any* bc(1), including (and -especially) the GNU bc(1). It also has many extensions and extra features beyond -other implementations. -{{ end }} -{{ E EH EN EHN }} -This bc(1) is a drop-in replacement for *any* bc(1), including (and especially) -the GNU bc(1). -{{ end }} - -**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** - -{{ A H N HN }} -:   Turns the globals **ibase**, **obase**, **scale**, and **seed** into stacks. - -    This has the effect that a copy of the current value of all four are pushed -{{ end }} -{{ E EH EN EHN }} -:   Turns the globals **ibase**, **obase**, and **scale** into stacks. - -    This has the effect that a copy of the current value of all three are pushed -{{ end }} -    onto a stack for every function call, as well as popped when every function -    returns. This means that functions can assign to any and all of those -    globals without worrying that the change will affect other functions. -    Thus, a hypothetical function named **output(x,b)** that simply printed -    **x** in base **b** could be written like this: - -        define void output(x, b) { -            obase=b -            x -        } - -    instead of like this: - -        define void output(x, b) { -            auto c -            c=obase -            obase=b -            x -            obase=c -        } - -    This makes writing functions much easier. - -{{ A H N HN }} -    (**Note**: the function **output(x,b)** exists in the extended math library. -     See the **LIBRARY** section.) - -    However, since using this flag means that functions cannot set **ibase**, -    **obase**, **scale**, or **seed** globally, functions that are made to do so -    cannot work anymore. There are two possible use cases for that, and each has -    a solution. -{{ end }} -{{ E EH EN EHN }} -    However, since using this flag means that functions cannot set **ibase**, -    **obase**, or **scale** globally, functions that are made to do so cannot -    work anymore. There are two possible use cases for that, and each has a -    solution. -{{ end }} - -    First, if a function is called on startup to turn bc(1) into a number -    converter, it is possible to replace that capability with various shell -    aliases. Examples: - -        alias d2o="bc -e ibase=A -e obase=8" -        alias h2b="bc -e ibase=G -e obase=2" - -{{ A H N HN }} -    Second, if the purpose of a function is to set **ibase**, **obase**, -    **scale**, or **seed** globally for any other purpose, it could be split -    into one to four functions (based on how many globals it sets) and each of -    those functions could return the desired value for a global. - -    For functions that set **seed**, the value assigned to **seed** is not -    propagated to parent functions. This means that the sequence of -    pseudo-random numbers that they see will not be the same sequence of -    pseudo-random numbers that any parent sees. This is only the case once -    **seed** has been set. - -    If a function desires to not affect the sequence of pseudo-random numbers -    of its parents, but wants to use the same **seed**, it can use the following -    line: - -        seed = seed -{{ end }} -{{ E EH EN EHN }} -    Second, if the purpose of a function is to set **ibase**, **obase**, or -    **scale** globally for any other purpose, it could be split into one to -    three functions (based on how many globals it sets) and each of those -    functions could return the desired value for a global. -{{ end }} - -    If the behavior of this option is desired for every run of bc(1), then users -    could make sure to define **BC_ENV_ARGS** and include this option (see the -    **ENVIRONMENT VARIABLES** section for more details). - -    If **-s**, **-w**, or any equivalents are used, this option is ignored. - -    This is a **non-portable extension**. - -**-h**, **-\-help** - -:   Prints a usage message and quits. - -**-i**, **-\-interactive** - -:   Forces interactive mode. (See the **INTERACTIVE MODE** section.) - -    This is a **non-portable extension**. - -**-L**, **-\-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 -{{ A H N HN }} -    math library and the extended math library before running any code, -    including any expressions or files specified on the command line. - -    To learn what is in the libraries, see the **LIBRARY** section. -{{ end }} -{{ E EH EN EHN }} -    math library before running any code, including any expressions or files -    specified on the command line. - -    To learn what is in the library, see the **LIBRARY** section. -{{ end }} - -**-P**, **-\-no-prompt** - -:   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** -{{ A H N HN }} -    * **irand** -{{ end }} -    * **last** -    * **limits** -    * **maxibase** -    * **maxobase** -{{ A H N HN }} -    * **maxrand** -{{ end }} -    * **maxscale** -    * **modexp** -    * **print** -{{ A H N HN }} -    * **rand** -{{ end }} -    * **read** -{{ A H N HN }} -    * **seed** -{{ end }} -	* **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 -{{ A H N HN }} -min allowable value for **obase** is **0**. If **obase** is **0**, values are -output in scientific notation, and if **obase** is **1**, values are output in -engineering notation. Otherwise, values are output in the specified base. - -Outputting in scientific and engineering notations are **non-portable -extensions**. -{{ end }} -{{ E EH EN EHN }} -min allowable value for **obase** is **2**. Values are output in the specified -base. -{{ end }} - -The *scale* of an expression is the number of digits in the result of the -expression right of the decimal point, and **scale** is a global variable that -sets the precision of any operations, with exceptions. **scale** is initially -**0**. **scale** cannot be negative. The max allowable value for **scale** is -**BC_SCALE_MAX** and can be queried in bc(1) programs with the **maxscale()** -built-in function. - -bc(1) has both *global* variables and *local* variables. All *local* -variables are local to the function; they are parameters or are introduced in -the **auto** list of a function (see the **FUNCTIONS** section). If a variable -is accessed which is not a parameter or in the **auto** list, it is assumed to -be *global*. If a parent function has a *local* variable version of a variable -that a child function considers *global*, the value of that *global* variable in -the child function is the value of the variable in the parent function, not the -value of the actual *global* variable. - -All of the above applies to arrays as well. - -The value of a statement that is an expression (i.e., any of the named -expressions or operands) is printed unless the lowest precedence operator is an -assignment operator *and* the expression is notsurrounded by parentheses. - -The value that is printed is also assigned to the special variable **last**. A -single dot (**.**) may also be used as a synonym for **last**. These are -**non-portable extensions**. - -Either semicolons or newlines may separate statements. - -## Comments - -There are two kinds of comments: - -1.	Block comments are enclosed in **/\*** and **\*/**. -2.	Line comments go from **#** until, and not including, the next newline. This -	is a **non-portable extension**. - -## Named Expressions - -The following are named expressions in bc(1): - -1.	Variables: **I** -2.	Array Elements: **I[E]** -3.	**ibase** -4.	**obase** -5.	**scale** -{{ A H N HN }} -6.	**seed** -7.	**last** or a single dot (**.**) - -Numbers 6 and 7 are **non-portable extensions**. - -The meaning of **seed** is dependent on the current pseudo-random number -generator but is guaranteed to not change except for new major versions. - -The *scale* and sign of the value may be significant. - -If a previously used **seed** value is assigned to **seed** and used again, the -pseudo-random number generator is guaranteed to produce the same sequence of -pseudo-random numbers as it did when the **seed** value was previously used. - -The exact value assigned to **seed** is not guaranteed to be returned if -**seed** is queried again immediately. However, if **seed** *does* return a -different value, both values, when assigned to **seed**, are guaranteed to -produce the same sequence of pseudo-random numbers. This means that certain -values assigned to **seed** will *not* produce unique sequences of pseudo-random -numbers. The value of **seed** will change after any use of the **rand()** and -**irand(E)** operands (see the *Operands* subsection below), except if the -parameter passed to **irand(E)** is **0**, **1**, or negative. - -There is no limit to the length (number of significant decimal digits) or -*scale* of the value that can be assigned to **seed**. -{{ end }} -{{ E EH EN EHN }} -6.	**last** or a single dot (**.**) - -Number 6 is a **non-portable extension**. -{{ end }} - -Variables and arrays do not interfere; users can have arrays named the same as -variables. This also applies to functions (see the **FUNCTIONS** section), so a -user can have a variable, array, and function that all have the same name, and -they will not shadow each other, whether inside of functions or not. - -Named expressions are required as the operand of **increment**/**decrement** -operators  and as the left side of **assignment** operators (see the *Operators* -subsection). - -## Operands - -The following are valid operands in bc(1): - -1.	Numbers (see the *Numbers* subsection below). -2.	Array indices (**I[E]**). -3.	**(E)**: The value of **E** (used to change precedence). -4.	**sqrt(E)**: The square root of **E**. **E** must be non-negative. -5.	**length(E)**: The number of significant decimal digits in **E**. 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**. -{{ A H N HN }} -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. -{{ end }} - -## Numbers - -Numbers are strings made up of digits, uppercase letters, and at most **1** -period for a radix. Numbers can have up to **BC_NUM_MAX** digits. Uppercase -letters are equal to **9** + their position in the alphabet (i.e., **A** equals -**10**, or **9+1**). If a digit or letter makes no sense with the current value -of **ibase**, they are set to the value of the highest valid digit in **ibase**. - -Single-character numbers (i.e., **A** alone) take the value that they would have -if they were valid digits, regardless of the value of **ibase**. This means that -**A** alone always equals decimal **10** and **Z** alone always equals decimal -**35**. - -{{ A H N HN }} -In addition, bc(1) accepts numbers in scientific notation. These have the form -**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be -an integer. An example is **1.89237e9**, which is equal to **1892370000**. -Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**. - -Using scientific notation is an error or warning if the **-s** or **-w**, -respectively, command-line options (or equivalents) are given. - -**WARNING**: Both the number and the exponent in scientific notation are -interpreted according to the current **ibase**, but the number is still -multiplied by **10\^exponent** regardless of the current **ibase**. For example, -if **ibase** is **16** and bc(1) is given the number string **FFeA**, the -resulting decimal number will be **2550000000000**, and if bc(1) is given the -number string **10e-4**, the resulting decimal number will be **0.0016**. - -Accepting input as scientific notation is a **non-portable extension**. -{{ end }} - -## Operators - -The following arithmetic and logical operators can be used. They are listed in -order of decreasing precedence. Operators in the same group have the same -precedence. - -**++** **-\-** - -:   Type: Prefix and Postfix - -    Associativity: None - -    Description: **increment**, **decrement** - -**-** **!** - -:   Type: Prefix - -    Associativity: None - -    Description: **negation**, **boolean not** - -{{ A H N HN }} -**\$** - -:   Type: Postfix - -    Associativity: None - -    Description: **truncation** - -**\@** - -:   Type: Binary - -    Associativity: Right - -    Description: **set precision** -{{ end }} - -**\^** - -:   Type: Binary - -    Associativity: Right - -    Description: **power** - -**\*** **/** **%** - -:   Type: Binary - -    Associativity: Left - -    Description: **multiply**, **divide**, **modulus** - -**+** **-** - -:   Type: Binary - -    Associativity: Left - -    Description: **add**, **subtract** - -{{ A H N HN }} -**\<\<** **\>\>** - -:   Type: Binary - -    Associativity: Left - -    Description: **shift left**, **shift right** - -**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=** -{{ end }} -{{ E EH EN EHN }} -**=** **+=** **-=** **\*=** **/=** **%=** **\^=** -{{ end }} - -:   Type: Binary - -    Associativity: Right - -    Description: **assignment** - -**==** **\<=** **\>=** **!=** **\<** **\>** - -:   Type: Binary - -    Associativity: Left - -    Description: **relational** - -**&&** - -:   Type: Binary - -    Associativity: Left - -    Description: **boolean and** - -**||** - -:   Type: Binary - -    Associativity: Left - -    Description: **boolean or** - -The operators will be described in more detail below. - -**++** **-\-** - -:   The prefix and postfix **increment** and **decrement** operators behave -    exactly like they would in C. They require a named expression (see the -    *Named Expressions* subsection) as an operand. - -    The prefix versions of these operators are more efficient; use them where -    possible. - -**-** - -:   The **negation** operator returns **0** if a user attempts to negate any -    expression with the value **0**. Otherwise, a copy of the expression with -    its sign flipped is returned. - -**!** - -:   The **boolean not** operator returns **1** if the expression is **0**, or -    **0** otherwise. - -    This is a **non-portable extension**. - -{{ A H N HN }} -**\$** - -:   The **truncation** operator returns a copy of the given expression with all -    of its *scale* removed. - -    This is a **non-portable extension**. - -**\@** - -:   The **set precision** operator takes two expressions and returns a copy of -    the first with its *scale* equal to the value of the second expression. That -    could either mean that the number is returned without change (if the -    *scale* of the first expression matches the value of the second -    expression), extended (if it is less), or truncated (if it is more). - -    The second expression must be an integer (no *scale*) and non-negative. - -    This is a **non-portable extension**. -{{ end }} - -**\^** - -:   The **power** operator (not the **exclusive or** operator, as it would be in -    C) takes two expressions and raises the first to the power of the value of -    the second. The *scale* of the result is equal to **scale**. - -    The second expression must be an integer (no *scale*), and if it is -    negative, the first value must be non-zero. - -**\*** - -:   The **multiply** operator takes two expressions, multiplies them, and -    returns the product. If **a** is the *scale* of the first expression and -    **b** is the *scale* of the second expression, the *scale* of the result is -    equal to **min(a+b,max(scale,a,b))** where **min()** and **max()** return -    the obvious values. - -**/** - -:   The **divide** operator takes two expressions, divides them, and returns the -    quotient. The *scale* of the result shall be the value of **scale**. - -    The second expression must be non-zero. - -**%** - -:   The **modulus** operator takes two expressions, **a** and **b**, and -    evaluates them by 1) Computing **a/b** to current **scale** and 2) Using the -    result of step 1 to calculate **a-(a/b)\*b** to *scale* -    **max(scale+scale(b),scale(a))**. - -    The second expression must be non-zero. - -**+** - -:   The **add** operator takes two expressions, **a** and **b**, and returns the -    sum, with a *scale* equal to the max of the *scale*s of **a** and **b**. - -**-** - -:   The **subtract** operator takes two expressions, **a** and **b**, and -    returns the difference, with a *scale* equal to the max of the *scale*s of -    **a** and **b**. - -{{ A H N HN }} -**\<\<** - -:   The **left shift** operator takes two expressions, **a** and **b**, and -    returns a copy of the value of **a** with its decimal point moved **b** -    places to the right. - -    The second expression must be an integer (no *scale*) and non-negative. - -    This is a **non-portable extension**. - -**\>\>** - -:   The **right shift** operator takes two expressions, **a** and **b**, and -    returns a copy of the value of **a** with its decimal point moved **b** -    places to the left. - -    The second expression must be an integer (no *scale*) and non-negative. - -    This is a **non-portable extension**. -{{ end }} - -{{ A H N HN }} -**=** **\<\<=** **\>\>=** **+=** **-=** **\*=** **/=** **%=** **\^=** **\@=** -{{ end }} -{{ E EH EN EHN }} -**=** **+=** **-=** **\*=** **/=** **%=** **\^=** -{{ end }} - -:   The **assignment** operators take two expressions, **a** and **b** where -    **a** is a named expression (see the *Named Expressions* subsection). - -    For **=**, **b** is copied and the result is assigned to **a**. For all -    others, **a** and **b** are applied as operands to the corresponding -    arithmetic operator and the result is assigned to **a**. - -{{ A H N HN }} -    The **assignment** operators that correspond to operators that are -    extensions are themselves **non-portable extensions**. -{{ end }} - -**==** **\<=** **\>=** **!=** **\<** **\>** - -:   The **relational** operators compare two expressions, **a** and **b**, and -    if the relation holds, according to C language semantics, the result is -    **1**. Otherwise, it is **0**. - -    Note that unlike in C, these operators have a lower precedence than the -    **assignment** operators, which means that **a=b\>c** is interpreted as -    **(a=b)\>c**. - -    Also, unlike the [standard][1] requires, these operators can appear anywhere -    any other expressions can be used. This allowance is a -    **non-portable extension**. - -**&&** - -:   The **boolean and** operator takes two expressions and returns **1** if both -    expressions are non-zero, **0** otherwise. - -    This is *not* a short-circuit operator. - -    This is a **non-portable extension**. - -**||** - -:   The **boolean or** operator takes two expressions and returns **1** if one -    of the expressions is non-zero, **0** otherwise. - -    This is *not* a short-circuit operator. - -    This is a **non-portable extension**. - -## Statements - -The following items are statements: - -1.	**E** -2.	**{** **S** **;** ... **;** **S** **}** -3.	**if** **(** **E** **)** **S** -4.	**if** **(** **E** **)** **S** **else** **S** -5.	**while** **(** **E** **)** **S** -6.	**for** **(** **E** **;** **E** **;** **E** **)** **S** -7.	An empty statement -8.	**break** -9.	**continue** -10.	**quit** -11.	**halt** -12.	**limits** -13.	A string of characters, enclosed in double quotes -14.	**print** **E** **,** ... **,** **E** -15.	**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. - -{{ A H N HN }} -Both scientific notation and engineering notation are available for printing the -results of expressions. Scientific notation is activated by assigning **0** to -**obase**, and engineering notation is activated by assigning **1** to -**obase**. To deactivate them, just assign a different value to **obase**. - -Scientific notation and engineering notation are disabled if bc(1) is run with -either the **-s** or **-w** command-line options (or equivalents). - -Printing numbers in scientific notation and/or engineering notation is a -**non-portable extension**. -{{ end }} - -## 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 - -{{ A H N HN }} -All of the functions below, including the functions in the extended math -library (see the *Extended Library* subsection below), are available when the -**-l** or **-\-mathlib** command-line flags are given, except that the extended -math library is not available when the **-s** option, the **-w** option, or -equivalents are given. -{{ end }} -{{ E EH EN EHN }} -All of the functions below  are available when the **-l** or **-\-mathlib** -command-line flags are given. -{{ end }} - -## Standard Library - -The [standard][1] defines the following functions for the math library: - -**s(x)** - -:   Returns the sine of **x**, which is assumed to be in radians. - -    This is a transcendental function (see the *Transcendental Functions* -    subsection below). - -**c(x)** - -:   Returns the cosine of **x**, which is assumed to be in radians. - -    This is a transcendental function (see the *Transcendental Functions* -    subsection below). - -**a(x)** - -:   Returns the arctangent of **x**, in radians. - -    This is a transcendental function (see the *Transcendental Functions* -    subsection below). - -**l(x)** - -:   Returns the natural logarithm of **x**. - -    This is a transcendental function (see the *Transcendental Functions* -    subsection below). - -**e(x)** - -:   Returns the mathematical constant **e** raised to the power of **x**. - -    This is a transcendental function (see the *Transcendental Functions* -    subsection below). - -**j(x, n)** - -:   Returns the bessel integer order **n** (truncated) of **x**. - -    This is a transcendental function (see the *Transcendental Functions* -    subsection below). - -{{ A H N HN }} -## 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). -{{ end }} - -## Transcendental Functions - -All transcendental functions can return slightly inaccurate results (up to 1 -[ULP][4]). This is unavoidable, and [this article][5] explains why it is -impossible and unnecessary to calculate exact results for the transcendental -functions. - -Because of the possible inaccuracy, I recommend that users call those functions -with the precision (**scale**) set to at least 1 higher than is necessary. If -exact results are *absolutely* required, users can double the precision -(**scale**) and then truncate. - -The transcendental functions in the standard math library are: - -* **s(x)** -* **c(x)** -* **a(x)** -* **l(x)** -* **e(x)** -* **j(x, n)** - -{{ A H N HN }} -The transcendental functions in the extended math library are: - -* **l2(x)** -* **l10(x)** -* **log(x, b)** -* **pi(p)** -* **t(x)** -* **a2(y, x)** -* **sin(x)** -* **cos(x)** -* **tan(x)** -* **atan(x)** -* **atan2(y, x)** -* **r2d(x)** -* **d2r(x)** -{{ end }} - -# RESET - -When bc(1) encounters an error or a signal that it has a non-default handler -for, it resets. This means that several things happen. - -First, any functions that are executing are stopped and popped off the stack. -The behavior is not unlike that of exceptions in programming languages. Then -the execution point is set so that any code waiting to execute (after all -functions returned) is skipped. - -Thus, when bc(1) resets, it skips any remaining code waiting to be executed. -Then, if it is interactive mode, and the error was not a fatal error (see the -**EXIT STATUS** section), it asks for more input; otherwise, it exits with the -appropriate return code. - -Note that this reset behavior is different from the GNU bc(1), which attempts to -start executing the statement right after the one that caused an error. - -# PERFORMANCE - -Most bc(1) implementations use **char** types to calculate the value of **1** -decimal digit at a time, but that can be slow. This bc(1) does something -different. - -It uses large integers to calculate more than **1** decimal digit at a time. If -built in a environment where **BC_LONG_BIT** (see the **LIMITS** section) is -**64**, then each integer has **9** decimal digits. If built in an environment -where **BC_LONG_BIT** is **32** then each integer has **4** decimal digits. This -value (the number of decimal digits per large integer) is called -**BC_BASE_DIGS**. - -The actual values of **BC_LONG_BIT** and **BC_BASE_DIGS** can be queried with -the **limits** statement. - -In addition, this bc(1) uses an even larger integer for overflow checking. This -integer type depends on the value of **BC_LONG_BIT**, but is always at least -twice as large as the integer type used to store digits. - -# LIMITS - -The following are the limits on bc(1): - -**BC_LONG_BIT** - -:   The number of bits in the **long** type in the environment where bc(1) was -    built. This determines how many decimal digits can be stored in a single -    large integer (see the **PERFORMANCE** section). - -**BC_BASE_DIGS** - -:   The number of decimal digits per large integer (see the **PERFORMANCE** -    section). Depends on **BC_LONG_BIT**. - -**BC_BASE_POW** - -:   The max decimal number that each large integer can store (see -    **BC_BASE_DIGS**) plus **1**. Depends on **BC_BASE_DIGS**. - -**BC_OVERFLOW_MAX** - -:   The max number that the overflow type (see the **PERFORMANCE** section) can -    hold. Depends on **BC_LONG_BIT**. - -**BC_BASE_MAX** - -:   The maximum output base. Set at **BC_BASE_POW**. - -**BC_DIM_MAX** - -:   The maximum size of arrays. Set at **SIZE_MAX-1**. - -**BC_SCALE_MAX** - -:   The maximum **scale**. Set at **BC_OVERFLOW_MAX-1**. - -**BC_STRING_MAX** - -:   The maximum length of strings. Set at **BC_OVERFLOW_MAX-1**. - -**BC_NAME_MAX** - -:   The maximum length of identifiers. Set at **BC_OVERFLOW_MAX-1**. - -**BC_NUM_MAX** - -:   The maximum length of a number (in decimal digits), which includes digits -    after the decimal point. Set at **BC_OVERFLOW_MAX-1**. - -{{ A H N HN }} -**BC_RAND_MAX** - -:   The maximum integer (inclusive) returned by the **rand()** operand. Set at -    **2\^BC_LONG_BIT-1**. -{{ end }} - -Exponent - -:   The maximum allowable exponent (positive or negative). Set at -    **BC_OVERFLOW_MAX**. - -Number of vars - -:   The maximum number of vars/arrays. Set at **SIZE_MAX-1**. - -The actual values can be queried with the **limits** statement. - -These limits are meant to be effectively non-existent; the limits are so large -(at least on 64-bit machines) that there should not be any point at which they -become a problem. In fact, memory should be exhausted before these limits should -be hit. - -# ENVIRONMENT VARIABLES - -bc(1) recognizes the following environment variables: - -**POSIXLY_CORRECT** - -:   If this variable exists (no matter the contents), bc(1) behaves as if -    the **-s** option was given. - -**BC_ENV_ARGS** - -:   This is another way to give command-line arguments to bc(1). They should be -    in the same format as all other command-line arguments. These are always -    processed first, so any files given in **BC_ENV_ARGS** will be processed -    before arguments and files given on the command-line. This gives the user -    the ability to set up "standard" options and files to be used at every -    invocation. The most useful thing for such files to contain would be useful -    functions that the user might want every time bc(1) runs. - -    The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, -    but it does not understand escape sequences. For example, the string -    **"/home/gavin/some bc file.bc"** will be correctly parsed, but the string -    **"/home/gavin/some \"bc\" file.bc"** will include the backslashes. - -    The quote parsing will handle either kind of quotes, **'** or **"**. Thus, -    if you have a file with any number of single quotes in the name, you can use -    double quotes as the outside quotes, as in **"some 'bc' file.bc"**, and vice -    versa if you have a file with double quotes. However, handling a file with -    both kinds of quotes in **BC_ENV_ARGS** is not supported due to the -    complexity of the parsing, though such files are still supported on the -    command-line where the parsing is done by the shell. - -**BC_LINE_LENGTH** - -:   If this environment variable exists and contains an integer that is greater -    than **1** and is less than **UINT16_MAX** (**2\^16-1**), bc(1) will output -    lines to that length, including the backslash (**\\**). The default line -    length is **70**. - -    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. - -**BC_EXPR_EXIT** - -:   If any expressions or expression files are given on the command-line with -    **-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment -    variable exists and contains an integer, a non-zero value makes bc(1) exit -    after executing the expressions and expression files, and a non-zero value -    makes bc(1) not exit. - -    This environment variable overrides 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 -{{ A H N HN }} -    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. -{{ end }} -{{ E EH EN EHN }} -    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. -{{ end }} - -**2** - -:   A parse error occurred. - -    Parse errors include unexpected **EOF**, using an invalid character, failing -    to find the end of a string or comment, using a token where it is invalid, -    giving an invalid expression, giving an invalid print statement, giving an -    invalid function definition, attempting to assign to an expression that is -    not a named expression (see the *Named Expressions* subsection of the -    **SYNTAX** section), giving an invalid **auto** list, having a duplicate -    **auto**/function parameter, failing to find the end of a code block, -    attempting to return a value from a **void** function, attempting to use a -    variable as a reference, and using any extensions when the option **-s** or -    any equivalents were given. - -**3** - -:   A runtime error occurred. - -    Runtime errors include assigning an invalid number to 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. - -{{ A E N EN }} -## 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. -{{ end }} - -## 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 -{{ A E N EN }} -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. -{{ end }} -{{ H EH HN EHN }} -default handler for all other signals. -{{ end }} - -{{ A E N EN }} -# 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. -{{ end }} - -{{ A E H EH }} -# LOCALES - -This bc(1) ships with support for adding error messages for different locales -and thus, supports **LC_MESSAGES**. -{{ end }} - -# SEE ALSO - -dc(1) - -# STANDARDS - -bc(1) is compliant with the [IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] -specification. The flags **-efghiqsvVw**, all long options, and the extensions -noted above are extensions to that specification. - -Note that the specification explicitly says that bc(1) only accepts numbers that -use a period (**.**) as a radix point, regardless of the value of -**LC_NUMERIC**. - -{{ A E H EH }} -This bc(1) supports error messages for different locales, and thus, it supports -**LC_MESSAGES**. -{{ end }} - -# BUGS - -None are known. Report bugs at https://git.yzena.com/gavin/bc. - -# AUTHORS - -Gavin D. Howard <gavin@yzena.com> and contributors. - -[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html -[2]: https://www.gnu.org/software/bc/ -[3]: https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero -[4]: https://en.wikipedia.org/wiki/Unit_in_the_last_place -[5]: https://people.eecs.berkeley.edu/~wkahan/LOG10HAF.TXT -[6]: https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero diff --git a/manuals/benchmarks.md b/manuals/benchmarks.md deleted file mode 100644 index af0593f4e876..000000000000 --- a/manuals/benchmarks.md +++ /dev/null @@ -1,673 +0,0 @@ -# Benchmarks - -The results of these benchmarks suggest that building this `bc` with -optimization at `-O3` with link-time optimization (`-flto`) will result in the -best performance. However, using `-march=native` can result in **WORSE** -performance. - -*Note*: all benchmarks were run four times, and the fastest run is the one -shown. Also, `[bc]` means whichever `bc` was being run, and the assumed working -directory is the root directory of this repository. Also, this `bc` was at -version `3.0.0` while GNU `bc` was at version `1.07.1`, and all tests were -conducted on an `x86_64` machine running Gentoo Linux with `clang` `9.0.1` as -the compiler. - -## Typical Optimization Level - -These benchmarks were run with both `bc`'s compiled with the typical `-O2` -optimizations and no link-time optimization. - -### Addition - -The command used was: - -``` -tests/script.sh bc add.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 2.54 -user 1.21 -sys 1.32 -``` - -For this `bc`: - -``` -real 0.88 -user 0.85 -sys 0.02 -``` - -### Subtraction - -The command used was: - -``` -tests/script.sh bc subtract.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 2.51 -user 1.05 -sys 1.45 -``` - -For this `bc`: - -``` -real 0.91 -user 0.85 -sys 0.05 -``` - -### Multiplication - -The command used was: - -``` -tests/script.sh bc multiply.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 7.15 -user 4.69 -sys 2.46 -``` - -For this `bc`: - -``` -real 2.20 -user 2.10 -sys 0.09 -``` - -### Division - -The command used was: - -``` -tests/script.sh bc divide.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 3.36 -user 1.87 -sys 1.48 -``` - -For this `bc`: - -``` -real 1.61 -user 1.57 -sys 0.03 -``` - -### Power - -The command used was: - -``` -printf '1234567890^100000; halt\n' | time -p [bc] -q > /dev/null -``` - -For GNU `bc`: - -``` -real 11.30 -user 11.30 -sys 0.00 -``` - -For this `bc`: - -``` -real 0.73 -user 0.72 -sys 0.00 -``` - -### Scripts - -[This file][1] was downloaded, saved at `../timeconst.bc` and the following -patch was applied: - -``` ---- ../timeconst.bc	2018-09-28 11:32:22.808669000 -0600 -+++ ../timeconst.bc	2019-06-07 07:26:36.359913078 -0600 -@@ -110,8 +110,10 @@ -  - 		print "#endif /* KERNEL_TIMECONST_H */\n" - 	} --	halt - } -  --hz = read(); --timeconst(hz) -+for (i = 0; i <= 50000; ++i) { -+	timeconst(i) -+} -+ -+halt -``` - -The command used was: - -``` -time -p [bc] ../timeconst.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 16.71 -user 16.06 -sys 0.65 -``` - -For this `bc`: - -``` -real 13.16 -user 13.15 -sys 0.00 -``` - -Because this `bc` is faster when doing math, it might be a better comparison to -run a script that is not running any math. As such, I put the following into -`../test.bc`: - -``` -for (i = 0; i < 100000000; ++i) { -	y = i -} - -i -y - -halt -``` - -The command used was: - -``` -time -p [bc] ../test.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 16.60 -user 16.59 -sys 0.00 -``` - -For this `bc`: - -``` -real 22.76 -user 22.75 -sys 0.00 -``` - -I also put the following into `../test2.bc`: - -``` -i = 0 - -while (i < 100000000) { -	i += 1 -} - -i - -halt -``` - -The command used was: - -``` -time -p [bc] ../test2.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 17.32 -user 17.30 -sys 0.00 -``` - -For this `bc`: - -``` -real 16.98 -user 16.96 -sys 0.01 -``` - -It seems that the improvements to the interpreter helped a lot in certain cases. - -Also, I have no idea why GNU `bc` did worse when it is technically doing less -work. - -## Recommended Optimizations from `2.7.0` - -Note that, when running the benchmarks, the optimizations used are not the ones -I recommended for version `2.7.0`, which are `-O3 -flto -march=native`. - -This `bc` separates its code into modules that, when optimized at link time, -removes a lot of the inefficiency that comes from function overhead. This is -most keenly felt with one function: `bc_vec_item()`, which should turn into just -one instruction (on `x86_64`) when optimized at link time and inlined. There are -other functions that matter as well. - -I also recommended `-march=native` on the grounds that newer instructions would -increase performance on math-heavy code. We will see if that assumption was -correct. (Spoiler: **NO**.) - -When compiling both `bc`'s with the optimizations I recommended for this `bc` -for version `2.7.0`, the results are as follows. - -### Addition - -The command used was: - -``` -tests/script.sh bc add.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 2.44 -user 1.11 -sys 1.32 -``` - -For this `bc`: - -``` -real 0.59 -user 0.54 -sys 0.05 -``` - -### Subtraction - -The command used was: - -``` -tests/script.sh bc subtract.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 2.42 -user 1.02 -sys 1.40 -``` - -For this `bc`: - -``` -real 0.64 -user 0.57 -sys 0.06 -``` - -### Multiplication - -The command used was: - -``` -tests/script.sh bc multiply.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 7.01 -user 4.50 -sys 2.50 -``` - -For this `bc`: - -``` -real 1.59 -user 1.53 -sys 0.05 -``` - -### Division - -The command used was: - -``` -tests/script.sh bc divide.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 3.26 -user 1.82 -sys 1.44 -``` - -For this `bc`: - -``` -real 1.24 -user 1.20 -sys 0.03 -``` - -### Power - -The command used was: - -``` -printf '1234567890^100000; halt\n' | time -p [bc] -q > /dev/null -``` - -For GNU `bc`: - -``` -real 11.08 -user 11.07 -sys 0.00 -``` - -For this `bc`: - -``` -real 0.71 -user 0.70 -sys 0.00 -``` - -### Scripts - -The command for the `../timeconst.bc` script was: - -``` -time -p [bc] ../timeconst.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 15.62 -user 15.08 -sys 0.53 -``` - -For this `bc`: - -``` -real 10.09 -user 10.08 -sys 0.01 -``` - -The command for the next script, the `for` loop script, was: - -``` -time -p [bc] ../test.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 14.76 -user 14.75 -sys 0.00 -``` - -For this `bc`: - -``` -real 17.95 -user 17.94 -sys 0.00 -``` - -The command for the next script, the `while` loop script, was: - -``` -time -p [bc] ../test2.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 14.84 -user 14.83 -sys 0.00 -``` - -For this `bc`: - -``` -real 13.53 -user 13.52 -sys 0.00 -``` - -## Link-Time Optimization Only - -Just for kicks, let's see if `-march=native` is even useful. - -The optimizations I used for both `bc`'s were `-O3 -flto`. - -### Addition - -The command used was: - -``` -tests/script.sh bc add.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 2.41 -user 1.05 -sys 1.35 -``` - -For this `bc`: - -``` -real 0.58 -user 0.52 -sys 0.05 -``` - -### Subtraction - -The command used was: - -``` -tests/script.sh bc subtract.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 2.39 -user 1.10 -sys 1.28 -``` - -For this `bc`: - -``` -real 0.65 -user 0.57 -sys 0.07 -``` - -### Multiplication - -The command used was: - -``` -tests/script.sh bc multiply.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 6.82 -user 4.30 -sys 2.51 -``` - -For this `bc`: - -``` -real 1.57 -user 1.49 -sys 0.08 -``` - -### Division - -The command used was: - -``` -tests/script.sh bc divide.bc 1 0 1 1 [bc] -``` - -For GNU `bc`: - -``` -real 3.25 -user 1.81 -sys 1.43 -``` - -For this `bc`: - -``` -real 1.27 -user 1.23 -sys 0.04 -``` - -### Power - -The command used was: - -``` -printf '1234567890^100000; halt\n' | time -p [bc] -q > /dev/null -``` - -For GNU `bc`: - -``` -real 10.50 -user 10.49 -sys 0.00 -``` - -For this `bc`: - -``` -real 0.72 -user 0.71 -sys 0.00 -``` - -### Scripts - -The command for the `../timeconst.bc` script was: - -``` -time -p [bc] ../timeconst.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 15.50 -user 14.81 -sys 0.68 -``` - -For this `bc`: - -``` -real 10.17 -user 10.15 -sys 0.01 -``` - -The command for the next script, the `for` loop script, was: - -``` -time -p [bc] ../test.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 14.99 -user 14.99 -sys 0.00 -``` - -For this `bc`: - -``` -real 16.85 -user 16.84 -sys 0.00 -``` - -The command for the next script, the `while` loop script, was: - -``` -time -p [bc] ../test2.bc > /dev/null -``` - -For GNU `bc`: - -``` -real 14.92 -user 14.91 -sys 0.00 -``` - -For this `bc`: - -``` -real 12.75 -user 12.75 -sys 0.00 -``` - -It turns out that `-march=native` can be a problem. As such, I have removed the -recommendation to build with `-march=native`. - -## Recommended Compiler - -When I ran these benchmarks with my `bc` compiled under `clang` vs. `gcc`, it -performed much better under `clang`. I recommend compiling this `bc` with -`clang`. - -[1]: https://github.com/torvalds/linux/blob/master/kernel/time/timeconst.bc diff --git a/manuals/dc.1.md.in b/manuals/dc.1.md.in deleted file mode 100644 index 5ca37bcc97c4..000000000000 --- a/manuals/dc.1.md.in +++ /dev/null @@ -1,1452 +0,0 @@ -<!--- - -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 -{{ A H N HN }} -value for **obase** is **0**. If **obase** is **0**, values are output in -scientific notation, and if **obase** is **1**, values are output in engineering -notation. Otherwise, values are output in the specified base. - -Outputting in scientific and engineering notations are **non-portable -extensions**. -{{ end }} -{{ E EH EN EHN }} -value for **obase** is **2**. Values are output in the specified base. -{{ end }} - -The *scale* of an expression is the number of digits in the result of the -expression right of the decimal point, and **scale** is a register (see the -**REGISTERS** section) that sets the precision of any operations (with -exceptions). **scale** is initially **0**. **scale** cannot be negative. The max -allowable value for **scale** can be queried in dc(1) programs with the **V** -command. - -{{ A H N HN }} -**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**. -{{ end }} - -## Comments - -Comments go from **#** until, and not including, the next newline. This is a -**non-portable extension**. - -# NUMBERS - -Numbers are strings made up of digits, uppercase letters up to **F**, and at -most **1** period for a radix. Numbers can have up to **DC_NUM_MAX** digits. -Uppercase letters are equal to **9** + their position in the alphabet (i.e., -**A** equals **10**, or **9+1**). If a digit or letter makes no sense with the -current value of **ibase**, they are set to the value of the highest valid digit -in **ibase**. - -Single-character numbers (i.e., **A** alone) take the value that they would have -if they were valid digits, regardless of the value of **ibase**. This means that -**A** alone always equals decimal **10** and **F** alone always equals decimal -**15**. - -{{ A H N HN }} -In addition, dc(1) accepts numbers in scientific notation. These have the form -**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be -an integer. An example is **1.89237e9**, which is equal to **1892370000**. -Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**. - -**WARNING**: Both the number and the exponent in scientific notation are -interpreted according to the current **ibase**, but the number is still -multiplied by **10\^exponent** regardless of the current **ibase**. For example, -if **ibase** is **16** and dc(1) is given the number string **FFeA**, the -resulting decimal number will be **2550000000000**, and if dc(1) is given the -number string **10e_4**, the resulting decimal number will be **0.0016**. - -Accepting input as scientific notation is a **non-portable extension**. -{{ end }} - -# COMMANDS - -The valid commands are listed below. - -## Printing - -These commands are used for printing. - -{{ A H N HN }} -Note that both scientific notation and engineering notation are available for -printing numbers. Scientific notation is activated by assigning **0** to -**obase** using **0o**, and engineering notation is activated by assigning **1** -to **obase** using **1o**. To deactivate them, just assign a different value to -**obase**. - -Printing numbers in scientific notation and/or engineering notation is a -**non-portable extension**. -{{ end }} - -**p** - -:   Prints the value on top of the stack, whether number or string, and prints a -    newline after. - -    This does not alter the stack. - -**n** - -:   Prints the value on top of the stack, whether number or string, and pops it -    off of the stack. - -**P** - -:   Pops a value off the stack. - -    If the value is a number, it is truncated and the absolute value of the -    result is printed as though **obase** is **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**. - -{{ A H N HN }} -**\$** - -:   The top value is popped off the stack and copied, and the copy is truncated -    and pushed onto the stack. - -    This is a **non-portable extension**. - -**\@** - -:   The top two values are popped off the stack, and the precision of the second -    is set to the value of the first, whether by truncation or extension. - -    The first value popped off of the stack must be an integer and non-negative. - -    This is a **non-portable extension**. - -**H** - -:   The top two values are popped off the stack, and the second is shifted left -    (radix shifted right) to the value of the first. - -    The first value popped off of the stack must be an integer and non-negative. - -    This is a **non-portable extension**. - -**h** - -:   The top two values are popped off the stack, and the second is shifted right -    (radix shifted left) to the value of the first. - -    The first value popped off of the stack must be an integer and non-negative. - -    This is a **non-portable extension**. -{{ end }} - -**G** - -:   The top two values are popped off of the stack, they are compared, and a -    **1** is pushed if they are equal, or **0** otherwise. - -    This is a **non-portable extension**. - -**N** - -:   The top value is popped off of the stack, and if it a **0**, a **1** is -    pushed; otherwise, a **0** is pushed. - -    This is a **non-portable extension**. - -**(** - -:   The top two values are popped off of the stack, they are compared, and a -    **1** is pushed if the first is less than the second, or **0** otherwise. - -    This is a **non-portable extension**. - -**{** - -:   The top two values are popped off of the stack, they are compared, and a -    **1** is pushed if the first is less than or equal to the second, or **0** -    otherwise. - -    This is a **non-portable extension**. - -**)** - -:   The top two values are popped off of the stack, they are compared, and a -    **1** is pushed if the first is greater than the second, or **0** otherwise. - -    This is a **non-portable extension**. - -**}** - -:   The top two values are popped off of the stack, they are compared, and a -    **1** is pushed if the first is greater than or equal to the second, or -    **0** otherwise. - -    This is a **non-portable extension**. - -**M** - -:   The top two values are popped off of the stack. If they are both non-zero, a -    **1** is pushed onto the stack. If either of them is zero, or both of them -    are, then a **0** is pushed onto the stack. - -    This is like the **&&** operator in bc(1), and it is *not* a short-circuit -    operator. - -    This is a **non-portable extension**. - -**m** - -:   The top two values are popped off of the stack. If at least one of them is -    non-zero, a **1** is pushed onto the stack. If both of them are zero, then a -    **0** is pushed onto the stack. - -    This is like the **||** operator in bc(1), and it is *not* a short-circuit -    operator. - -    This is a **non-portable extension**. - -{{ A H N HN }} -## Pseudo-Random Number Generator - -dc(1) has a built-in pseudo-random number generator. These commands query the -pseudo-random number generator. (See Parameters for more information about the -**seed** value that controls the pseudo-random number generator.) - -The pseudo-random number generator is guaranteed to **NOT** be -cryptographically secure. - -**'** - -:   Generates an integer between 0 and **DC_RAND_MAX**, inclusive (see the -    **LIMITS** section). - -    The generated integer is made as unbiased as possible, subject to the -    limitations of the pseudo-random number generator. - -    This is a **non-portable extension**. - -**"** - -:   Pops a value off of the stack, which is used as an **exclusive** upper bound -    on the integer that will be generated. If the bound is negative or is a -    non-integer, an error is raised, and dc(1) resets (see the **RESET** -    section) while **seed** remains unchanged. If the bound is larger than -    **DC_RAND_MAX**, the higher bound is honored by generating several -    pseudo-random integers, multiplying them by appropriate powers of -    **DC_RAND_MAX+1**, and adding them together. Thus, the size of integer that -    can be generated with this command is unbounded. Using this command will -    change the value of **seed**, unless the operand is **0** or **1**. In that -    case, **0** is pushed onto the stack, and **seed** is *not* changed. - -    The generated integer is made as unbiased as possible, subject to the -    limitations of the pseudo-random number generator. - -    This is a **non-portable extension**. -{{ end }} - -## Stack Control - -These commands control the stack. - -**c** - -:   Removes all items from ("clears") the stack. - -**d** - -:   Copies the item on top of the stack ("duplicates") and pushes the copy onto -    the stack. - -**r** - -:   Swaps ("reverses") the two top items on the stack. - -**R** - -:   Pops ("removes") the top value from the stack. - -## Register Control - -These commands control registers (see the **REGISTERS** section). - -**s**_r_ - -:   Pops the value off the top of the stack and stores it into register *r*. - -**l**_r_ - -:   Copies the value in register *r* and pushes it onto the stack. This does not -    alter the contents of *r*. - -**S**_r_ - -:   Pops the value off the top of the (main) stack and pushes it onto the stack -    of register *r*. The previous value of the register becomes inaccessible. - -**L**_r_ - -:   Pops the value off the top of the stack for register *r* and push it onto -    the main stack. The previous value in the stack for register *r*, if any, is -    now accessible via the **l**_r_ command. - -## Parameters - -{{ A H N HN }} -These commands control the values of **ibase**, **obase**, **scale**, and -**seed**. Also see the **SYNTAX** section. -{{ end }} -{{ E EH EN EHN }} -These commands control the values of **ibase**, **obase**, and **scale**. Also -see the **SYNTAX** section. -{{ end }} - -**i** - -:   Pops the value off of the top of the stack and uses it to set **ibase**, -    which must be between **2** and **16**, inclusive. - -    If the value on top of the stack has any *scale*, the *scale* is ignored. - -**o** - -:   Pops the value off of the top of the stack and uses it to set **obase**, -{{ A H N HN }} -    which must be between **0** and **DC_BASE_MAX**, inclusive (see the -    **LIMITS** section and the **NUMBERS** section). -{{ end }} -{{ E EH EN EHN }} -    which must be between **2** and **DC_BASE_MAX**, inclusive (see the -    **LIMITS** section). -{{ end }} - -    If the value on top of the stack has any *scale*, the *scale* is ignored. - -**k** - -:   Pops the value off of the top of the stack and uses it to set **scale**, -    which must be non-negative. - -    If the value on top of the stack has any *scale*, the *scale* is ignored. - -{{ A H N HN }} -**j** - -:   Pops the value off of the top of the stack and uses it to set **seed**. The -    meaning of **seed** is dependent on the current pseudo-random number -    generator but is guaranteed to not change except for new major versions. - -    The *scale* and sign of the value may be significant. - -    If a previously used **seed** value is used again, the pseudo-random number -    generator is guaranteed to produce the same sequence of pseudo-random -    numbers as it did when the **seed** value was previously used. - -    The exact value assigned to **seed** is not guaranteed to be returned if the -    **J** command is used. However, if **seed** *does* return a different value, -    both values, when assigned to **seed**, are guaranteed to produce the same -    sequence of pseudo-random numbers. This means that certain values assigned -    to **seed** will not produce unique sequences of pseudo-random numbers. - -    There is no limit to the length (number of significant decimal digits) or -    *scale* of the value that can be assigned to **seed**. - -    This is a **non-portable extension**. -{{ end }} - -**I** - -:   Pushes the current value of **ibase** onto the main stack. - -**O** - -:   Pushes the current value of **obase** onto the main stack. - -**K** - -:   Pushes the current value of **scale** onto the main stack. - -{{ A H N HN }} -**J** - -:   Pushes the current value of **seed** onto the main stack. - -    This is a **non-portable extension**. -{{ end }} - -**T** - -:   Pushes the maximum allowable value of **ibase** onto the main stack. - -    This is a **non-portable extension**. - -**U** - -:   Pushes the maximum allowable value of **obase** onto the main stack. - -    This is a **non-portable extension**. - -**V** - -:   Pushes the maximum allowable value of **scale** onto the main stack. - -    This is a **non-portable extension**. - -{{ A H N HN }} -**W** - -:   Pushes the maximum (inclusive) integer that can be generated with the **'** -    pseudo-random number generator command. - -    This is a **non-portable extension**. -{{ end }} - -## Strings - -The following commands control strings. - -dc(1) can work with both numbers and strings, and registers (see the -**REGISTERS** section) can hold both strings and numbers. dc(1) always knows -whether the contents of a register are a string or a number. - -While arithmetic operations have to have numbers, and will print an error if -given a string, other commands accept strings. - -Strings can also be executed as macros. For example, if the string **[1pR]** is -executed as a macro, then the code **1pR** is executed, meaning that the **1** -will be printed with a newline after and then popped from the stack. - -**\[**_characters_**\]** - -:   Makes a string containing *characters* and pushes it onto the stack. - -    If there are brackets (**\[** and **\]**) in the string, then they must be -    balanced. Unbalanced brackets can be escaped using a backslash (**\\**) -    character. - -    If there is a backslash character in the string, the character after it -    (even another backslash) is put into the string verbatim, but the (first) -    backslash is not. - -**a** - -:   The value on top of the stack is popped. - -    If it is a number, it is truncated and its absolute value is taken. The -    result mod **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**. - -{{ A H N HN }} -**DC_RAND_MAX** - -:   The maximum integer (inclusive) returned by the **'** command, if dc(1). Set -    at **2\^DC_LONG_BIT-1**. -{{ end }} - -Exponent - -:   The maximum allowable exponent (positive or negative). Set at -    **DC_OVERFLOW_MAX**. - -Number of vars - -:   The maximum number of vars/arrays. Set at **SIZE_MAX-1**. - -These limits are meant to be effectively non-existent; the limits are so large -(at least on 64-bit machines) that there should not be any point at which they -become a problem. In fact, memory should be exhausted before these limits should -be hit. - -# ENVIRONMENT VARIABLES - -dc(1) recognizes the following environment variables: - -**DC_ENV_ARGS** - -:   This is another way to give command-line arguments to dc(1). They should be -    in the same format as all other command-line arguments. These are always -    processed first, so any files given in **DC_ENV_ARGS** will be processed -    before arguments and files given on the command-line. This gives the user -    the ability to set up "standard" options and files to be used at every -    invocation. The most useful thing for such files to contain would be useful -    functions that the user might want every time dc(1) runs. Another use would -    be to use the **-e** option to set **scale** to a value other than **0**. - -    The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, -    but it does not understand escape sequences. For example, the string -    **"/home/gavin/some dc file.dc"** will be correctly parsed, but the string -    **"/home/gavin/some \"dc\" file.dc"** will include the backslashes. - -    The quote parsing will handle either kind of quotes, **'** or **"**. Thus, -    if you have a file with any number of single quotes in the name, you can use -    double quotes as the outside quotes, as in **"some '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. - -**DC_EXPR_EXIT** - -:   If any expressions or expression files are given on the command-line with -    **-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment -    variable exists and contains an integer, a non-zero value makes dc(1) exit -    after executing the expressions and expression files, and a non-zero value -    makes dc(1) not exit. - -    This environment variable overrides 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 -{{ A H N HN }} -    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. -{{ end }} -{{ E EH EN EHN }} -    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. -{{ end }} - -**2** - -:   A parse error occurred. - -    Parse errors include unexpected **EOF**, using an invalid character, failing -    to find the end of a string or comment, and using a token where it is -    invalid. - -**3** - -:   A runtime error occurred. - -    Runtime errors include assigning an invalid number to 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. - -{{ A E N EN }} -## 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. -{{ end }} - -## 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 -{{ A E N EN }} -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. -{{ end }} -{{ H EH HN EHN }} -default handler for all other signals. -{{ end }} - -{{ A E N EN }} -# 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. -{{ end }} - -{{ A E H EH }} -# LOCALES - -This dc(1) ships with support for adding error messages for different locales -and thus, supports **LC_MESSAGES**. -{{ end }} - -# SEE ALSO - -bc(1) - -# STANDARDS - -The dc(1) utility operators are compliant with the operators in the bc(1) -[IEEE Std 1003.1-2017 (“POSIX.1-2017â€)][1] specification. - -# BUGS - -None are known. Report bugs at https://git.yzena.com/gavin/bc. - -# AUTHOR - -Gavin D. Howard <gavin@yzena.com> and contributors. - -[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html diff --git a/manuals/development.md b/manuals/development.md deleted file mode 100644 index 6733d496defd..000000000000 --- a/manuals/development.md +++ /dev/null @@ -1,5110 +0,0 @@ -# Development - -Updated: 06 Oct 2021 - -This document is meant for the day when I (Gavin D. Howard) get [hit by a -bus][1]. In other words, it's meant to make the [bus factor][1] a non-issue. - -This document is supposed to contain all of the knowledge necessary to develop -`bc` and `dc`. - -In addition, this document is meant to add to the [oral tradition of software -engineering][118], as described by Bryan Cantrill. - -This document will reference other parts of the repository. That is so a lot of -the documentation can be closest to the part of the repo where it is actually -necessary. - -## What Is It? - -This repository contains an implementation of both [POSIX `bc`][2] and [Unix -`dc`][3]. - -POSIX `bc` is a standard utility required for POSIX systems. `dc` is a -historical utility that was included in early Unix and even predates both Unix -and C. They both are arbitrary-precision command-line calculators with their own -programming languages. `bc`'s language looks similar to C, with infix notation -and including functions, while `dc` uses [Reverse Polish Notation][4] and allows -the user to execute strings as though they were functions. - -In addition, it is also possible to build the arbitrary-precision math as a -library, named [`bcl`][156]. - -**Note**: for ease, I will refer to both programs as `bc` in this document. -However, if I say "just `bc`," I am referring to just `bc`, and if I say `dc`, I -am referring to just `dc`. - -### History - -This project started in January 2018 when a certain individual on IRC, hearing -that I knew how to write parsers, asked me to write a `bc` parser for his math -library. I did so. I thought about writing my own math library, but he -disparaged my programming skills and made me think that I couldn't do it. - -However, he took so long to do it that I eventually decided to give it a try and -had a working math portion in two weeks. It taught me that I should not listen -to such people. - -From that point, I decided to make it an extreme learning experience about how -to write quality software. - -That individual's main goal had been to get his `bc` into [toybox][16], and I -managed to get my own `bc` in. I also got it in [busybox][17]. - -Eventually, in late 2018, I also decided to try my hand at implementing -[Karatsuba multiplication][18], an algorithm that that unnamed individual -claimed I could never implement. It took me a bit, but I did it. - -This project became a passion project for me, and I continued. In mid-2019, -Stefan Eßer suggested I improve performance by putting more than 1 digit in each -section of the numbers. After I showed immaturity because of some burnout, I -implemented his suggestion, and the results were incredible. - -Since that time, I have gradually been improving the `bc` as I have learned more -about things like fuzzing, [`scan-build`][19], [valgrind][20], -[AddressSanitizer][21] (and the other sanitizers), and many other things. - -One of my happiest moments was when my `bc` was made the default in FreeBSD. - -But since I believe in [finishing the software I write][22], I have done less -work on `bc` over time, though there are still times when I put a lot of effort -in, such as now (17 June 2021), when I am attempting to convince OpenBSD to use -my `bc`. - -And that is why I am writing this document: someday, someone else is going to -want to change my code, and this document is my attempt to make it as simple as -possible. - -### Values - -[According to Bryan Cantrill][10], all software has values. I think he's -correct, though I [added one value for programming languages in particular][11]. - -However, for `bc`, his original list will do: - -* Approachability -* Availability -* Compatibility -* Composability -* Debuggability -* Expressiveness -* Extensibility -* Interoperability -* Integrity -* Maintainability -* Measurability -* Operability -* Performance -* Portability -* Resiliency -* Rigor -* Robustness -* Safety -* Security -* Simplicity -* Stability -* Thoroughness -* Transparency -* Velocity - -There are several values that don't apply. The reason they don't apply is -because `bc` and `dc` are existing utilities; this is just another -reimplementation. The designs of `bc` and `dc` are set in stone; there is -nothing we can do to change them, so let's get rid of those values that would -apply to their design: - -* Compatibility -* Integrity -* Maintainability -* Measurability -* Performance -* Portability -* Resiliency -* Rigor -* Robustness -* Safety -* Security -* Simplicity -* Stability -* Thoroughness -* Transparency - -Furthermore, some of the remaining ones don't matter to me, so let me get rid of -those and order the rest according to my *actual* values for this project: - -* Robustness -* Stability -* Portability -* Compatibility -* Performance -* Security -* Simplicity - -First is **robustness**. This `bc` and `dc` should be robust, accepting any -input, never crashing, and instead, returning an error. - -Closely related to that is **stability**. The execution of `bc` and `dc` should -be deterministic and never change for the same inputs, including the -pseudo-random number generator (for the same seed). - -Third is **portability**. These programs should run everywhere that POSIX -exists, as well as Windows. This means that just about every person on the -planet will have access to these programs. - -Next is **compatibility**. These programs should, as much as possible, be -compatible with other existing implementations and standards. - -Then we come to **performance**. A calculator is only usable if it's fast, so -these programs should run as fast as possible. - -After that is **security**. These programs should *never* be the reason a user's -computer is compromised. - -And finally, **simplicity**. Where possible, the code should be simple, while -deferring to the above values. - -Keep these values in mind for the rest of this document, and for exploring any -other part of this repo. - -#### Portability - -But before I go on, I want to talk about portability in particular. - -Most of these principles just require good attention and care, but portability -is different. Sometimes, it requires pulling in code from other places and -adapting it. In other words, sometimes I need to duplicate and adapt code. - -This happened in a few cases: - -* Option parsing (see [`include/opt.h`][35]). -* History (see [`include/history.h`][36]). -* Pseudo-Random Number Generator (see [`include/rand.h`][37]). - -This was done because I decided to ensure that `bc`'s dependencies were -basically zero. In particular, either users have a normal install of Windows or -they have a POSIX system. - -A POSIX system limited me to C99, `sh`, and zero external dependencies. That -last item is why I pull code into `bc`: if I pull it in, it's not an external -dependency. - -That's why `bc` has duplicated code. Remove it, and you risk `bc` not being -portable to some platforms. - -## Suggested Course - -I do have a suggested course for programmers to follow when trying to understand -this codebase. The order is this: - -1.	`bc` Spec. -2.	Manpages. -3.	Test suite. -4.	Understand the build. -5.	Algorithms manual. -6.	Code concepts. -7.	Repo structure. -8.	Headers. -9.	Source code. - -This order roughly follows this order: - -1. High-level requirements -2. Low-level requirements -3. High-level implementation -4. Low-level implementation - -In other words, first understand what the code is *supposed* to do, then -understand the code itself. - -## Useful External Tools - -I have a few tools external to `bc` that are useful: - -* A [Vim plugin with syntax files made specifically for my `bc` and `dc`][132]. -* A [repo of `bc` and `dc` scripts][133]. -* A set of `bash` aliases (see below). -* A `.bcrc` file with items useful for my `bash` setup (see below). - -My `bash` aliases are these: - -```sh -alias makej='make -j16' -alias mcmake='make clean && make' -alias mcmakej='make clean && make -j16' -alias bcdebug='CPPFLAGS="-DBC_DEBUG_CODE=1" CFLAGS="-Weverything -Wno-padded \ -    -Wno-switch-enum -Wno-format-nonliteral -Wno-cast-align \ -    -Wno-unreachable-code-return -Wno-missing-noreturn \ -    -Wno-disabled-macro-expansion -Wno-unreachable-code -Wall -Wextra \ -    -pedantic -std=c99" ./configure.sh' -alias bcconfig='CFLAGS="-Weverything -Wno-padded -Wno-switch-enum \ -    -Wno-format-nonliteral -Wno-cast-align -Wno-unreachable-code-return \ -    -Wno-missing-noreturn -Wno-disabled-macro-expansion -Wno-unreachable-code \ -    -Wall -Wextra -pedantic -std=c99" ./configure.sh' -alias bcnoassert='CPPFLAGS="-DNDEBUG" CFLAGS="-Weverything -Wno-padded \ -    -Wno-switch-enum -Wno-format-nonliteral -Wno-cast-align \ -    -Wno-unreachable-code-return -Wno-missing-noreturn \ -    -Wno-disabled-macro-expansion -Wno-unreachable-code -Wall -Wextra \ -    -pedantic -std=c99" ./configure.sh' -alias bcdebugnoassert='CPPFLAGS="-DNDEBUG -DBC_DEBUG_CODE=1" \ -    CFLAGS="-Weverything -Wno-padded -Wno-switch-enum -Wno-format-nonliteral \ -    -Wno-cast-align -Wno-unreachable-code-return -Wno-missing-noreturn \ -    -Wno-disabled-macro-expansion -Wno-unreachable-code -Wall -Wextra \ -    -pedantic -std=c99" ./configure.sh' -alias bcunset='unset BC_LINE_LENGTH && unset BC_ENV_ARGS' -``` - -`makej` runs `make` with all of my cores. - -`mcmake` runs `make clean` before running `make`. It will take a target on the -command-line. - -`mcmakej` is a combination of `makej` and `mcmake`. - -`bcdebug` configures `bc` for a full debug build, including `BC_DEBUG_CODE` (see -[Debugging][134] below). - -`bcconfig` configures `bc` with Clang (Clang is my personal default compiler) -using full warnings, with a few really loud and useless warnings turned off. - -`bcnoassert` configures `bc` to not have asserts built in. - -`bcdebugnoassert` is like `bcnoassert`, except it also configures `bc` for debug -mode. - -`bcunset` unsets my personal `bc` environment variables, which are set to: - -```sh -export BC_ENV_ARGS="-l $HOME/.bcrc" -export BC_LINE_LENGTH="74" -``` - -Unsetting these environment variables are necessary for running -[`scripts/release.sh`][83] because otherwise, it will error when attempting to -run `bc -s` on my `$HOME/.bcrc`. - -Speaking of which, the contents of that file are: - -```bc -define void print_time_unit(t){ -	if(t<10)print "0" -	if(t<1&&t)print "0" -	print t,":" -} -define void sec2time(t){ -	auto s,m,h,d,r -	r=scale -	scale=0 -	t=abs(t) -	s=t%60 -	t-=s -	m=t/60%60 -	t-=m -	h=t/3600%24 -	t-=h -	d=t/86400 -	if(d)print_time_unit(d) -	if(h)print_time_unit(h) -	print_time_unit(m) -	if(s<10)print "0" -	if(s<1&&s)print "0" -	s -	scale=r -} -define minutes(secs){ -	return secs/60; -} -define hours(secs){ -	return secs/3600; -} -define days(secs){ -	return secs/3600/24; -} -define years(secs){ -	return secs/3600/24/365.25; -} -define fbrand(b,p){ -	auto l,s,t -	b=abs(b)$ -	if(b<2)b=2 -	s=scale -	t=b^abs(p)$ -	l=ceil(l2(t),0) -	if(l>scale)scale=l -	t=irand(t)/t -	scale=s -	return t -} -define ifbrand(i,b,p){return irand(abs(i)$)+fbrand(b,p)} -``` - -This allows me to use `bc` as part of my `bash` prompt. - -## Code Style - -The code style for `bc` is...weird, and that comes from historical accident. - -In [History][23], I mentioned how I got my `bc` in [toybox][16]. Well, in order -to do that, my `bc` originally had toybox style. Eventually, I changed to using -tabs, and assuming they were 4 spaces wide, but other than that, I basically -kept the same style, with some exceptions that are more or less dependent on my -taste. - -The code style is as follows: - -* Tabs are 4 spaces. -* Tabs are used at the beginning of lines for indent. -* Spaces are used for alignment. -* Lines are limited to 80 characters, period. -* Pointer asterisk (`*`) goes with the variable (on the right), not the type, -  unless it is for a pointer type returned from a function. -* The opening brace is put on the same line as the header for the function, -  loop, or `if` statement. -* Unless the header is more than one line, in which case the opening brace is -  put on its own line. -* If the opening brace is put on its own line, there is no blank line after it. -* If the opening brace is *not* put on its own line, there *is* a blank line -  after it, *unless* the block is only one or two lines long. -* Code lines are grouped into what I call "paragraphs." Basically, lines that -  seem like they should go together are grouped together. This one comes down -  to judgment. -* Bodies of `if` statements, `else` statements, and loops that are one line -  long are put on the same line as the statement, unless the header is more than -  one line long, and/or, the header and body cannot fit into 80 characters with -  a space inbetween them. -* If single-line bodies are on a separate line from their headers, and the -  headers are only a single line, then no braces are used. -* However, braces are *always* used if they contain another `if` statement or -  loop. -* Loops with empty bodies are ended with a semicolon. -* Expressions that return a boolean value are surrounded by paretheses. -* Macro backslashes are aligned as far to the left as possible. -* Binary operators have spaces on both sides. -* If a line with binary operators overflows 80 characters, a newline is inserted -  *after* binary operators. -* Function modifiers and return types are on the same line as the function name. -* With one exception, `goto`'s are only used to jump to the end of a function -  for cleanup. -* All structs, enums, and unions are `typedef`'ed. -* All constant data is in one file: [`src/data.c`][131], but the corresponding -  `extern` declarations are in the appropriate header file. -* All local variables are declared at the beginning of the scope where they -  appear. They may be initialized at that point, if it does not invoke UB or -  otherwise cause bugs. -* All precondition `assert()`'s (see [Asserts][135]) come *after* local variable -  declarations. -* Besides short `if` statements and loops, there should *never* be more than one -  statement per line. - -### ClangFormat - -I attempted three times to use [ClangFormat][24] to impose a standard, -machine-useful style on `bc`. All three failed. Otherwise, the style in this -repo would be more consistent. - -## Repo Structure - -Functions are documented with Doxygen-style doc comments. Functions that appear -in headers are documented in the headers, while static functions are documented -where they are defined. - -### `configure` - -A symlink to [`configure.sh`][69]. - -### `configure.sh` - -This is the script to configure `bc` and [`bcl`][156] for building. - -This `bc` has a custom build system. The reason for this is because of -[*portability*][136]. - -If `bc` used an outside build system, that build system would be an external -dependency. Thus, I had to write a build system for `bc` that used nothing but -C99 and POSIX utilities. - -One of those utilities is POSIX `sh`, which technically implements a -Turing-complete programming language. It's a terrible one, but it works. - -A user that wants to build `bc` on a POSIX system (not Windows) first runs -`configure.sh` with the options he wants. `configure.sh` uses those options and -the `Makefile` template ([`Makefile.in`][70]) to generate an actual valid -`Makefile`. Then `make` can do the rest. - -For more information about the build process, see the [Build System][142] -section and the [build manual][14]. - -For more information about shell scripts, see [POSIX Shell Scripts][76]. - -`configure.sh` does the following: - -1.	It processes command-line arguments and figure out what the user wants to -	build. -2.	It reads in [`Makefile.in`][70]. -3.	One-by-one, it replaces placeholders (in [`Makefile.in`][70]) of the form -	`%%<placeholder_name>%%` based on the [build type][81]. -4.	It appends a list of file targets based on the [build type][81]. -5.	It appends the correct test targets. -6.	It copies the correct manpage and markdown manual for `bc` and `dc` into a -	location from which they can be copied for install. -7.	It does a `make clean` to reset the build state. - -### `.gitattributes` - -A `.gitattributes` file. This is needed to preserve the `crlf` line endings in -the Visual Studio files. - -### `.gitignore` - -The `.gitignore` - -### `LICENSE.md` - -This is the `LICENSE` file, including the licenses of various software that I -have borrowed. - -### `Makefile.in` - -This is the `Makefile` template for [`configure.sh`][69] to use for generating a -`Makefile`. - -For more information, see [`configure.sh`][69], the [Build System][142] section, -and the [build manual][14]. - -Because of [portability][136], the generated `Makefile.in` should be a pure -[POSIX `make`][74]-compatible `Makefile` (minus the placeholders). Here are a -few snares for the unwary programmer in this file: - -1.	No extensions allowed, including and especially GNU extensions. -2.	If new headers are added, they must also be added to `Makefile.in`. -3.	Don't delete the `.POSIX:` empty target at the top; that's what tells `make` -	implementations that pure [POSIX `make`][74] is needed. - -In particular, there is no way to set up variables other than the `=` operator. -There are no conditionals, so all of the conditional stuff must be in -[`configure.sh`][69]. This is, in fact, why [`configure.sh`][69] exists in the -first place: [POSIX `make`][74] is barebones and only does a build with no -configuration. - -### `NEWS.md` - -A running changelog with an entry for each version. This should be updated at -the same time that [`include/version.h`][75] is. - -### `NOTICE.md` - -The `NOTICE` file with proper attributions. - -### `README.md` - -The `README`. Read it. - -### `benchmarks/` - -The folder containing files to generate benchmarks. - -Each of these files was made, at one time or another, to benchmark some -experimental feature, so if it seems there is no rhyme or reason to these -benchmarks, it is because there is none, besides historical accident. - -#### `bc/` - -The folder containing `bc` scripts to generate `bc` benchmarks. - -##### `add.bc` - -The file to generate the benchmark to benchmark addition in `bc`. - -##### `arrays_and_constants.bc` - -The file to generate the benchmark to benchmark `bc` using lots of array names -and constants. - -##### `arrays.bc` - -The file to generate the benchmark to benchmark `bc` using lots of array names. - -##### `constants.bc` - -The file to generate the benchmark to benchmark `bc` using lots of constants. - -##### `divide.bc` - -The file to generate the benchmark to benchmark division in `bc`. - -##### `functions.bc` - -The file to generate the benchmark to benchmark `bc` using lots of functions. - -##### `irand_long.bc` - -The file to generate the benchmark to benchmark `bc` using lots of calls to -`irand()` with large bounds. - -##### `irand_short.bc` - -The file to generate the benchmark to benchmark `bc` using lots of calls to -`irand()` with small bounds. - -##### `lib.bc` - -The file to generate the benchmark to benchmark `bc` using lots of calls to -heavy functions in `lib.bc`. - -##### `multiply.bc` - -The file to generate the benchmark to benchmark multiplication in `bc`. - -##### `postfix_incdec.bc` - -The file to generate the benchmark to benchmark `bc` using postfix increment and -decrement operators. - -##### `power.bc` - -The file to generate the benchmark to benchmark power (exponentiation) in `bc`. - -##### `subtract.bc` - -The file to generate the benchmark to benchmark subtraction in `bc`. - -##### `strings.bc` - -The file to generate the benchmark to benchmark `bc` using lots of strings. - -#### `dc/` - -The folder containing `dc` scripts to generate `dc` benchmarks. - -##### `modexp.dc` - -The file to generate the benchmark to benchmark modular exponentiation in `dc`. - -### `gen/` - -A folder containing the files necessary to generate C strings that will be -embedded in the executable. - -All of the files in this folder have license headers, but the program and script -that can generate strings from them include code to strip the license header out -before strings are generated. - -#### `bc_help.txt` - -A text file containing the text displayed for `bc -h` or `bc --help`. - -This text just contains the command-line options and a short summary of the -differences from GNU and BSD `bc`'s. It also directs users to the manpage. - -The reason for this is because otherwise, the help would be far too long to be -useful. - -**Warning**: The text has some `printf()` format specifiers. You need to make -sure the format specifiers match the arguments given to `bc_file_printf()`. - -#### `dc_help.txt` - -A text file containing the text displayed for `dc -h` or `dc --help`. - -This text just contains the command-line options and a short summary of the -differences from GNU and BSD `dc`'s. It also directs users to the manpage. - -The reason for this is because otherwise, the help would be far too long to be -useful. - -**Warning**: The text has some `printf()` format specifiers. You need to make -sure the format specifiers match the arguments given to `bc_file_printf()`. - -#### `lib.bc` - -A `bc` script containing the [standard math library][5] required by POSIX. See -the [POSIX standard][2] for what is required. - -This file does not have any extraneous whitespace, except for tabs at the -beginning of lines. That is because this data goes directly into the binary, -and whitespace is extra bytes in the binary. Thus, not having any extra -whitespace shrinks the resulting binary. - -However, tabs at the beginning of lines are kept for two reasons: - -1.	Readability. (This file is still code.) -2.	The program and script that generate strings from this file can remove -	tabs at the beginning of lines. - -For more details about the algorithms used, see the [algorithms manual][25]. - -However, there are a few snares for unwary programmers. - -First, all constants must be one digit. This is because otherwise, multi-digit -constants could be interpreted wrongly if the user uses a different `ibase`. -This does not happen with single-digit numbers because they are guaranteed to be -interpreted what number they would be if the `ibase` was as high as possible. - -This is why `A` is used in the library instead of `10`, and things like `2*9*A` -for `180` in [`lib2.bc`][26]. - -As an alternative, you can set `ibase` in the function, but if you do, make sure -to set it with a single-digit number and beware the snare below... - -Second, `scale`, `ibase`, and `obase` must be safely restored before returning -from any function in the library. This is because without the `-g` option, -functions are allowed to change any of the globals. - -Third, all local variables in a function must be declared in an `auto` statement -before doing anything else. This includes arrays. However, function parameters -are considered predeclared. - -Fourth, and this is only a snare for `lib.bc`, not [`lib2.bc`][26], the code -must not use *any* extensions. It has to work when users use the `-s` or `-w` -flags. - -#### `lib2.bc` - -A `bc` script containing the [extended math library][7]. - -Like [`lib.bc`][8], and for the same reasons, this file should have no -extraneous whitespace, except for tabs at the beginning of lines. - -For more details about the algorithms used, see the [algorithms manual][25]. - -Also, be sure to check [`lib.bc`][8] for the snares that can trip up unwary -programmers when writing code for `lib2.bc`. - -#### `strgen.c` - -Code for the program to generate C strings from text files. This is the original -program, although [`strgen.sh`][9] was added later. - -The reason I used C here is because even though I knew `sh` would be available -(it must be available to run `configure.sh`), I didn't know how to do what I -needed to do with POSIX utilities and `sh`. - -Later, [`strgen.sh`][9] was contributed by Stefan Eßer of FreeBSD, showing that -it *could* be done with `sh` and POSIX utilities. - -However, `strgen.c` exists *still* exists because the versions generated by -[`strgen.sh`][9] may technically hit an environmental limit. (See the [draft C99 -standard][12], page 21.) This is because [`strgen.sh`][9] generates string -literals, and in C99, string literals can be limited to 4095 characters, and -`gen/lib2.bc` is above that. - -Fortunately, the limit for "objects," which include `char` arrays, is much -bigger: 65535 bytes, so that's what `strgen.c` generates. - -However, the existence of `strgen.c` does come with a cost: the build needs C99 -compiler that targets the host machine. For more information, see the ["Cross -Compiling" section][13] of the [build manual][14]. - -Read the comments in `strgen.c` for more detail about it, the arguments it -takes, and how it works. - -#### `strgen.sh` - -An `sh` script that will generate C strings that uses only POSIX utilities. This -exists for those situations where a host C99 compiler is not available, and the -environment limits mentioned above in [`strgen.c`][15] don't matter. - -`strgen.sh` takes the same arguments as [`strgen.c`][15], and the arguments mean -the exact same things, so see the comments in [`strgen.c`][15] for more detail -about that, and see the comments in `strgen.sh` for more details about it and -how it works. - -For more information about shell scripts, see [POSIX Shell Scripts][76]. - -### `include/` - -A folder containing the headers. - -The headers are not included among the source code because I like it better that -way. Also there were folders within `src/` at one point, and I did not want to -see `#include "../some_header.h"` or things like that. - -So all headers are here, even though only one ([`bcl.h`][30]) is meant for end -users (to be installed in `INCLUDEDIR`). - -#### `args.h` - -This file is the API for processing command-line arguments. - -#### `bc.h` - -This header is the API for `bc`-only items. This includes the `bc_main()` -function and the `bc`-specific lexing and parsing items. - -The `bc` parser is perhaps the most sensitive part of the entire codebase. See -the documentation in `bc.h` for more information. - -The code associated with this header is in [`src/bc.c`][40], -[`src/bc_lex.c`][41], and [`src/bc_parse.c`][42]. - -#### `bcl.h` - -This header is the API for the [`bcl`][156] library. - -This header is meant for distribution to end users and contains the API that end -users of [`bcl`][156] can use in their own software. - -This header, because it's the public header, is also the root header. That means -that it has platform-specific fixes for Windows. (If the fixes were not in this -header, the build would fail on Windows.) - -The code associated with this header is in [`src/library.c`][43]. - -#### `dc.h` - -This header is the API for `dc`-only items. This includes the `dc_main()` -function and the `dc`-specific lexing and parsing items. - -The code associated with this header is in [`src/dc.c`][44], -[`src/dc_lex.c`][45], and [`src/dc_parse.c`][46]. - -#### `file.h` - -This header is for `bc`'s internal buffered I/O API. - -For more information about `bc`'s error handling and custom buffered I/O, see -[Error Handling][97] and [Custom I/O][114], along with [`status.h`][176] and the -notes about version [`3.0.0`][32] in the [`NEWS`][32]. - -The code associated with this header is in [`src/file.c`][47]. - -#### `history.h` - -This header is for `bc`'s implementation of command-line editing/history, which -is based on a [UTF-8-aware fork][28] of [`linenoise`][29]. - -For more information, see the [Command-Line History][189] section. - -The code associated with this header is in [`src/history.c`][48]. - -#### `lang.h` - -This header defines the data structures and bytecode used for actual execution -of `bc` and `dc` code. - -Yes, it's misnamed; that's an accident of history where the first things I put -into it all seemed related to the `bc` language. - -The code associated with this header is in [`src/lang.c`][49]. - -#### `lex.h` - -This header defines the common items that both programs need for lexing. - -The code associated with this header is in [`src/lex.c`][50], -[`src/bc_lex.c`][41], and [`src/dc_lex.c`][45]. - -#### `library.h` - -This header defines the things needed for [`bcl`][156] that users should *not* -have access to. In other words, [`bcl.h`][30] is the *public* header for the -library, and this header is the *private* header for the library. - -The code associated with this header is in [`src/library.c`][43]. - -#### `num.h` - -This header is the API for numbers and math. - -The code associated with this header is in [`src/num.c`][39]. - -#### `opt.h` - -This header is the API for parsing command-line arguments. - -It's different from [`args.h`][31] in that [`args.h`][31] is for the main code -to process the command-line arguments into global data *after* they have already -been parsed by `opt.h` into proper tokens. In other words, `opt.h` actually -parses the command-line arguments, and [`args.h`][31] turns that parsed data -into flags (bits), strings, and expressions that will be used later. - -Why are they separate? Because originally, `bc` used `getopt_long()` for -parsing, so [`args.h`][31] was the only one that existed. After it was -discovered that `getopt_long()` has different behavior on different platforms, I -adapted a [public-domain option parsing library][34] to do the job instead. And -in doing so, I gave it its own header. - -They could probably be combined, but I don't really care enough at this point. - -The code associated with this header is in [`src/opt.c`][51]. - -#### `parse.h` - -This header defines the common items that both programs need for parsing. - -Note that the parsers don't produce abstract syntax trees (AST's) or any -intermediate representations. They produce bytecode directly. In other words, -they don't have special data structures except what they need to do their job. - -The code associated with this header is in [`src/parse.c`][50], -[`src/bc_lex.c`][42], and [`src/dc_lex.c`][46]. - -#### `program.h` - -This header defines the items needed to manage the data structures in -[`lang.h`][38] as well as any helper functions needed to generate bytecode or -execute it. - -The code associated with this header is in [`src/program.c`][53]. - -#### `rand.h` - -This header defines the API for the [pseudo-random number generator -(PRNG)][179]. - -The PRNG only generates fixed-size integers. The magic of generating random -numbers of arbitrary size is actually given to the code that does math -([`src/num.c`][39]). - -The code associated with this header is in [`src/rand.c`][54]. - -#### `read.h` - -This header defines the API for reading from files and `stdin`. - -Thus, [`file.h`][55] is really for buffered *output*, while this file is for -*input*. There is no buffering needed for `bc`'s inputs. - -The code associated with this header is in [`src/read.c`][56]. - -#### `status.h` - -This header has several things: - -* A list of possible errors that internal `bc` code can use. -* Compiler-specific fixes. -* Platform-specific fixes. -* Macros for `bc`'s [error handling][97]. - -There is no code associated with this header. - -#### `vector.h` - -This header defines the API for the vectors (resizable arrays) that are used for -data structures. - -Vectors are what do the heavy lifting in almost all of `bc`'s data structures. -Even the maps of identifiers and arrays use vectors. - -#### `version.h` - -This header defines the version of `bc`. - -There is no code associated with this header. - -#### `vm.h` - -This header defines the API for setting up and running `bc` and `dc`. - -It is so named because I think of it as the "virtual machine" of `bc`, though -that is probably not true as [`program.h`][57] is probably the "virtual machine" -API. Thus, the name is more historical accident. - -The code associated with this header is in [`src/vm.c`][58]. - -### `locales/` - -This folder contains a bunch of `.msg` files and soft links to the real `.msg` -files. This is how locale support is implemented in `bc`. - -The files are in the format required by the [`gencat`][59] POSIX utility. They -all have the same messages, in the same order, with the same numbering, under -the same groups. This is because the locale system expects those messages in -that order. - -The softlinks exist because for many locales, they would contain the exact same -information. To prevent duplication, they are simply linked to a master copy. - -The naming format for all files is: - -``` -<language_code>_<country_code>.<encoding>.msg -``` - -This naming format must be followed for all locale files. - -### `manuals/` - -This folder contains the documentation for `bc`, `dc`, and [`bcl`][156], along -with a few other manuals. - -#### `algorithms.md` - -This file explains the mathematical algorithms that are used. - -The hope is that this file will guide people in understanding how the math code -works. - -#### `bc.1.md.in` - -This file is a template for the markdown version of the `bc` manual and -manpages. - -For more information about how the manpages and markdown manuals are generated, -and for why, see [`scripts/manpage.sh`][60] and [Manuals][86]. - -#### `bcl.3` - -This is the manpage for the [`bcl`][156] library. It is generated from -[`bcl.3.md`][61] using [`scripts/manpage.sh`][60]. - -For the reason why I check generated data into the repo, see -[`scripts/manpage.sh`][60] and [Manuals][86]. - -#### `bcl.3.md` - -This is the markdown manual for the [`bcl`][156] library. It is the source for the -generated [`bcl.3`][62] file. - -#### `benchmarks.md` - -This is a document that compares this `bc` to GNU `bc` in various benchmarks. It -was last updated when version [`3.0.0`][32] was released. - -It has very little documentation value, other than showing what compiler options -are useful for performance. - -#### `build.md` - -This is the [build manual][14]. - -This `bc` has a custom build system. The reason for this is because of -[*portability*][136]. - -If `bc` used an outside build system, that build system would be an external -dependency. Thus, I had to write a build system for `bc` that used nothing but -C99 and POSIX utilities, including barebones [POSIX `make`][74]. - -for more information about the build system, see the [build system][142] -section, the [build manual][14], [`configure.sh`][69], and [`Makefile.in`][70]. - -#### `dc.1.md.in` - -This file is a template for the markdown version of the `dc` manual and -manpages. - -For more information about how the manpages and markdown manuals are generated, -and for why, see [`scripts/manpage.sh`][60] and [Manuals][86]. - -#### `development.md` - -The file you are reading right now. - -#### `header_bcl.txt` - -Used by [`scripts/manpage.sh`][60] to give the [`bcl.3`][62] manpage a proper -header. - -For more information about generating manuals, see [`scripts/manpage.sh`][60] -and [Manuals][86]. - -#### `header_bc.txt` - -Used by [`scripts/manpage.sh`][60] to give the [generated `bc` manpages][79] a -proper header. - -For more information about generating manuals, see [`scripts/manpage.sh`][60] -and [Manuals][86]. - -#### `header_dc.txt` - -Used by [`scripts/manpage.sh`][60] to give the [generated `dc` manpages][80] a -proper header. - -For more information about generating manuals, see [`scripts/manpage.sh`][60] -and [Manuals][86]. - -#### `header.txt` - -Used by [`scripts/manpage.sh`][60] to give all generated manpages a license -header. - -For more information about generating manuals, see [`scripts/manpage.sh`][60] -and [Manuals][86]. - -#### `release.md` - -A checklist that I try to somewhat follow when making a release. - -#### `bc/` - -A folder containing the `bc` manuals. - -Each `bc` manual corresponds to a [build type][81]. See that link for more -details. - -For each manual, there are two copies: the markdown version generated from the -template, and the manpage generated from the markdown version. - -#### `dc/` - -A folder containing the `dc` manuals. - -Each `dc` manual corresponds to a [build type][81]. See that link for more -details. - -For each manual, there are two copies: the markdown version generated from the -template, and the manpage generated from the markdown version. - -### `scripts/` - -This folder contains helper scripts. Most of them are written in pure [POSIX -`sh`][72], but one ([`karatsuba.py`][78]) is written in Python 3. - -For more information about the shell scripts, see [POSIX Shell Scripts][76]. - -#### `afl.py` - -This script is meant to be used as part of the fuzzing workflow. - -It does one of two things: checks for valid crashes, or runs `bc` and or `dc` -under all of the paths found by [AFL++][125]. - -See [Fuzzing][82] for more information about fuzzing, including this script. - -#### `alloc.sh` - -This script is a quick and dirty script to test whether or not the garbage -collection mechanism of the [`BcNum` caching][96] works. It has been little-used -because it tests something that is not important to correctness. - -#### `benchmark.sh` - -A script making it easy to run benchmarks and to run the executable produced by -[`ministat.c`][223] on them. - -For more information, see the [Benchmarks][144] section. - -#### `bitfuncgen.c` - -A source file for an executable to generate tests for `bc`'s bitwise functions -in [`gen/lib2.bc`][26]. The executable is `scripts/bitfuncgen`, and it is built -with `make bitfuncgen`. It produces the test on `stdout` and the expected -results on `stderr`. This means that to generat tests, use the following -invokation: - -``` -scripts/bitfuncgen > tests/bc/bitfuncs.txt 2> tests/bc/bitfuncs_results.txt -``` - -It calls `abort()` if it runs into an error. - -#### `exec-install.sh` - -This script is the magic behind making sure `dc` is installed properly if it's -a symlink to `bc`. It checks to see if it is a link, and if so, it just creates -a new symlink in the install directory. Of course, it also installs `bc` itself, -or `dc` when it's alone. - -#### `functions.sh` - -This file is a bunch of common functions for most of the POSIX shell scripts. It -is not supposed to be run; instead, it is *sourced* by other POSIX shell -scripts, like so: - -``` -. "$scriptdir/functions.sh" -``` - -or the equivalent, depending on where the sourcing script is. - -For more information about the shell scripts, see [POSIX Shell Scripts][76]. - -#### `fuzz_prep.sh` - -Fuzzing is a regular activity when I am preparing for a release. - -This script handles all the options and such for building a fuzzable binary. -Instead of having to remember a bunch of options, I just put them in this script -and run the script when I want to fuzz. - -For more information about fuzzing, see [Fuzzing][82]. - -#### `karatsuba.py` - -This script has at least one of two major differences from most of the other -scripts: - -* It's written in Python 3. -* It's meant for software packagers. - -For example, [`scripts/afl.py`][94] and [`scripts/randmath.py`][95] are both in -Python 3, but they are not meant for the end user or software packagers and are -not included in source distributions. But this script is. - -This script breaks my rule of only POSIX utilities necessary for package -maintainers, but there's a very good reason for that: it's only meant to be run -*once* when the package is created for the first time, and maybe not even then. - -You see, this script does two things: it tests the Karatsuba implementation at -various settings for `KARATSUBA_LEN`, and it figures out what the optimal -`KARATSUBA_LEN` is for the machine that it is running on. - -Package maintainers can use this script, when creating a package for this `bc`, -to figure out what is optimal for their users. Then they don't have to run it -ever again. So this script only has to run on the packagers machine. - -I tried to write the script in `sh`, by the way, and I finally accepted the -tradeoff of using Python 3 when it became too hard. - -However, I also mentioned that it's for testing Karatsuba with various settings -of `KARATSUBA_LEN`. Package maintainers will want to run the [test suite][124], -right? - -Yes, but this script is not part of the [test suite][124]; it's used for testing -in the [`scripts/release.sh`][83] script, which is maintainer use only. - -However, there is one snare with `karatsuba.py`: I didn't want the user to have -to install any Python libraries to run it. Keep that in mind if you change it. - -#### `link.sh` - -This script is the magic behind making `dc` a symlink of `bc` when both -calculators are built. - -#### `locale_install.sh` - -This script does what its name says: it installs locales. - -It turns out that this is complicated. - -There is a magic environment variable, `$NLSPATH`, that tells you how and where -you are supposed to install locales. - -Yes, *how*. And where. - -But now is not the place to rant about `$NLSPATH`. For more information on -locales and `$NLSPATH`, see [Locales][85]. - -#### `locale_uninstall.sh` - -This script does what its name says: it uninstalls locales. - -This is far less complicated than installing locales. I basically generate a -wildcard path and then list all paths that fit that wildcard. Then I delete each -one of those paths. Easy. - -For more information on locales, see [Locales][85]. - -#### `manpage.sh` - -This script is the one that generates markdown manuals from a template and a -manpage from a markdown manual. - -For more information about generating manuals, see [Manuals][86]. - -#### `ministat.c` - -This is a file copied [from FreeBSD][221] that calculates the standard -statistical numbers, such as mean, average, and median, based on numbers -obtained from a file. - -For more information, see the [FreeBSD ministat(1) manpage][222]. - -This file allows `bc` to build the `scripts/ministat` executable using the -command `make ministat`, and this executable helps programmers evaluate the -results of [benchmarks][144] more accurately. - -#### `package.sh` - -This script is what helps `bc` maintainers cut a release. It does the following: - -1.	Creates the appropriate `git` tag. -2.	Pushes the `git` tag. -3.	Copies the repo to a temp directory. -4.	Removes files that should not be included in source distributions. -5.	Creates the tarballs. -6.	Signs the tarballs. -7.	Zips and signs the Windows executables if they exist. -8.	Calculates and outputs SHA512 and SHA256 sums for all of the files, -	including the signatures. - -This script is for `bc` maintainers to use when cutting a release. It is not -meant for outside use. This means that some non-POSIX utilities can be used, -such as `git` and `gpg`. - -In addition, before using this script, it expects that the folders that Windows -generated when building `bc`, `dc`, and [`bcl`][156], are in the parent -directory of the repo, exactly as Windows generated them. If they are not there, -then it will not zip and sign, nor calculate sums of, the Windows executables. - -Because this script creates a tag and pushes it, it should *only* be run *ONCE* -per release. - -#### `radamsa.sh` - -A script to test `bc`'s command-line expression parsing code, which, while -simple, strives to handle as much as possible. - -What this script does is it uses the test cases in [`radamsa.txt`][98] an input -to the [Radamsa fuzzer][99]. - -For more information, see the [Radamsa][128] section. - -#### `radamsa.txt` - -Initial test cases for the [`radamsa.sh`][100] script. - -#### `randmath.py` - -This script generates random math problems and checks that `bc`'s and `dc`'s -output matches the GNU `bc` and `dc`. (For this reason, it is necessary to have -GNU `bc` and `dc` installed before using this script.) - -One snare: be sure that this script is using the GNU `bc` and `dc`, not a -previously-installed version of this `bc` and `dc`. - -If you want to check for memory issues or failing asserts, you can build the -`bc` using `./scripts/fuzz_prep.sh -a`, and then run it under this script. Any -errors or crashes should be caught by the script and given to the user as part -of the "checklist" (see below). - -The basic idea behind this script is that it generates as many math problems as -it can, biasing towards situations that may be likely to have bugs, and testing -each math problem against GNU `bc` or `dc`. - -If GNU `bc` or `dc` fails, it just continues. If this `bc` or `dc` fails, it -stores that problem. If the output mismatches, it also stores the problem. - -Then, when the user sends a `SIGINT`, the script stops testing and goes into -report mode. One-by-one, it will go through the "checklist," the list of failed -problems, and present each problem to the user, as well as whether this `bc` or -`dc` crashed, and its output versus GNU. Then the user can decide to add them as -test cases, which it does automatically to the appropriate test file. - -#### `release_settings.txt` - -A text file of settings combinations that [`release.sh`][83] uses to ensure that -`bc` and `dc` build and work with various default settings. [`release.sh`][83] -simply reads it line by line and uses each line for one build. - -#### `release.sh` - -This script is for `bc` maintainers only. It runs `bc`, `dc`, and [`bcl`][156] -through a gauntlet that is mostly meant to be used in preparation for a release. - -It does the following: - -1.	Builds every [build type][81], with every setting combo in -	[`release_settings.txt`][93] with both calculators, `bc` alone, and `dc` -	alone. -2.	Builds every [build type][81], with every setting combo in -	[`release_settings.txt`][93] with both calculators, `bc` alone, and `dc` -	alone for 32-bit. -3.	Does #1 and #2 for Debug, Release, Release with Debug Info, and Min Size -	Release builds. -4.	Runs the [test suite][124] on every build, if desired. -5.	Runs the [test suite][124] under [ASan, UBSan, and MSan][21] for every build -	type/setting combo. -6.	Runs [`scripts/karatsuba.py`][78] in test mode. -7.	Runs the [test suite][124] for both calculators, `bc` alone, and `dc` alone -	under [valgrind][20] and errors if there are any memory bugs or memory -	leaks. - -#### `safe-install.sh` - -A script copied from [musl][101] to atomically install files. - -#### `test_settings.sh` - -A quick and dirty script to help automate rebuilding while manually testing the -various default settings. - -This script uses [`test_settings.txt`][103] to generate the various settings -combos. - -For more information about settings, see [Settings][102] in the [build -manual][14]. - -#### `test_settings.txt` - -A list of the various settings combos to be used by [`test_settings.sh`][104]. - -### `src/` - -This folder is, obviously, where the actual heart and soul of `bc`, the source -code, is. - -All of the source files are in one folder; this simplifies the build system -immensely. - -There are separate files for `bc` and `dc` specific code ([`bc.c`][40], -[`bc_lex.c`][41], [`bc_parse.c`][42], [`dc.c`][44], [`dc_lex.c`][45], and -[`dc_parse.c`][46]) where possible because it is cleaner to exclude an entire -source file from a build than to have `#if`/`#endif` preprocessor guards. - -That said, it was easier in many cases to use preprocessor macros where both -calculators used much of the same code and data structures, so there is a -liberal sprinkling of them through the code. - -#### `args.c` - -Code for processing command-line arguments. - -The header for this file is [`include/args.h`][31]. - -#### `bc.c` - -The code for the `bc` main function `bc_main()`. - -The header for this file is [`include/bc.h`][106]. - -#### `bc_lex.c` - -The code for lexing that only `bc` needs. - -The headers for this file are [`include/lex.h`][180] and [`include/bc.h`][106]. - -#### `bc_parse.c` - -The code for parsing that only `bc` needs. This code is the most complex and -subtle in the entire codebase. - -The headers for this file are [`include/parse.h`][181] and -[`include/bc.h`][106]. - -#### `data.c` - -Due to [historical accident][23] because of a desire to get my `bc` into -[toybox][16], all of the constant data that `bc` needs is all in one file. This -is that file. - -There is no code in this file, but a lot of the const data has a heavy influence -on code, including the order of data in arrays because that order has to -correspond to the order of other things elsewhere in the codebase. If you change -the order of something in this file, run `make test`, and get errors, you -changed something that depends on the order that you messed up. - -Almost all headers have `extern` references to items in this file. - -#### `dc.c` - -The code for the `dc` main function `dc_main()`. - -The header for this file is [`include/dc.h`][182]. - -#### `dc_lex.c` - -The code for lexing that only `dc` needs. - -The headers for this file are [`include/lex.h`][180] and [`include/dc.h`][182]. - -#### `dc_parse.c` - -The code for parsing that only `dc` needs. - -The headers for this file are [`include/parse.h`][181] and -[`include/bc.h`][182]. - -#### `file.c` - -The code for `bc`'s implementation of buffered I/O. For more information about -why I implemented my own buffered I/O, see [`include/file.h`][55], [Error -Handling][97], and [Custom I/O][114], along with [`status.h`][176] and the notes -about version [`3.0.0`][32] in the [`NEWS`][32]. - -The header for this file is [`include/file.h`][55]. - -#### `history.c` - -The code for `bc`'s implementation of command-line editing/history, which is -based on a [UTF-8-aware fork][28] of [`linenoise`][29]. - -For more information, see the [Command-Line History][189] section. - -The header for this file is [`include/history.h`][36]. - -#### `lang.c` - -The data structures used for actual execution of `bc` and `dc` code. - -While execution is done in [`src/program.c`][53], this file defines functions -for initializing, copying, and freeing the data structures, which is somewhat -orthogonal to actual execution. - -Yes, it's misnamed; that's an accident of history where the first things I put -into it all seemed related to the `bc` language. - -The header for this file is [`include/lang.h`][38]. - -#### `lex.c` - -The code for the common things that both programs need for lexing. - -The header for this file is [`include/lex.h`][180]. - -#### `library.c` - -The code to implement the public API of the `bcl` library. - -The code in this file does a lot to ensure that clients do not have to worry -about internal `bc` details, especially error handling with `setjmp()` and -`longjmp()`. That and encapsulating the handling of numbers are the bulk of what -the code in this file actually does because most of the library is still -implemented in [`src/num.c`][39]. - -The headers for this file are [`include/bcl.h`][30] and -[`include/library.h`][183]. - -#### `main.c` - -The entry point for both programs; this is the `main()` function. - -This file has no headers associated with it. - -#### `num.c` - -The code for all of the arbitrary-precision [numbers][177] and [math][178] in -`bc`. - -The header for this file is [`include/num.h`][184]. - -#### `opt.c` - -The code for parsing command-line options. - -The header for this file is [`include/opt.h`][35]. - -#### `parse.c` - -The code for the common items that both programs need for parsing. - -The header for this file is [`include/parse.h`][181]. - -#### `program.c` - -The code for the actual execution engine for `bc` and `dc` code. - -The header for this file is [`include/program.h`][57]. - -#### `rand.c` - -The code for the [pseudo-random number generator (PRNG)][179] and the special -stack handling it needs. - -The PRNG only generates fixed-size integers. The magic of generating random -numbers of arbitrary size is actually given to the code that does math -([`src/num.c`][39]). - -The header for this file is [`include/rand.h`][37]. - -#### `read.c` - -The code for reading from files and `stdin`. - -The header for this file is [`include/read.h`][185]. - -#### `vector.c` - -The code for [vectors][111], [maps][186], and [slab vectors][187], along with -slabs. - -The header for this file is [`include/vector.h`][174]. - -#### `vm.c` - -The code for setting up and running `bc` and `dc`. - -It is so named because I think of it as the "virtual machine" of `bc`, though -that is probably not true as [`program.h`][57] is probably the "virtual machine" -code. Thus, the name is more historical accident. - -The header for this file is [`include/vm.h`][27]. - -### `tests/` - -This directory contains the entire [test suite][124] and its infrastructure. - -#### `all.sh` - -A convenience script for the `make run_all_tests` target (see the [Group -Tests][141] section for more information). - -#### `all.txt` - -The file with the names of the calculators. This is to make it easier for the -test scripts to know where the standard and other test directories are. - -#### `bcl.c` - -The test for the [`bcl`][156] API. For more information, see the [`bcl` -Test][157] section. - -#### `error.sh` - -The script to run the file-based error tests in `tests/<calculator>/errors/` for -each calculator. For more information, see the [Error Tests][151] section. - -This is a separate script so that each error file can be run separately and in -parallel. - -#### `errors.sh` - -The script to run the line-based error tests in `tests/<calculator>/errors.txt` -for each calculator. For more information, see the [Error Tests][151] section. - -#### `extra_required.txt` - -The file with the list of tests which both calculators have that need the [Extra -Math build option][188]. This exists to make it easy for test scripts to skip -those tests when the [Extra Math build option][188] is disabled. - -#### `history.py` - -The file with all of the history tests. For more information, see the [History -Tests][155] section. - -#### `history.sh` - -The script to integrate [`history.py`][139] into the build system in a portable -way, and to skip it if necessary. - -This script also re-runs the test three times if it fails. This is because -`pexpect` can be flaky at times. - -#### `other.sh` - -The script to run the "other" (miscellaneous) tests for each calculator. For -more information, see the [Other Tests][154] section. - -#### `read.sh` - -The script to run the read tests for each calculator. For more information, see -the [`read()` Tests][153] section. - -#### `script.sed` - -The `sed` script to edit the output of GNU `bc` when generating script tests. -For more information, see the [Script Tests][150] section. - -#### `script.sh` - -The script for running one script test. For more information, see the [Script -Tests][150] section. - -#### `scripts.sh` - -The script to help the `make run_all_tests` (see the [Group Tests][141] section) -run all of the script tests. - -#### `stdin.sh` - -The script to run the `stdin` tests for each calculator. For more information, -see the [`stdin` Tests][152] section. - -#### `test.sh` - -The script to run one standard test. For more information, see the [Standard -Tests][149] section. - -#### `bc/` - -The standard tests directory for `bc`. For more information, see the [Standard -Tests][149] section. - -##### `all.txt` - -The file to tell the build system and `make run_all_tests` (see the [Group -Tests][141] section) what standard tests to run for `bc`, as well as in what -order. - -This file just lists the test names, one per line. - -##### `errors.txt` - -The initial error test file for `bc`. This file has one test per line. See the -[Error Tests][151] section for more information. - -##### `posix_errors.txt` - -The file of tests for POSIX compatibility for `bc`. This file has one test per -line. For more information, see the [Error Tests][151] section. - -##### `timeconst.sh` - -The script to run the `bc` tests that use the [Linux `timeconst.bc` script][6]. -For more information, see the [Linux `timeconst.bc` Script][191]section. - -##### `errors/` - -The directory with error tests for `bc`, most discovered by AFL++ (see the -[Fuzzing][82] section). There is one test per file. For more information, see -the [Error Tests][151] section. - -##### `scripts/` - -The script tests directory for `bc`. For more information, see the [Script -Tests][150] section. - -###### `all.txt` - -A file to tell the build system and `make run_all_tests` (see the [Group -Tests][141] section) what script tests to run for `bc`, as well as in what -order. - -This file just lists the test names, one per line. - -#### `dc/` - -The standard tests directory for `dc`. For more information, see the [Standard -Tests][149] section. - -##### `all.txt` - -The file to tell the build system and `make run_all_tests` (see the [Group -Tests][141] section) what standard tests to run for `dc`, as well as in what -order. - -This file just lists the test names, one per line. - -##### `errors.txt` - -The initial error test file for `dc`. This file has one test per line. See the -[Error Tests][151] section for more information. - -##### `read_errors.txt` - -The file of tests errors with the `?` command (`read()` in `bc`). This file has -one test per line. See the [Error Tests][151] section for more information. - -##### `errors/` - -The directory with error tests for `dc`, most discovered by AFL++ (see the -[Fuzzing][82] section). There is one test per file. For more information, see -the [Error Tests][151] section. - -##### `scripts/` - -The script tests directory for `dc`. For more information, see the [Script -Tests][150] section. - -###### `all.txt` - -The file to tell the build system and `make run_all_tests` (see the [Group -Tests][141] section) what script tests to run for `dc`, as well as in what -order. - -This file just lists the test names, one per line. - -#### `fuzzing/` - -The directory containing the fuzzing infrastructure. For more information, see -the [Fuzzing][82] section. - -##### `bc_afl_continue.yaml` - -The [`tmuxp`][123] config (for use with [`tmux`][122]) for easily restarting a -fuzz run. For more information, see the [Convenience][130] subsection of the -[Fuzzing][82] section. - -##### `bc_afl.yaml` - -The [`tmuxp`][123] config (for use with [`tmux`][122]) for easily starting a -fuzz run. For more information, see the [Convenience][130] subsection of the -[Fuzzing][82] section. - -Be aware that this will delete all previous unsaved fuzzing tests in the output -directories. - -##### `bc_inputs1/` - -The fuzzing input directory for the first third of inputs for `bc`. For more -information, see the [Corpuses][192] subsection of the [Fuzzing][82] section. - -##### `bc_inputs2/` - -The fuzzing input directory for the second third of inputs for `bc`. For more -information, see the [Corpuses][192] subsection of the [Fuzzing][82] section. - -##### `bc_inputs3/` - -The fuzzing input directory for the third third of inputs for `bc`. For more -information, see the [Corpuses][192] subsection of the [Fuzzing][82] section. - -##### `dc_inputs/` - -The fuzzing input directory for the inputs for `dc`. For more information, see -the [Corpuses][192] subsection of the [Fuzzing][82] section. - -### `vs/` - -The directory containing all of the materials needed to build `bc`, `dc`, and -`bcl` on Windows. - -#### `bcl.sln` - -A Visual Studio solution file for [`bcl`][156]. This, along with -[`bcl.vcxproj`][63] and [`bcl.vcxproj.filters`][64] is what makes it possible to -build [`bcl`][156] on Windows. - -#### `bcl.vcxproj` - -A Visual Studio project file for [`bcl`][156]. This, along with [`bcl.sln`][65] -and [`bcl.vcxproj.filters`][64] is what makes it possible to build [`bcl`][156] -on Windows. - -#### `bcl.vcxproj.filters` - -A Visual Studio filters file for [`bcl`][156]. This, along with [`bcl.sln`][65] -and [`bcl.vcxproj`][63] is what makes it possible to build [`bcl`][156] on -Windows. - -#### `bc.sln` - -A Visual Studio solution file for `bc`. This, along with [`bc.vcxproj`][66] -and [`bc.vcxproj.filters`][67] is what makes it possible to build `bc` on -Windows. - -#### `bc.vcxproj` - -A Visual Studio project file for `bc`. This, along with [`bc.sln`][68] and -[`bc.vcxproj.filters`][67] is what makes it possible to build `bc` on Windows. - -#### `bc.vcxproj.filters` - -A Visual Studio filters file for `bc`. This, along with [`bc.sln`][68] and -[`bc.vcxproj`][66] is what makes it possible to build `bc` on Windows. - -#### `tests/` - -A directory of files to run tests on Windows. - -##### `tests_bc.bat` - -A file to run basic `bc` tests on Windows. It expects that it will be run from -the directory containing it, and it also expects a `bc.exe` in the same -directory. - -##### `tests_dc.bat` - -A file to run basic `dc` tests on Windows. It expects that it will be run from -the directory containing it, and it also expects a `bc.exe` in the same -directory. - -## Build System - -The build system is described in detail in the [build manual][14], so -maintainers should start there. This section, however, describes some parts of -the build system that only maintainers will care about. - -### Clean Targets - -`bc` has a default `make clean` target that cleans up the build files. However, -because `bc`'s build system can generate many different types of files, there -are other clean targets that may be useful: - -* `make clean_gen` cleans the `gen/strgen` executable generated from -  [`gen/strgen.c`][15]. It has no prerequisites. -* `make clean` cleans object files, `*.cat` files (see the [Locales][85] -  section), executables, and files generated from text files in [`gen/`][145], -  including `gen/strgen` if it was built. So this has a prerequisite on -  `make clean_gen` in normal use. -* `make clean_benchmarks` cleans [benchmarks][144], including the `ministat` -  executable. It has no prerequisites. -* `make clean_config` cleans the generated `Makefile` and the manuals that -  [`configure.sh`][69] copied in preparation for install. It also depends on -  `make clean` and `make clean_benchmarks`, so it cleans those items too. This -  is the target that [`configure.sh`][69] uses before it does its work. -* `make clean_coverage` cleans the generated coverage files for the [test -  suite][124]'s [code coverage][146] capabilities. It has no prerequisites. This -  is useful if the code coverage tools are giving errors. -* `make clean_tests` cleans *everything*. It has prerequisites on all previous -  clean targets, but it also cleans all of the [generated tests][143]. - -When adding more generated files, you may need to add them to one of these -targets and/or add a target for them especially. - -### Preprocessor Macros - -`bc` and `dc` use *a lot* of preprocessor macros to ensure that each build type: - -* builds, -* works under the [test suite][124], and -* excludes as much code as possible from all builds. - -This section will explain the preprocessor style of `bc` and `dc`, as well as -provide an explanation of the macros used. - -#### Style - -The style of macro use in `bc` is pretty straightforward: I avoid depending on -macro definitions and instead, I set defaults if the macro is not defined and -then test the value if the macro with a plain `#if`. - -(Some examples of setting defaults are in [`include/status.h`][176], just above -the definition of the `BcStatus` enum.) - -In other words, I use `#if` instead of `#ifndef` or `#ifdef`, where possible. - -There are a couple of cases where I went with standard stuff instead. For -example, to test whether I am in debug mode or not, I still use the standard -`#ifndef NDEBUG`. - -#### Standard Macros - -`BC_ENABLED` - -:   This macro expands to `1` if `bc` is enabled, `0` if disabled. - -`DC_ENABLED` - -:   This macro expands to `1` if `dc` is enabled, `0` if disabled. - -`BUILD_TYPE` - -:   The macro expands to the build type, which is one of: `A`, `E`, `H`, `N`, -    `EH`, `EN`, `HN`, `EHN`. This build type is used in the help text to direct -    the user to the correct markdown manual in the `git.yzena.com` website. - -`EXECPREFIX` - -:   This macro expands to the prefix on the executable name. This is used to -    allow `bc` and `dc` to skip the prefix when finding out which calculator is -    executing. - -`BC_NUM_KARATSUBA_LEN` - -:   This macro expands to an integer, which is the length of numbers below which -    the Karatsuba multiplication algorithm switches to brute-force -    multiplication. - -`BC_ENABLE_EXTRA_MATH` - -:   This macro expands to `1` if the [Extra Math build option][188] is enabled, -    `0` if disabled. - -`BC_ENABLE_HISTORY` - -:   This macro expands to `1` if the [History build option][193] is enabled, `0` -    if disabled. - -`BC_ENABLE_NLS` - -:   This macro expands to `1` if the [NLS build option][193] (for locales) is -    enabled, `0` if disabled. - -`BC_ENABLE_LIBRARY` - -:   This macro expands to `1` if the [`bcl` library][156] is enabled, `0` if -    disabled. If this is enabled, building the calculators themselves is -    disabled, but both `BC_ENABLED` and `DC_ENABLED` must be non-zero. - -`BC_ENABLE_MEMCHECK` - -:   This macro expands to `1` if `bc` has been built for use with Valgrind's -    [Memcheck][194], `0` otherwise. This ensures that fatal errors still free -    all of their memory when exiting. `bc` does not do that normally because -    what's the point? - -`BC_ENABLE_AFL` - -:   This macro expands to `1` if `bc` has been built for fuzzing with -    [AFL++][125], `0` otherwise. See the [Fuzzing][82] section for more -    information. - -`BC_DEFAULT_BANNER` - -:   This macro expands to the default value for displaying the `bc` banner. - -`BC_DEFAULT_SIGINT_RESET` - -:   The macro expands to the default value for whether or not `bc` should reset -    on `SIGINT` or quit. - -`BC_DEFAULT_TTY_MODE` - -:   The macro expands to the default value for whether or not `bc` should use -    TTY mode when it available. - -`BC_DEFAULT_PROMPT` - -:   This macro expands to the default value for whether or not `bc` should use a -    prompt when TTY mode is available. - -`DC_DEFAULT_SIGINT_RESET` - -:   The macro expands to the default value for whether or not `dc` should reset -    on `SIGINT` or quit. - -`DC_DEFAULT_TTY_MODE` - -:   The macro expands to the default value for whether or not `dc` should use -    TTY mode when it available. - -`DC_DEFAULT_PROMPT` - -:   This macro expands to the default value for whether or not `dc` should use a -    prompt when TTY mode is available. - -`BC_DEBUG_CODE` - -:   If this macro expands to a non-zero integer, then `bc` is built with *a lot* -    of extra debugging code. This is never set by the build system and must be -    set by the programmer manually. This should never be set in builds given to -    end users. For more information, see the [Debugging][134] section. - -## Test Suite - -While the source code may be the heart and soul of `bc`, the test suite is the -arms and legs: it gives `bc` the power to do anything it needs to do. - -The test suite is what allowed `bc` to climb to such high heights of quality. -This even goes for fuzzing because fuzzing depends on the test suite for its -input corpuses. (See the [Fuzzing][82] section.) - -Understanding how the test suite works should be, I think, the first thing that -maintainers learn after learning what `bc` and `dc` should do. This is because -the test suite, properly used, gives confidence that changes have not caused -bugs or regressions. - -That is why I spent the time to make the test suite as easy to use and as fast -as possible. - -To use the test suite (assuming `bc` and/or `dc` are already built), run the -following command: - -``` -make test -``` - -That's it. That's all. - -It will return an error code if the test suite failed. It will also print out -information about the failure. - -If you want the test suite to go fast, then run the following command: - -``` -make -j<cores> test -``` - -Where `<cores>` is the number of cores that your computer has. Of course, this -requires a `make` implementation that supports that option, but most do. (And I -will use this convention throughout the rest of this section.) - -I have even tried as much as possible, to put longer-running tests near the -beginning of the run so that the entire suite runs as fast as possible. - -However, if you want to be sure which test is failing, then running a bare -`make test` is a great way to do that. - -But enough about how you have no excuses to use the test suite as much as -possible; let's talk about how it works and what you *can* do with it. - -### Standard Tests - -The heavy lifting of testing the math in `bc`, as well as basic scripting, is -done by the "standard tests" for each calculator. - -These tests use the files in the [`tests/bc/`][161] and [`tests/dc/`][162] -directories (except for [`tests/bc/all.txt`][163], [`tests/bc/errors.txt`][164], -[`tests/bc/posix_errors.txt`][165], [`tests/bc/timeconst.sh`][166], -[`tests/dc/all.txt`][167], [`tests/dc/errors.txt`][168], and -[`tests/dc/read_errors.txt`][175]), which are called the "standard test -directories." - -For every test, there is the test file and the results file. The test files have -names of the form `<test>.txt`, where `<test>` is the name of the test, and the -results files have names of the form `<test>_results.txt`. - -If the test file exists but the results file does not, the results for that test -are generated by a GNU-compatible `bc` or `dc`. See the [Generated Tests][143] -section. - -The `all.txt` file in each standard tests directory is what tells the test suite -and [build system][142] what tests there are, and the tests are either run in -that order, or in the case of parallel `make`, that is the order that the -targets are listed as prerequisites of `make test`. - -If the test exists in the `all.txt` file but does not *actually* exist, the test -and its results are generated by a GNU-compatible `bc` or `dc`. See the -[Generated Tests][143] section. - -To add a non-generated standard test, do the following: - -* Add the test file (`<test>.txt` in the standard tests directory). -* Add the results file (`<test>_results.txt` in the standard tests directory). -  You can skip this step if just the results file needs to be generated. See the -  [Generated Tests][147] section for more information. -* Add the name of the test to the `all.txt` file in the standard tests -  directory, putting it in the order it should be in. If possible, I would put -  longer tests near the beginning because they will start running earlier with -  parallel `make`. I always keep `decimal` first, though, as a smoke test. - -If you need to add a generated standard test, see the [Generated Tests][147] -section for how to do that. - -Some standard tests need to be skipped in certain cases. That is handled by the -[build system][142]. See the [Integration with the Build System][147] section -for more details. - -In addition to all of the above, the standard test directory is not only the -directory for the standard tests of each calculator, it is also the parent -directory of all other test directories for each calculator. - -#### `bc` Standard Tests - -The list of current (17 July 2021) standard tests for `bc` is below: - -decimal - -:   Tests decimal parsing and printing. - -print - -:   Tests printing in every base from decimal. This is near the top for -    performance of parallel testing. - -parse - -:   Tests parsing in any base and outputting in decimal. This is near the top -    for performance of parallel testing. - -lib2 - -:   Tests the extended math library. This is near the top for performance of -    parallel testing. - -print2 - -:   Tests printing at the extreme values of `obase`. - -length - -:   Tests the `length()` builtin function. - -scale - -:   Tests the `scale()` builtin function. - -shift - -:   Tests the left (`<<`) and right (`>>`) shift operators. - -add - -:   Tests addition. - -subtract - -:   Tests subtraction. - -multiply - -:   Tests multiplication. - -divide - -:   Tests division. - -modulus - -:   Tests modulus. - -power - -:   Tests power (exponentiation). - -sqrt - -:   Tests the `sqrt()` (square root) builtin function. - -trunc - -:   Tests the truncation (`$`) operator. - -places - -:   Tests the places (`@`) operator. - -vars - -:   Tests some usage of variables. This one came from [AFL++][125] I think. - -boolean - -:   Tests boolean operators. - -comp - -:   Tests comparison operators. - -abs - -:   Tests the `abs()` builtin function. - -assignments - -:   Tests assignment operators, including increment/decrement operators. - -functions - -:   Tests functions, specifically function parameters being replaced before they -    themselves are used. See the comment in `bc_program_call()` about the last -    condition. - -scientific - -:   Tests scientific notation. - -engineering - -:   Tests engineering notation. - -globals - -:   Tests that assigning to globals affects callers. - -strings - -:   Tests strings. - -strings2 - -:   Tests string allocation in slabs, to ensure slabs work. - -letters - -:   Tests single and double letter numbers to ensure they behave differently. -    Single-letter numbers always be set to the same value, regardless of -    `ibase`. - -exponent - -:   Tests the `e()` function in the math library. - -log - -:   Tests the `l()` function in the math library. - -pi - -:   Tests that `bc` produces the right value of pi for numbers with varying -    `scale` values. - -arctangent - -:   Tests the `a()` function in the math library. - -sine - -:   Tests the `s()` function in the math library. - -cosine - -:   Tests the `c()` function in the math library. - -bessel - -:   Tests the `j()` function in the math library. - -arrays - -:   Test arrays. - -misc - -:   Miscellaneous tests. I named it this because at the time, I struggled to -    classify them, but it's really testing multi-line numbers. - -misc1 - -:   A miscellaneous test found by [AFL++][125]. - -misc2 - -:   A miscellaneous test found by [AFL++][125]. - -misc3 - -:   A miscellaneous test found by [AFL++][125]. - -misc4 - -:   A miscellaneous test found by [AFL++][125]. - -misc5 - -:   A miscellaneous test found by [AFL++][125]. - -misc6 - -:   A miscellaneous test found by [AFL++][125]. - -misc7 - -:   A miscellaneous test found by [AFL++][125]. - -void - -:   Tests void functions. - -rand - -:   Tests the pseudo-random number generator and its special stack handling. - -recursive_arrays - -:   Tested the slab vector undo ability in used in `bc_parse_name()` when it -    existed. Now used as a stress test. - -divmod - -:   Tests divmod. - -modexp - -:   Tests modular exponentiation. - -bitfuncs - -:   Tests the bitwise functions, `band()`, `bor()`, `bxor()`, `blshift()` and -    `brshift()` in [`gen/lib2.bc`][26]. - -leadingzero - -:   Tests the leading zero functionality and the `plz*()` and `pnlz*()` -    functions in [`gen/lib2.bc`][26]. - -#### `dc` Standard Tests - -The list of current (17 July 2021) standard tests for `dc` is below: - -decimal - -:   Tests decimal parsing and printing. - -length - -:   Tests the `length()` builtin function, including for strings and arrays. - -stack_len - -:   Tests taking the length of the results stack. - -stack_len - -:   Tests taking the length of the execution stack. - -add - -:   Tests addition. - -subtract - -:   Tests subtraction. - -multiply - -:   Tests multiplication. - -divide - -:   Tests division. - -modulus - -:   Tests modulus. - -divmod - -:   Tests divmod. - -power - -:   Tests power (exponentiation). - -sqrt - -:   Tests the `sqrt()` (square root) builtin function. - -modexp - -:   Tests modular exponentiation. - -boolean - -:   Tests boolean operators. - -negate - -:   Tests negation as a command and as part of numbers. - -trunc - -:   Tests the truncation (`$`) operator. - -places - -:   Tests the places (`@`) operator. - -shift - -:   Tests the left (`<<`) and right (`>>`) shift operators. - -abs - -:   Tests the `abs()` builtin function. - -scientific - -:   Tests scientific notation. - -engineering - -:   Tests engineering notation. - -vars - -:   Tests some usage of variables. This one came from [AFL++][125] I think. - -misc - -:   Miscellaneous tests. I named it this because at the time, I struggled to -    classify them. - -strings - -:   Tests strings. - -rand - -:   Tests the pseudo-random number generator and its special stack handling. - -exec_stack - -:   Tests the execution stack depth command. - -### Script Tests - -The heavy lifting of testing the scripting of `bc` is done by the "script tests" -for each calculator. - -These tests use the files in the [`tests/bc/scripts/`][169] and -[`tests/dc/scripts/`][170] directories (except for -[`tests/bc/scripts/all.txt`][171] and [`tests/dc/scripts/all.txt`][172]), which -are called the "script test directories." - -To add a script test, do the following: - -* Add the test file (`<test>.bc` or `<test>.dc` in the script tests directory). -* Add the results file (`<test>.txt` in the script tests directory). You can -  skip this step if just the results file needs to be generated. See the -  [Generated Tests][147] section for more information. -* Add the name of the test to the `all.txt` file in the script tests directory, -  putting it in the order it should be in. If possible, I would put longer tests -  near the beginning because they will start running earlier with parallel -  `make`. - -Some script tests need to be skipped in certain cases. That is handled by the -[build system][142]. See the [Integration with the Build System][147] section -for more details. - -Another unique thing about the script tests, at least for `bc`: they test the -`-g` and `--global-stacks` flags. This means that all of the script tests for -`bc` are written assuming the `-g` flag was given on the command-line - -There is one extra piece of script tests: [`tests/script.sed`][190]. This `sed` -script is used to remove an incompatibility with GNU `bc`. - -If there is only one more character to print at the end of `BC_LINE_LENGTH`, GNU -`bc` still prints a backslash+newline+digit combo. OpenBSD doesn't, which is -correct according to my reading of the `bc` spec, so my `bc` doesn't as well. - -The `sed` script edits numbers that end with just one digit on a line by itself -to put it on the same line as others. - -#### `bc` Script Tests - -The list of current (17 July 2021) script tests for `bc` is below: - -print.bc - -:   Tests printing even harder than the print standard test. - -multiply.bc - -:   Tests multiplication even harder than the multiply standard test. - -divide.bc - -:   Tests division even harder than the divide standard test. - -subtract.bc - -:   Tests subtraction even harder than the subtract standard test. - -add.bc - -:   Tests addition even harder than the add standard test. - -parse.bc - -:   Tests parsing even harder than the parse standard test. - -array.bc - -:   Tests arrays even harder than the arrays standard test. - -atan.bc - -:   Tests arctangent even harder than the arctangent standard test. - -bessel.bc - -:   Tests bessel even harder than the bessel standard test. - -functions.bc - -:   Tests functions even harder than the functions standard test. - -globals.bc - -:   Tests global stacks directly. - -len.bc - -:   Tests the `length()` builtin on arrays. - -rand.bc - -:   Tests the random number generator in the presence of global stacks. - -references.bc - -:   Tests functions with array reference parameters. - -screen.bc - -:   A random script provided by an early user that he used to calculate the size -    of computer screens - -strings2.bc - -:   Tests escaping in strings. - -ifs.bc - -:   Tests proper ending of `if` statements without `else` statements. - -ifs2.bc - -:   More tests proper ending of `if` statements without `else` statements. - -#### `dc` Script Tests - -The list of current (17 July 2021) script tests for `dc` is below: - -prime.dc - -:   Tests scripting by generating the first 100,000 primes. - -asciify.dc - -:   Tests the asciify command. - -stream.dc - -:   Tests the stream command. - -array.dc - -:   Tests arrays. - -else.dc - -:   Tests else clauses on conditional execution commands. - -factorial.dc - -:   Tests scripting with factorial. - -loop.dc - -:   Tests scripting by implementing loops. - -quit.dc - -:   Tests the quit command in the presence of tail calls. - -weird.dc - -:   A miscellaneous test. - -### Error Tests - -One of the most useful parts of the `bc` test suite, in my opinion, is the heavy -testing of error conditions. - -Just about every error condition I can think of is tested, along with many -machine-generated (by [AFL++][125]) ones. - -However, because the error tests will often return error codes, they require -different infrastructure from the rest of the test suite, which assumes that -the calculator under test will return successfully. A lot of that infrastructure -is in the [`scripts/functions.sh`][105] script, but it basically allows the -calculator to exit with an error code and then tests that there *was* an error -code. - -Besides returning error codes, error tests also ensure that there is output from -`stderr`. This is to make sure that an error message is always printed. - -The error tests for each calculator are spread through two directories, due to -historical accident. These two directories are the standard test directory (see -the [Standard Tests][149] section) and the `errors/` directory directly -underneath the standard tests directory. - -This split is convenient, however, because the tests in each directory are -treated differently. - -The error tests in the standard test directory, which include `errors.txt` for -both calculators, `posix_errors.txt` for `bc`, and `read_errors.txt` for `dc`, -are run by [`tests/errors.sh`][226]. It reads them line-by-line and shoves the -data through `stdin`. Each line is considered a separate test. For this reason, -there can't be any blank lines in the error files in the standard tests -directory because a blank line causes a successful exit. - -On the other hand, the tests in the `errors/` directory below the standard tests -directory are run by [`tests/error.sh`][227] and are considered to be one test -per file. As such, they are used differently. They are shoved into the -calculator through `stdin`, but they are also executed by passing them on the -command-line. - -To add an error test, first figure out which kind you want. - -Is it a simple one-liner, and you don't care if it's tested through a file? - -Then put it in one of the error files in the standard test directory. I would -only put POSIX errors in the `posix_errors.txt` file for `bc`, and only `read()` -errors in the `read_errors.txt` file for `dc`; all others I would put in the -respective `errors.txt` file. - -On the other hand, if you care if the error is run as a file on the -command-line, or the error requires multiple lines to reproduce, then put the -test in the respective `errors/` directory and run the [`configure.sh`][69] -script again. - -After that, you are done; the test suite will automatically pick up the new -test, and you don't have to tell the test suite the expected results. - -### `stdin` Tests - -The `stdin` tests specifically test the lexing and parsing of multi-line -comments and strings. This is important because when reading from `stdin`, the -calculators can only read one line at a time, so partial parses are possible. - -To add `stdin` tests, just add the tests to the `stdin.txt` file in the -respective standard tests directory, and add the expected results in the -`stdin_results.txt` in the respective standard tests directory. - -### `read()` Tests - -The `read()` tests are meant to test the `read()` builtin function, to ensure -that the parsing and execution is correct. - -Each line is one test, as that is the nature of using the `read()` function, so -to add a test, just add it as another line in the `read.txt` file in the -respective standard tests directory, and add its result to the -`read_results.txt` file in the respective standard tests directory. - -### Other Tests - -The "other" tests are just random tests that I could not easily classify under -other types of tests. They usually include things like command-line parsing and -environment variable testing. - -To add an other test, it requires adding the programming for it to -[`tests/other.sh`][195] because all of the tests are written specifically in -that script. It would be best to use the infrastructure in -[`scripts/functions.sh`][105]. - -### Linux `timeconst.bc` Script - -One special script that `bc`'s test suite will use is the [Linux `timeconst.bc` -script][6]. - -I made the test suite able to use this script because the reason the -[toybox][16] maintainer wanted my `bc` is because of this script, and I wanted -to be sure that it would run correctly on the script. - -However, it is not part of the distribution, nor is it part of the repository. -The reason for this is because [`timeconst.bc`][6] is under the GPL, while this -repo is under a BSD license. - -If you want `bc` to run tests on [`timeconst.bc`][6], download it and place it -at `tests/bc/scripts/timeconst.bc`. If it is there, the test suite will -automatically run its tests; otherwise, it will skip it. - -### History Tests - -There are automatic tests for history; however, they have dependencies: Python 3 -and [`pexpect`][137]. - -As a result, because I need the [test suite to be portable][138], like the rest -of `bc`, the history tests are carefully guarded with things to ensure that they -are skipped, rather than failing if Python and [`pexpect`][137] are not -installed. For this reason, there is a `sh` script, [`tests/history.sh`][140] -that runs the actual script, [`tests/history.py`][139]. - -I have added as many tests as I could to cover as many lines and branches as -possible. I guess I could have done more, but doing so would have required a lot -of time. - -I have tried to make it as easy as possible to run the history tests. They will -run automatically if you use the `make test_history` command, and they will also -use parallel execution with `make -j<cores> test_history`. - -However, the history tests are meant only to be run by maintainers of `bc`; they -are *not* meant to be run by users and packagers. The reason for this is that -they only seem to work reliably on Linux; `pexpect` seems to have issues on -other platforms, especially timeout issues. - -Thus, they are excluded from running with `make test` and [`tests/all.sh`][225]. -However, they can be run from the [`scripts/release.sh`][83] script. - -All of the tests are contained in [`tests/history.py`][139]. The reason for this -is because they are in Python, and I don't have an easy way of including Python -(or at the very least, I am not familiar enough with Python to do that). So they -are all in the same file to make it easier on me. - -Each test is one function in the script. They all take the same number and type -of arguments: - -1.	`exe`: the executable to run. -2.	`args`: the arguments to pass to the executable. -3.	`env`: the environment. - -Each function creates a child process with `pexpect.spawn` and then tests with -that child. Then the function returns the child to the caller, who closes it -and checks its error code against its expected error code. - -Yes, the error code is not a success all the time. This is because of the UTF-8 -tests; `bc` gives a fatal error on any non-ASCII data because ASCII is all `bc` -is required to handle, per the [standard][2]. - -So in [`tests/history.py`][139], there are four main arrays: - -* `bc` test functions, -* `bc` expected error codes. -* `dc` test functions. -* `dc` expected error codes. - -[`tests/history.py`][139] takes an index as an argument; that index is what test -it should run. That index is used to index into the proper test and error code -array. - -If you need to add more history tests, you need to do the following: - -1.	Add the function for that test to [`tests/history.py`][139]. -2.	Add the function to the proper array of tests. -3.	Add the expected error code to the proper array of error codes. -4.	Add a target for the test to [`Makefile.in`][70]. -5.	Add that target as a prerequisite to either `test_bc_history` or -	`test_dc_history`. - -You do not need to do anything to add the test to `history_all_tests` (see -[Group Tests][141] below) because the scripts will automatically run all of the -tests properly. - -### Generated Tests - -Some tests are *large*, and as such, it is impractical to check them into `git`. -Instead, the tests depend on the existence of a GNU-compatible `bc` in the -`PATH`, which is then used to generate the tests. - -If [`configure.sh`][69] was run with the `-G` argument, which disables generated -tests, then `make test` and friends will automatically skip generated tests. -This is useful to do on platforms that are not guaranteed to have a -GNU-compatible `bc` installed. - -However, adding a generated test is a complicated because you have to figure out -*where* you want to put the file to generate the test. - -For example, `bc`'s test suite will automatically use a GNU-compatible `bc` to -generate a `<test>_results.txt` file in the [standard tests][149] directory -(either `tests/bc/` or `tests/dc/`) if none exists for the `<test>` test. If no -`<test>.txt` file exists in the [standard tests][149] directory, then `bc`'s -test suite will look for a `<test>.bc` or `<test>.dc` file in the [script -tests][150] directory (either `tests/bc/scripts` or `tests/dc/scripts`), and if -that exists, it will use that script to generate the `<test>.txt` file in the -[standard tests][149] directory after which it will generate the -`<test>_results.txt` file in the [standard tests][149] directory. - -So you can choose to either: - -* Have a test in the [standard tests][149] directory without a corresponding -  `*_results.txt` file, or -* Have a script in the [script tests][150] directory to generate the -  corresponding file in the standard test directory before generating the -  corresponding `*_results.txt` file. - -Adding a script has a double benefit: the script itself can be used as a test. -However, script test results can also be generated. - -If `bc` is asked to run a script test, then if the script does not exist, `bc`'s -test suite returns an error. If it *does* exist, but no corresponding -`<test>.txt` file exists in the [script tests][150] directory, then a -GNU-compatible `bc` is used to generate the `<test>.txt` results file. - -If generated tests are disabled through [`configure.sh`][69], then these tests -are not generated if they do not exist. However, if they *do* exist, then they -are run. This can happen if a `make clean_tests` was not run between a build -that generated tests and a build that will not. - -### Group Tests - -While the test suite has a lot of targets in order to get parallel execution, -there are five targets that allow you to run each section, or all, of the test -suite as one unit: - -* `bc_all_tests` (`bc` tests) -* `timeconst_all_tests` ([Linux `timeconst.bc` script][6] tests) -* `dc_all_tests` (`dc` tests) -* `history_all_tests` (history tests) -* `run_all_tests` (combination of the previous four) - -In addition, there are more fine-grained targets available: - -* `test_bc` runs all `bc` tests (except history tests). -* `test_dc` runs all `dc` tests (except history tests). -* `test_bc_tests` runs all `bc` [standard tests][149]. -* `test_dc_tests` runs all `dc` [standard tests][149]. -* `test_bc_scripts` runs all `bc` [script tests][150]. -* `test_dc_scripts` runs all `dc` [script tests][150]. -* `test_bc_stdin` runs the `bc` [`stdin` tests][152]. -* `test_dc_stdin` runs the `dc` [`stdin` tests][152]. -* `test_bc_read` runs the `bc` [`read()` tests][153]. -* `test_dc_read` runs the `dc` [`read()` tests][153]. -* `test_bc_errors` runs the `bc` [error tests][151]. -* `test_dc_errors` runs the `dc` [error tests][151]. -* `test_bc_other` runs the `bc` [other tests][151]. -* `test_dc_other` runs the `dc` [other tests][151]. -* `timeconst` runs the tests for the [Linux `timeconst.bc` script][6]. -* `test_history` runs all history tests. -* `test_bc_history` runs all `bc` history tests. -* `test_dc_history` runs all `dc` history tests. - -All of the above tests are parallelizable. - -### Individual Tests - -In addition to all of the above, individual test targets are available. These -are mostly useful for attempting to fix a singular test failure. - -These tests are: - -* `test_bc_<test>`, where `<test>` is the name of a `bc` [standard test][149]. -  The name is the name of the test file without the `.txt` extension. It is the -  name printed by the test suite when running the test. -* `test_dc_<test>`, where `<test>` is the name of a `dc` [standard test][149]. -  The name is the name of the test file without the `.txt` extension. It is the -  name printed by the test suite when running the test. -* `test_bc_script_<test>`, where `<test>` is the name of a `bc` [script -  test][150]. The name of the test is the name of the script without the `.bc` -  extension. -* `test_dc_script_<test>`, where `<test>` is the name of a `dc` [script -  test][150]. The name of the test is the name of the script without the `.dc` -  extension. -* `test_bc_history<idx>` runs the `bc` history test with index `<idx>`. -* `test_dc_history<idx>` runs the `dc` history test with index `<idx>`. - -### [`bcl`][156] Test - -When [`bcl`][156] is built, the [build system][142] automatically ensures that -`make test` runs the [`bcl`][156] test instead of the `bc` and `dc` tests. - -There is only one test, and it is built from [`tests/bcl.c`][158]. - -The reason the test is in C is because [`bcl`][156] is a C library; I did not -want to have to write C code *and* POSIX `sh` scripts to run it. - -The reason there is only one test is because most of the code for the library is -tested by virtue of testing `bc` and `dc`; the test needs to only ensure that -the library bindings and plumbing do not interfere with the underlying code. - -However, just because there is only one test does not mean that it doesn't test -more than one thing. The code actually handles a series of tests, along with -error checking to ensure that nothing went wrong. - -To add a [`bcl`][156] test, just figure out what test you want, figure out where -in the [`tests/bcl.c`][158] would be best to put it, and put it there. Do as -much error checking as possible, and use the `err(BclError)` function. Ensure -that all memory is freed because that test is run through [Valgrind][159] and -[AddressSanitizer][160]. - -### Integration with the Build System - -If it was not obvious by now, the test suite is heavily integrated into the -[build system][142], but the integration goes further than just making the test -suite easy to run from `make` and generating individual and group tests. - -The big problem the test suite has is that some `bc` code, stuff that is -important to test, is only in *some* builds. This includes all of the extra math -extensions, for example. - -So the test suite needs to have some way of turning off the tests that depend on -certain [build types][81] when those [build types][81] are not used. - -This is the reason the is tightly integrated with the [build system][142]: the -[build system][142] knows what [build type][81] was used and can tell the test -suite to turn off the tests that do not apply. - -It does this with arguments to the test scripts that are either a `1` or a `0`, -depending on whether tests of that type should be enabled or not. These -arguments are why I suggest, in the [Test Scripts][148] section, to always use a -`make` target to run the test suite or any individual test. I have added a lot -of targets to make this easy and as fast as possible. - -In addition to all of that, the build system is responsible for selecting the -`bc`/`dc` tests or the [`bcl` test][157]. - -### Output Directories - -During any run of the test suite, the test suite outputs the results of running -various tests to files. These files are usually output to `tests/bc_outputs/` -and `tests/dc_outputs/`. - -However, in some cases, it may be necessary to output test results to a -different directory. If that is the case, set the environment variable -`BC_TEST_OUTPUT_DIR` to the name of the directory. - -If that is done, then test results will be written to -`$BC_TEST_OUTPUT_DIR/bc_outputs/` and `$BC_TEST_OUTPUT_DIR/dc_outputs/`. - -### Test Suite Portability - -The test suite is meant to be run by users and packagers as part of their -install process. - -This puts some constraints on the test suite, but the biggest is that the test -suite must be as [portable as `bc` itself][136]. - -This means that the test suite must be implemented in pure POSIX `make`, `sh`, -and C99. - -#### Test Scripts - -To accomplish the portability, the test suite is run by a bunch of `sh` scripts -that have the constraints laid out in [POSIX Shell Scripts][76]. - -However, that means they have some quirks, made worse by the fact that there are -[generated tests][143] and [tests that need to be skipped, but only -sometimes][147]. - -This means that a lot of the scripts take an awkward number and type of -arguments. Some arguments are strings, but most are integers, like -[`scripts/release.sh`][83]. - -It is for this reason that I do not suggest running the test scripts directly. -Instead, always use an appropriate `make` target, which already knows the -correct arguments for the test because of the [integration with the build -system][147]. - -### Test Coverage - -In order to get test coverage information, you need `gcc`, `gcov`, and `gcovr`. - -If you have them, run the following commands: - -``` -CC=gcc ./configure -gO3 -c -make -j<cores> -make coverage -``` - -Note that `make coverage` does not have a `-j<cores>` part; it cannot be run in -parallel. If you try, you will get errors. And note that `CC=gcc` is used. - -After running those commands, you can open your web browser and open the -`index.html` file in the root directory of the repo. From there, you can explore -all of the coverage results. - -If you see lines or branches that you think you could hit with a manual -execution, do such manual execution, and then run the following command: - -``` -make coverage_output -``` - -and the coverage output will be updated. - -If you want to rerun `make coverage`, you must do a `make clean` and build -first, like this: - -``` -make clean -make -j<cores> -make coverage -``` - -Otherwise, you will get errors. - -If you want to run tests in parallel, you can do this: - -``` -make -j<cores> -make -j<cores> test -make coverage_output -``` - -and that will generate coverage output correctly. - -### [AddressSanitizer][21] and Friends - -To run the test suite under [AddressSanitizer][21] or any of its friends, use -the following commands: - -``` -CFLAGS="-fsanitize=<sanitizer> ./configure -gO3 -m -make -j<cores> -make -j<cores> test -``` - -where `<sanitizer>` is the correct name of the desired sanitizer. There is one -exception to the above: `UndefinedBehaviorSanitizer` should be run on a build -that has zero optimization, so for `UBSan`, use the following commands: - -``` -CFLAGS="-fsanitize=undefined" ./configure -gO0 -m -make -j<cores> -make -j<cores> test -``` - -### [Valgrind][20] - -To run the test suite under [Valgrind][20], run the following commands: - -``` -./configure -gO3 -v -make -j<cores> -make -j<cores> test -``` - -It really is that easy. I have directly added infrastructure to the build system -and the test suite to ensure that if [Valgrind][20] detects any memory errors or -any memory leaks at all, it will tell the test suite infrastructure to report an -error and exit accordingly. - -## POSIX Shell Scripts - -There is a lot of shell scripts in this repository, and every single one of them -is written in pure [POSIX `sh`][72]. - -The reason that they are written in [POSIX `sh`][72] is for *portability*: POSIX -systems are only guaranteed to have a barebones implementation of `sh` -available. - -There are *many* snares for unwary programmers attempting to modify -[`configure.sh`][69], any of the scripts in this directory, [`strgen.sh`][9], or -any of the scripts in [`tests/`][77]. Here are some of them: - -1.	No `bash`-isms. -2.	Only POSIX standard utilities are allowed. -3.	Only command-line options defined in the POSIX standard for POSIX utilities -	are allowed. -4.	Only the standardized behavior of POSIX utilities is allowed. -5.	Functions return data by *printing* it. Using `return` sets their exit code. - -In other words, the script must only use what is standardized in the [`sh`][72] -and [Shell Command Language][73] standards in POSIX. This is *hard*. It precludes -things like `local` and the `[[ ]]` notation. - -These are *enormous* restrictions and must be tested properly. I put out at -least one release with a change to `configure.sh` that wasn't portable. That was -an embarrassing mistake. - -The lack of `local`, by the way, is why variables in functions are named with -the form: - -``` -_<function_name>_<var_name> -``` - -This is done to prevent any clashes of variable names with already existing -names. And this applies to *all* shell scripts. However, there are a few times -when that naming convention is *not* used; all of them are because those -functions are required to change variables in the global scope. - -### Maintainer-Only Scripts - -If a script is meant to be used for maintainers (of `bc`, not package -maintainers), then rules 2, 3, and 4 don't need to be followed as much because -it is assumed that maintainers will be able to install whatever tools are -necessary to do the job. - -## Manuals - -The manuals for `bc` and `dc` are all generated, and the manpages for `bc`, -`dc`, and `bcl` are also generated. - -Why? - -I don't like the format of manpages, and I am not confident in my ability to -write them. Also, they are not easy to read on the web. - -So that explains why `bcl`'s manpage is generated from its markdown version. But -why are the markdown versions of the `bc` and `dc` generated? - -Because the content of the manuals needs to change based on the [build -type][81]. For example, if `bc` was built with no history support, it should not -have the **COMMAND LINE HISTORY** section in its manual. If it did, that would -just confuse users. - -So the markdown manuals for `bc` and `dc` are generated from templates -([`manuals/bc.1.md.in`][89] and [`manuals/dc.1.md.in`][90]). And from there, -the manpages are generated from the generated manuals. - -The generated manpage for `bcl` ([`manuals/bcl.3`][62]) is checked into version -control, and the generated markdown manuals and manpages for `bc` -([`manuals/bc`][79]) and `dc` ([`manuals/dc`][80]) are as well. - -This is because generating the manuals and manpages requires a heavy dependency -that only maintainers should care about: [Pandoc][92]. Because users [should not -have to install *any* dependencies][136], the files are generated, checked into -version control, and included in distribution tarballs. - -If you run [`configure.sh`][69], you have an easy way of generating the markdown -manuals and manpages: just run `make manpages`. This target calls -[`scripts/manpage.sh`][60] appropriately for `bc`, `dc`, and `bcl`. - -For more on how generating manuals and manpages works, see -[`scripts/manpage.sh`][60]. - -## Locales - -The locale system of `bc` is enormously complex, but that's because -POSIX-compatible locales are terrible. - -How are they terrible? - -First, `gencat` does not work for generating cross-compilation. In other words, -it does not generate machine-portable files. There's nothing I can do about -this except for warn users. - -Second, the format of `.msg` files is...interesting. Thank goodness it is text -because otherwise, it would be impossible to get them right. - -Third, `.msg` files are not used. In other words, `gencat` exists. Why? - -Fourth, `$NLSPATH` is an awful way to set where and *how* to install locales. - -Yes, where and *how*. - -Obviously, from it's name, it's a path, and that's the where. The *how* is more -complicated. - -It's actually *not* a path, but a path template. It's a format string, and it -can have a few format specifiers. For more information on that, see [this -link][84]. But in essence, those format specifiers configure how each locale is -supposed to be installed. - -With all those problems, why use POSIX locales? Portability, as always. I can't -assume that `gettext` will be available, but I *can* pretty well assume that -POSIX locales will be available. - -The locale system of `bc` includes all files under [`locales/`][85], -[`scripts/locale_install.sh`][87], [`scripts/locale_uninstall.sh`][88], -[`scripts/functions.sh`][105], the `bc_err_*` constants in [`src/data.c`][131], -and the parts of the build system needed to activate it. There is also code in -[`src/vm.c`][58] (in `bc_vm_gettext()`) for loading the current locale. - -If the order of error messages and/or categories are changed, the order of -errors must be changed in the enum, the default error messages and categories in -[`src/data.c`][131], and all of the messages and categories in the `.msg` files -under [`locales/`][85]. - -## Static Analysis - -I do *some* static analysis on `bc`. - -I used to use [Coverity][196], but I stopped using it when it started giving me -too many false positives and also because it had a vulnerability. - -However, I still use the [Clang Static Analyzer][197] through -[`scan-build`][19]. I only use it in debug mode because I have to add some -special code to make it not complain about things that are definitely not a -problem. - -The most frequent example of false positives is where a local is passed to a -function to be initialized. [`scan-build`][19] misses that fact, so I -pre-initialize such locals to prevent the warnings. - -To run `scan-build`, do the following: - -``` -make clean -scan-build make -``` - -`scan-build` will print its warnings to `stdout`. - -## Fuzzing - -The quality of this `bc` is directly related to the amount of fuzzing I did. As -such, I spent a lot of work making the fuzzing convenient and fast, though I do -admit that it took me a long time to admit that it did need to be faster. - -First, there were several things which make fuzzing fast: - -* Using [AFL++][125]'s deferred initialization. -* Splitting `bc`'s corpuses. -* Parallel fuzzing. - -Second, there are several things which make fuzzing convenient: - -* Preprepared input corpuses. -* [`scripts/fuzz_prep.sh`][119]. -* `tmux` and `tmuxp` configs. -* [`scripts/afl.py`][94]. - -### Fuzzing Performance - -Fuzzing with [AFL++][125] can be ***SLOW***. Spending the time to make it as -fast as possible is well worth the time. - -However, there is a caveat to the above: it is easy to make [AFL++][125] crash, -be unstable, or be unable to find "paths" (see [AFL++ Quickstart][129]) if the -performance enhancements are done poorly. - -To stop [AFL++][125] from crashing on test cases, and to be stable, these are -the requirements: - -* The state at startup must be *exactly* the same. -* The virtual memory setup at startup must be *exactly* the same. - -The first isn't too hard; it's the second that is difficult. - -`bc` allocates a lot of memory at start. ("A lot" is relative; it's far less -than most programs.) After going through an execution run, however, some of that -memory, while it could be cleared and reset, is in different places because of -vectors. Since vectors reallocate, their allocations are not guaranteed to be in -the same place. - -So to make all three work, I had to set up the deferred initialization and -persistent mode *before* any memory was allocated (except for `vm.jmp_bufs`, -which is probably what caused the stability to drop below 100%). However, using -deferred alone let me put the [AFL++][125] initialization further back. This -works because [AFL++][125] sets up a `fork()` server that `fork()`'s `bc` right -at that call. Thus, every run has the exact same virtual memory setup, and each -run can skip all of the setup code. - -I tested `bc` using [AFL++][125]'s deferred initialization, plus persistent -mode, plus shared memory fuzzing. In order to do it safely, with stability above -99%, all of that was actually *slower* than using just deferred initialization -with the initialization *right before* `stdin` was read. And as a bonus, the -stability in that situation is 100%. - -As a result, my [AFL++][125] setup only uses deferred initialization. That's the -`__AFL_INIT()` call. - -(Note: there is one more big item that must be done in order to have 100% -stability: the pseudo-random number generator *must* start with *exactly* the -same seed for every run. This is set up with the `tmux` and `tmuxp` configs that -I talk about below in [Convenience][130]. This seed is set before the -`__AFL_INIT()` call, so setting it has no runtime cost for each run, but without -it, stability would be abysmal.) - -On top of that, while `dc` is plenty fast under fuzzing (because of a faster -parser and less test cases), `bc` can be slow. So I have split the `bc` input -corpus into three parts, and I set fuzzers to run on each individually. This -means that they will duplicate work, but they will also find more stuff. - -On top of all of that, each input corpus (the three `bc` corpuses and the one -`dc` corpus) is set to run with 4 fuzzers. That works out perfectly for two -reasons: first, my machine has 16 cores, and second, the [AFL++][125] docs -recommend 4 parallel fuzzers, at least, to run different "power schedules." - -### Convenience - -The preprepared input corpuses are contained in the -`tests/fuzzing/bc_inputs{1,2,3}/`, and `tests/fuzzing/dc_inputs` directories. -There are three `bc` directories and only one `dc` directory because `bc`'s -input corpuses are about three times as large, and `bc` is a larger program; -it's going to need much more fuzzing. - -(They do share code though, so fuzzing all of them still tests a lot of the same -math code.) - -The next feature of convenience is the [`scripts/fuzz_prep.sh`][119] script. It -assumes the existence of `afl-clang-lto` in the `$PATH`, but if that exists, it -automatically configures and builds `bc` with a fuzz-ideal build. - -A fuzz-ideal build has several things: - -* `afl-clang-lto` as the compiler. (See [AFL++ Quickstart][129].) -* Debug mode, to crash as easily as possible. -* Full optimization (including [Link-Time Optimization][126]), for performance. -* [AFL++][125]'s deferred initialization (see [Fuzzing Performance][127] above). -* And `AFL_HARDEN=1` during the build to harden the build. See the [AFL++][125] -  documentation for more information. - -There is one big thing that a fuzz-ideal build does *not* have: it does not use -[AFL++][125]'s `libdislocator.so`. This is because `libdislocator.so` crashes if -it fails to allocate memory. I do not want to consider those as crashes because -my `bc` does, in fact, handle them gracefully by exiting with a set error code. -So `libdislocator.so` is not an option. - -However, to add to [`scripts/fuzz_prep.sh`][119] making a fuzz-ideal build, in -`tests/fuzzing/`, there are two `yaml` files: [`tests/fuzzing/bc_afl.yaml`][120] -and [`tests/fuzzing/bc_afl_continue.yaml`][121]. These files are meant to be -used with [`tmux`][122] and [`tmuxp`][123]. While other programmers will have to -adjust the `start_directory` item, once it is adjusted, then using this command: - -``` -tmuxp load tests/fuzzing/bc_afl.yaml -``` - -will start fuzzing. - -In other words, to start fuzzing, the sequence is: - -``` -./scripts/fuzz_prep.sh -tmuxp load tests/fuzzing/bc_afl.yaml -``` - -Doing that will load, in `tmux`, 16 separate instances of [AFL++][125], 12 on -`bc` and 4 on `dc`. The outputs will be put into the -`tests/fuzzing/bc_outputs{1,2,3}/` and `tests/fuzzing/dc_outputs/` directories. - -(Note that loading that config will also delete all unsaved [AFL++][125] output -from the output directories.) - -Sometimes, [AFL++][125] will report crashes when there are none. When crashes -are reported, I always run the following command: - -``` -./scripts/afl.py <dir> -``` - -where `dir` is one of `bc1`, `bc2`, `bc3`, or `dc`, depending on which of the -16 instances reported the crash. If it was one of the first four (`bc11` through -`bc14`), I use `bc1`. If it was one of the second four (`bc21` through `bc24`, I -use `bc2`. If it was one of the third four (`bc31` through `bc34`, I use `bc3`. -And if it was `dc`, I use `dc`. - -The [`scripts/afl.py`][94] script will report whether [AFL++][125] correctly -reported a crash or not. If so, it will copy the crashing test case to -`.test.txt` and tell you whether it was from running it as a file or through -`stdin`. - -From there, I personally always investigate the crash and fix it. Then, when the -crash is fixed, I either move `.test.txt` to `tests/{bc,dc}/errors/<idx>.txt` as -an error test (if it produces an error) or I create a new -`tests/{bc,dc}/misc<idx>.txt` test for it and a corresponding results file. (See -[Test Suite][124] for more information about the test suite.) In either case, -`<idx>` is the next number for a file in that particular place. For example, if -the last file in `tests/{bc,dc}/errors/` is `tests/{bc,dc}/errors/18.txt`, I -move `.test.txt` to `tests/bc/error/19.txt`. - -Then I immediately run [`scripts/afl.py`][94] again to find the next crash -because often, [AFL++][125] found multiple test cases that trigger the same -crash. If it finds another, I repeat the process until it is happy. - -Once it *is* happy, I do the same `fuzz_prep.sh`, `tmuxp load` sequence and -restart fuzzing. Why do I restart instead of continuing? Because with the -changes, the test outputs could be stale and invalid. - -However, there *is* a case where I continue: if [`scripts/afl.py`][94] finds -that every crash reported by [AFL++][125] is invalid. If that's the case, I can -just continue with the command: - -``` -tmuxp load tests/fuzzing/bc_afl_continue.yaml -``` - -(Note: I admit that I usually run [`scripts/afl.py`][94] while the fuzzer is -still running, so often, I don't find a need to continue since there was no -stop. However, the capability is there, if needed.) - -In addition, my fuzzing setup, including the `tmux` and `tmuxp` configs, -automatically set up [AFL++][125] power schedules (see [Fuzzing -Performance][127] above). They also set up the parallel fuzzing such that there -is one fuzzer in each group of 4 that does deterministic fuzzing. It's always -the first one in each group. - -For more information about deterministic fuzzing, see the [AFL++][125] -documentation. - -### Corpuses - -I occasionally add to the input corpuses. These files come from new files in the -[Test Suite][124]. In fact, I use soft links when the files are the same. - -However, when I add new files to an input corpus, I sometimes reduce the size of -the file by removing some redundancies. - -And then, when adding to the `bc` corpuses, I try to add them evenly so that -each corpus will take about the same amount of time to get to a finished state. - -### [AFL++][125] Quickstart - -The way [AFL++][125] works is complicated. - -First, it is the one to invoke the compiler. It leverages the compiler to add -code to the binary to help it know when certain branches are taken. - -Then, when fuzzing, it uses that branch information to generate information -about the "path" that was taken through the binary. - -I don't know what AFL++ counts as a new path, but each new path is added to an -output corpus, and it is later used as a springboard to find new paths. - -This is what makes AFL++ so effective: it's not just blindly thrashing a binary; -it adapts to the binary by leveraging information about paths. - -### Fuzzing Runs - -For doing a fuzzing run, I expect about a week or two where my computer is -basically unusable, except for text editing and light web browsing. - -Yes, it can take two weeks for me to do a full fuzzing run, and that does *not* -include the time needed to find and fix crashes; it only counts the time on the -*last* run, the one that does not find any crashes. This means that the entire -process can take a month or more. - -What I use as an indicator that the fuzzing run is good enough is when the -number of "Pending" paths (see [AFL++ Quickstart][129] above) for all fuzzer -instances, except maybe the deterministic instances, is below 50. And even then, -I try to let deterministic instances get that far as well. - -You can see how many pending paths are left in the "path geometry" section of -the [AFL++][125] dashboard. - -Also, to make [AFL++][125] quit, you need to send it a `SIGINT`, either with -`Ctrl+c` or some other method. It will not quit until you tell it to. - -### Radamsa - -I rarely use [Radamsa][99] instead of [AFL++][125]. In fact, it's only happened -once. - -The reason I use [Radamsa][99] instead of [AFL++][125] is because it is easier -to use with varying command-line arguments, which was needed for testing `bc`'s -command-line expression parsing code, and [AFL++][125] is best when testing -input from `stdin`. - -[`scripts/radamsa.sh`][100] does also do fuzzing on the [AFL++][125] inputs, but -it's not as effective at that, so I don't really use it for that either. - -[`scripts/radamsa.sh`][100] and [Radamsa][99] were only really used once; I have -not had to touch the command-line expression parsing code since. - -### [AddressSanitizer][21] with Fuzzing - -One advantage of using [AFL++][125] is that it saves every test case that -generated a new path (see [AFL++ Quickstart][129] above), and it doesn't delete -them when the user makes it quit. - -Keeping them around is not a good idea, for several reasons: - -* They are frequently large. -* There are a lot of them. -* They go stale; after `bc` is changed, the generated paths may not be valid -  anymore. - -However, before they are deleted, they can definitely be leveraged for even -*more* bug squashing by running *all* of the paths through a build of `bc` with -[AddressSanitizer][21]. - -This can easily be done with these four commands: - -``` -./scripts/fuzz_prep.sh -a -./scripts/afl.py --asan bc1 -./scripts/afl.py --asan bc2 -./scripts/afl.py --asan bc3 -./scripts/afl.py --asan dc -``` - -(By the way, the last four commands could be run in separate terminals to do the -processing in parallel.) - -These commands build an [ASan][21]-enabled build of `bc` and `dc` and then they -run `bc` and `dc` on all of the found crashes and path output corpuses. This is -to check that no path or crash has found any memory errors, including memory -leaks. - -Because the output corpuses can contain test cases that generate infinite loops -in `bc` or `dc`, [`scripts/afl.py`][94] has a timeout of 8 seconds, which is far -greater than the timeout that [AFL++][125] uses and should be enough to catch -any crash. - -If [AFL++][125] fails to find crashes *and* [ASan][21] fails to find memory -errors on the outputs of [AFL++][125], that is an excellent indicator of very -few bugs in `bc`, and a release can be made with confidence. - -## Code Concepts - -This section is about concepts that, if understood, will make it easier to -understand the code as it is written. - -The concepts in this section are not found in a single source file, but they are -littered throughout the code. That's why I am writing them all down in a single -place. - -### POSIX Mode - -POSIX mode is `bc`-only. - -In fact, POSIX mode is two different modes: Standard Mode and Warning Mode. -These modes are designed to help users write POSIX-compatible `bc` scripts. - -#### Standard Mode - -Standard Mode is activated with the `-s` or `--standard` flags. - -In this mode, `bc` will error if any constructs are used that are not strictly -compatible with the [POSIX `bc` specification][2]. - -#### Warning Mode - -Warning Mode is activated with the `-w` or `--warn` flags. - -In this mode, `bc` will issue warnings, but continue, if any constructs are used -that are not strictly compatible with the [POSIX `bc` specification][2]. - -### Memory Management - -The memory management in `bc` is simple: everything is owned by one thing. - -If something is in a vector, it is owned by that vector. - -If something is contained in a struct, it is owned by that struct with one -exception: structs can be given pointers to other things, but only if those -other things will outlast the struct itself. - -As an example, the `BcParse` struct has a pointer to the one `BcProgram` in -`bc`. This is okay because the program is initialized first and deallocated -last. - -In other words, it's simple: if a field in a struct is a pointer, then unless -that pointer is directly allocated by the struct (like the vector array or the -number limb array), that struct does not own the item at that pointer. -Otherwise, the struct *does* own the item. - -### [Async-Signal-Safe][115] Signal Handling - -`bc` is not the typical Unix utility. Most Unix utilities are I/O bound, but -`bc` is, by and large, CPU-bound. This has several consequences, but the biggest -is that there is no easy way to allow signals to interrupt it. - -This consequence is not obvious, but it comes from the fact that a lot of I/O -operations can be interrupted and return [`EINTR`][198]. This makes such I/O -calls natural places for allowing signals to interrupt execution, even when the -signal comes during execution, and not interrupting I/O calls. The way this is -done is setting a flag in the signal handler, which is checked around the time -of the I/O call, when it is convenient. - -Alternatively, I/O bound programs can use the [self-pipe trick][199]. - -Neither of these are possible in `bc` because the execution of math code can -take a long time. If a signal arrives during this long execution time, setting a -flag like an I/O bound application and waiting until the next I/O call could -take seconds, minutes, hours, or even days. (Last I checked, my `bc` takes a -week to calculate a million digits of pi, and it's not slow as far as `bc` -implementations go.) - -Thus, using just the technique of setting the flag just will not work for an -interactive calculator. - -Well, it can, but it requires a lot of code and massive inefficiencies. I know -this because that was the original implementation. - -The original implementation set a flag and just exit the signal handler. Then, -on just about every loop header, I have a check for the signal flag. These -checks happened on every iteration of every loop. It was a massive waste because -it was polling, and [polling is evil][200]. - -So for version [3.0.0][32], I expended a lot of effort to change the -implementation. - -In the new system, code *outside* the signal handler sets a flag (`vm.sig_lock`) -to tell the signal handler whether it can use `longjmp()` to stop the current -execution. If so, it does. If not, it sets a flag, which then is used by the -code outside the signal handler that set the `vm.sig_lock` flag. When that code -unsets `vm.sig_lock`, it checks to see if a signal happened, and if so, that -code executes the `longjmp()` and stops the current execution. - -Other than that, the rest of the interrupt-based implementation is best -described in the [Error Handling][97]. - -However, there are rules for signal handlers that I must lay out. - -First, signal handlers can only call [async-signal-safe][115] functions. - -Second, any field set or read by both the signal handler and normal code must be -a `volatile sig_atomic_t`. - -Third, when setting such fields, they must be set to constants and no math can -be done on them. This restriction and the above restriction exist in order to -ensure that the setting of the fields is always atomic with respect to signals. - -These rules exist for *any* code using Unix signal handlers, not just `bc`. - -#### Vectors and Numbers - -Vectors and numbers needed special consideration with the interrupt-based signal -handling. - -When vectors and numbers are about to allocate, or *reallocate* their arrays, -they need to lock signals to ensure that they do not call `malloc()` and friends -and get interrupted by a signal because, as you will see in the [Error -Handling][97] section, `longjmp()` cannot be used in a signal handler if it may -be able to interrupt a non-[async-signal-safe][115] function like `malloc()` and -friends. - -### Asserts - -If you asked me what procedure is used the most in `bc`, I would reply without -hesitation, "`assert()`." - -I use `assert()` everywhere. In fact, it is what made [fuzzing][82] with -[AFL++][125] so effective. [AFL++][125] is incredibly good at finding crashes, -and a failing `assert()` counts as one. - -So while a lot of bad bugs might have corrupted data and *not* caused crashes, -because I put in so many `assert()`'s, they were *turned into* crashing bugs, -and [AFL++][125] found them. - -By far, the most bugs it found this way was in the `bc` parser. (See the [`bc` -Parsing][110] for more information.) And even though I was careful to put -`assert()`'s everywhere, most parser bugs manifested during execution of -bytecode because the virtual machine assumes the bytecode is valid. - -Sidenote: one of those bugs caused an infinite recursion when running the sine -(`s()`) function in the math library, so yes, parser bugs can be *very* weird. - -Anyway, the way I did `assert()`'s was like this: whenever I realized that I -had put assumptions into the code, I would put an `assert()` there to test it -**and** to *document* it. - -Yes, documentation. In fact, by far the best documentation of the code in `bc` -is actually the `assert()`'s. The only time I would not put an `assert()` to -test an assumption is if that assumption was already tested by an `assert()` -earlier. - -As an example, if a function calls another function and passes a pointer that -the caller previously `assert()`'ed was *not* `NULL`, then the callee does not -have to `assert()` it too, unless *also* called by another function that does -not `assert()` that. - -At first glance, it may seem like putting asserts for pointers being non-`NULL` -everywhere would actually be good, but unfortunately, not for fuzzing. Each -`assert()` is a branch, and [AFL++][125] rates its own effectiveness based on -how many branches it covers. If there are too many `assert()`'s, it may think -that it is not being effective and that more fuzzing is needed. - -This means that `assert()`'s show up most often in two places: function -preconditions and function postconditions. - -Function preconditions are `assert()`'s that test conditions relating to the -arguments a function was given. They appear at the top of the function, usually -before anything else (except maybe initializing a local variable). - -Function postconditions are `assert()`'s that test the return values or other -conditions when a function exits. These are at the bottom of a function or just -before a `return` statement. - -The other `assert()`'s cover various miscellaneous assumptions. - -If you change the code, I ***HIGHLY*** suggest that you use `assert()`'s to -document your assumptions. And don't remove them when [AFL++][125] gleefully -crashes `bc` and `dc` over and over again. - -### Vectors - -In `bc`, vectors mean resizable arrays, and they are the most fundamental piece -of code in the entire codebase. - -I had previously written a [vector implementation][112], which I used to guide -my decisions, but I wrote a new one so that `bc` would not have a dependency. I -also didn't make it as sophisticated; the one in `bc` is very simple. - -Vectors store some information about the type that they hold: - -* The size (as returned by `sizeof`). -* An enum designating the destructor. - -If the destructor is `BC_DTOR_NONE`, it is counted as the type not having a -destructor. - -But by storing the size, the vector can then allocate `size * cap` bytes, where -`cap` is the capacity. Then, when growing the vector, the `cap` is doubled again -and again until it is bigger than the requested size. - -But to store items, or to push items, or even to return items, the vector has to -figure out where they are, since to it, the array just looks like an array of -bytes. - -It does this by calculating a pointer to the underlying type with -`v + (i * size)`, where `v` is the array of bytes, `i` is the index of the -desired element, and `size` is the size of the underlying type. - -Doing that, vectors can avoid undefined behavior (because `char` pointers can -be cast to any other pointer type), while calculating the exact position of -every element. - -Because it can do that, it can figure out where to push new elements by -calculating `v + (len * size)`, where `len` is the number of items actually in -the vector. - -By the way, `len` is different from `cap`. While `cap` is the amount of storage -*available*, `len` is the number of actual elements in the vector at the present -point in time. - -Growing the vector happens when `len` is equal to `cap` *before* pushing new -items, not after. - -To add a destructor, you need to add an enum item to `BcDtorType` in -[`include/vector.h`][174] and add the actual destructor in the same place as the -enum item in the `bc_vec_dtors[]` array in [`src/data.c`][131]. - -#### Pointer Invalidation - -There is one big danger with the vectors as currently implemented: pointer -invalidation. - -If a piece of code receives a pointer from a vector, then adds an item to the -vector before they finish using the pointer, that code must then update the -pointer from the vector again. - -This is because any pointer inside the vector is calculated based off of the -array in the vector, and when the vector grows, it can `realloc()` the array, -which may move it in memory. If that is done, any pointer returned by -`bc_vec_item()`, `bc_vec_top()` and `bc_vec_item_rev()` will be invalid. - -This fact was the single most common cause of crashes in the early days of this -`bc`; wherever I have put a comment about pointers becoming invalidated and -updating them with another call to `bc_vec_item()` and friends, *do **NOT** -remove that code!* - -#### Maps - -Maps in `bc` are...not. - -They are really a combination of two vectors. Those combinations are easily -recognized in the source because one vector is named `<name>s` (plural), and the -other is named `<name>_map`. - -There are currently three, all in `BcProgram`: - -* `fns` and `fn_map` (`bc` functions). -* `vars` and `var_map` (variables). -* `arrs` and `arr_map` (arrays). - -They work like this: the `<name>_map` vector holds `BcId`'s, which just holds a -string and an index. The string is the name of the item, and the index is the -index of that item in the `<name>s` vector. - -Obviously, I could have just done a linear search for items in the `<name>s` -vector, but that would be slow with a lot of functions/variables/arrays. -Instead, I ensure that whenever an item is inserted into the `<name>_map` -vector, the item is inserted in sorted order. This means that the `<name>_map` -is always sorted (by the names of the items). - -So when looking up an item in the "map", what is really done is this: - -1.	A binary search is carried out on the names in the `<name>_map` vector. -2.	When one is found, it returns the index in the `<name>_map` vector where the -	item was found. -3.	This index is then used to retrieve the `BcId`. -4.	The index from the `BcId` is then used to index into the `<name>s` vector, -	which returns the *actual* desired item. - -Why were the `<name>s` and `<name>_map` vectors not combined for ease? The -answer is that sometime, when attempting to insert into the "map", code might -find that something is already there. For example, a function with that name may -already exist, or the variable might already exist. - -If the insert fails, then the name already exists, and the inserting code can -forego creating a new item to put into the vector. However, if there is no item, -the inserting code must create a new item and insert it. - -If the two vectors were combined together, it would not be possible to separate -the steps such that creating a new item could be avoided if it already exists. - -#### Slabs and Slab Vectors - -`bc` allocates *a lot* of small strings, and small allocations are the toughest -for general-purpose allocators to handle efficiently. - -Because of that reason, I decided to create a system for allocating small -strings using something that I call a "slab vector" after [slab -allocators][201]. - -These vectors allocate what I call "slabs," which are just an allocation of a -single page with a length to tell the slab how much of the slab is used. - -The vector itself holds slabs, and when the slab vector is asked to allocate a -string, it attempts to in the last slab. If that slab cannot do so, it allocates -a new slab and allocates from that. - -There is one exception: if a string is going to be bigger than 128 bytes, then -the string is directly allocated, and a slab is created with that pointer and a -length of `SIZE_MAX`, which tells the slab vector that it is a direct -allocation. Then, the last slab is pushed into the next spot and the new special -slab is put into the vacated spot. This ensures that a non-special slab is -always last. - -### Command-Line History - -When I first wrote `bc`, I immediately started using it in order to eat my own -dog food. - -It sucked, and the biggest reason why was because of the lack of command-line -history. - -At first, I just dealt with it, not knowing how command-line history might be -implemented. - -Eventually, I caved and attempted to adapt [`linenoise-mob`][28], which I had -known about for some time. - -It turned out to be easier than I thought; the hardest part was the tedious -renaming of everything to fit the `bc` naming scheme. - -Understanding command-line history in `bc` is really about understanding VT-100 -escape codes, so I would start there. - -Now, the history implementation of `bc` has been adapted far beyond that initial -adaptation to make the command-line history implementation perfect for `bc` -alone, including integrating it into `bc`'s [Custom I/O][114] and making sure -that it does not disturb output that did not end with a newline. - -On top of that, at one point, I attempted to get history to work on Windows. It -barely worked after a lot of work and a lot of portability code, but even with -all of that, it does not have at least one feature: multi-line pasting from the -clipboard. - -### Error Handling - -The error handling on `bc` got an overhaul for version [`3.0.0`][32], and it -became one of the things that taught me the most about C in particular and -programming in general. - -Before then, error handling was manual. Almost all functions returned a -`BcStatus` indicating if an error had occurred. This led to a proliferation of -lines like: - -``` -if (BC_ERR(s)) return s; -``` - -In fact, a quick and dirty count of such lines in version `2.7.2` (the last -version before [`3.0.0`][32]) turned up 252 occurrences of that sort of line. - -And that didn't even guarantee that return values were checked *everywhere*. - -But before I can continue, let me back up a bit. - -From the beginning, I decided that I would not do what GNU `bc` does on errors; -it tries to find a point at which it can recover. Instead, I decided that I -would have `bc` reset to a clean slate, which I believed, would reduce the -number of bugs where an unclean state caused errors with continuing execution. - -So from the beginning, errors would essentially unwind the stack until they got -to a safe place from which to clean the slate, reset, and ask for more input. - -Well, if that weren't enough, `bc` also has to handle [POSIX signals][113]. As -such, it had a signal handler that set a flag. But it could not safely interrupt -execution, so that's all it could do. - -In order to actually respond to the signal, I had to litter checks for the flag -*everywhere* in the code. And I mean *everywhere*. They had to be checked on -every iteration of *every* loop. They had to be checked going into and out of -certain functions. - -It was a mess. - -But fortunately for me, signals did the same thing that errors did: they unwound -the stack to the *same* place. - -Do you see where I am going with this? - -It turns out that what I needed was a [async-signal-safe][115] form of what -programmers call "exceptions" in other languages. - -I knew that [`setjmp()`][116] and [`longjmp()`][117] are used in C to implement -exceptions, so I thought I would learn how to use them. How hard could it be? - -Quite hard, it turns out, especially in the presence of signals. And that's -because there are a few big snares: - -1.	The value of any local variables are not guaranteed to be preserved after a -	`longjmp()` back into a function. -2.	While `longjmp()` is required to be [async-signal-safe][115], if it is -	invoked by a signal handler that interrupted a non-[async-signal-safe][115] -	function, then the behavior is undefined. -3.	Any mutation that is not guaranteed to be atomic with respect to signals may -	be incomplete when a signal arrives. - -Oh boy. - -For number 1, the answer to this is to hide data that must stay changed behind -pointers. Only the *pointers* are considered local, so as long as I didn't do -any modifying pointer arithmetic, pointers and their data would be safe. For -cases where I have local data that must change and stay changed, I needed to -*undo* the `setjmp()`, do the change, and the *redo* the `setjmp()`. - -For number 2 and number 3, `bc` needs some way to tell the signal handler that -it cannot do a `longjmp()`. This is done by "locking" signals with a `volatile -sig_atomic_t`. (For more information, see the [Async-Signal-Safe Signal -Handling][173] section.) For every function that calls a function that is not -async-signal-safe, they first need to use `BC_SIG_LOCK` to lock signals, and -afterward, use `BC_SIG_UNLOCK` to unlock signals. - -Code also need to do this for all global, non-atomic mutation, which means that -modifying any part of the `BcVm` global struct. - -`BC_SIG_UNLOCK` has another requirement: it must check for signals or errors and -jump if necessary. - -On top of all of that, *all* functions with cleanup needed to be able to run -their cleanup. This meant that `longjmp()` could not just jump to the finish; it -had to start what I call a "jump series," using a stack of `jmp_buf`'s -(`jmp_bufs` in `BcVm`). Each `longjmp()` uses the top of the `jmp_bufs` stack to -execute its jump. Then, if the cleanup code was executed because of a jump, the -cleanup code was responsible for continuing the jump series by popping the -previous item off the stack and using the new top of the stack for a jump. - -In this way, C++-style exceptions were implemented in pure C. Not fun, but it -works. However, the order of operations matters, especially in the macros that -help implement the error handling. - -For example, in `BC_UNSETJMP`, signals are unlocked before checking for signals. -If a signal comes between, that's fine; it will still cause a jump to the right -place. However, disabling the lock after could mean that a signal could come -*after* checking for signals, but before signals were unlocked, causing the -handling of the signal to be delayed. - -#### Custom I/O - -Why did I implement my own buffered I/O for `bc`? Because I use `setjmp()` and -`longjmp()` for error handling (see the [Error Handling][97] section), and the -buffered I/O in `libc` does not interact well with the use of those procedures; -all of the buffered I/O API is basically non-[async-signal-safe][115]. - -Implementing custom buffered I/O had other benefits. First, it allowed me to -tightly integrate history with the I/O code. Second, it allowed me to make -changes to history in order to make it adapt to user prompts. - -### Lexing - -To simplify parsing, both calculators use lexers to turn the text into a more -easily-parsable form. - -While some tokens are only one character long, others require many tokens, and -some of those need to store all of the text corresponding to the token for use -by the parsers. Tokens that need to store their corresponding text include, but -are not limited to: - -* Strings. -* Numbers. -* Identifiers. - -For this purpose, the lexer has a [vector][111] named `str` to store the data -for tokens. This data is overwritten if another token is lexed that needs to -store data, so the parsers need to copy the data before calling the lexer again. - -Both lexers do some of the same things: - -* Lex identifiers into tokens, storing the identifier in `str`. -* Lex number strings into tokens, storing the string in `str`. -* Lex whitespace. -* Lex comments. - -Other than that, and some common plumbing, the lexers have separate code. - -#### `dc` Lexing - -The `dc` lexer is remarkably simple; in fact, besides [`src/main.c`][205], -[`src/bc.c`][40], and [`src/dc.c`][44], which just contain one function each, -the only file smaller than [`src/dc_lex.c`][45] is [`src/args.c`][206], which -just processes command-line arguments after they are parsed by -[`src/opt.c`][51]. - -For most characters, the `dc` lexer is able to convert directly from the -character to its corresponding token. This happens using `dc_lex_tokens[]` in -[`src/data.c`][131]. - -`dc`'s lexer also has to lex the register name after lexing tokens for commands -that need registers. - -And finally, `dc`'s lexer needs to parse `dc` strings, which is the only part of -the `dc` lexer that is more complex than the `bc` lexer. This is because `dc` -strings need to have a balanced number of brackets. - -#### `bc` Lexing - -The `bc` lexer is fairly simple. It does the following things: - -* Lexes `bc` strings. -* Lexes `bc` identifiers. This is necessary because this is how `bc` keywords -  are lexed. After ensuring that an identifier is not a keyword, the `bc` lexer -  allows the common identifier function to take over. -* Turns characters and groups of characters into `bc` operator tokens. - -### Parsing - -The difference between parsing `bc` and `dc` code is...vast. The `dc` parser is -simple, while the `bc` parser is the most complex piece of code in the entire -codebase. - -However, they both do some of the same things. - -First, the parsers do *not* use [abstract syntax trees][207]; instead, they -directly generate the bytecode that will be executed by the `BcProgram` code. -Even in the case of `bc`, this heavily simplifies the parsing because the -[Shunting-Yard Algorithm][109] is designed to generate [Reverse Polish -Notation][108], which is basically directly executable. - -Second, any extra data that the `BcProgram` needs for execution is stored into -functions (see the [Functions][208] section). These include constants and -strings. - -#### `dc` Parsing - -The parser for `dc`, like its lexer, is remarkably simple. In fact, the easiness -of lexing and parsing [Reverse Polish notation][108] is probably why it was used -for `dc` when it was first created at Bell Labs. - -For most tokens, the `dc` parser is able to convert directly from the token -to its corresponding instruction. This happens using `dc_parse_insts[]` in -[`src/data.c`][131]. - -`dc`'s parser also has to parse the register name for commands that need -registers. This is the most complex part of the `dc` parser; each different -register command needs to be parsed differently because most of them require two -or more instructions to execute properly. - -For example, storing in a register requires a swap instruction and an assignment -instruction. - -Another example are conditional execution instructions; they need to produce the -instruction for the condition, and then they must parse a possible "else" part, -which might not exist. - -##### Existing Commands - -`dc` is based on commands, which are usually one letter. The following table is -a table of which ASCII characters are already used: - -| Characters | Used? | For...                                     | -|------------|-------|--------------------------------------------| -| Space      | x     | Separator                                  | -| `!`        | x     | Conditional Execution of Registers         | -| `"`        | x     | Bounded Rand Operator                      | -| `#`        | x     | Comments                                   | -| `$`        | x     | Truncation                                 | -| `%`        | x     | Modulus                                    | -| `&`        |       |                                            | -| `'`        | x     | Rand Operator                              | -| `(`        | x     | Greater Than Operator                      | -| `)`        | x     | Less Than Operator                         | -| `*`        | x     | Multiplication                             | -| `+`        | x     | Addition                                   | -| `,`        | x     | Depth of Execution Stack                   | -| `-`        | x     | Subtraction                                | -| `.`        | x     | Numbers                                    | -| `/`        | x     | Division                                   | -| `0-9`      | x     | Numbers                                    | -| `:`        | x     | Store into Array                           | -| `;`        | x     | Load from Array                            | -| `<`        | x     | Conditional Execution of Registers         | -| `=`        | x     | Conditional Execution of Registers         | -| `>`        | x     | Conditional Execution of Registers         | -| `?`        | x     | Ask for User Input                         | -| `@`        | x     | Places Operator                            | -| `A-F`      | x     | Numbers                                    | -| `G`        | x     | Equal Operator                             | -| `H`        | x     | Shift Left                                 | -| `I`        | x     | Push `ibase` onto Stack                    | -| `J`        | x     | Push `seed` onto Stack                     | -| `K`        | x     | Push `scale` onto Stack                    | -| `L`        | x     | Pop off of Register                        | -| `M`        | x     | Boolean And Operator                       | -| `N`        | x     | Boolean Not Operator                       | -| `O`        | x     | Push `obase` onto Stack                    | -| `P`        | x     | Byte Stream Printing                       | -| `Q`        | x     | Quit Some Number of Macros                 | -| `R`        | x     | Pop Top of Stack                           | -| `S`        | x     | Push onto Register                         | -| `T`        | x     | Push Max `ibase` onto Stack                | -| `U`        | x     | Push Max `obase` onto Stack                | -| `V`        | x     | Push Max `scale` onto Stack                | -| `W`        | x     | Push Max of `'` Operator                   | -| `X`        | x     | Scale of a Number                          | -| `Y`        | x     | Length of Array                            | -| `Z`        | x     | Number of Significant Digits               | -| `[`        | x     | Strings                                    | -| `\\`       | x     | Escaping Brackets in Strings               | -| `]`        | x     | Strings                                    | -| `^`        | x     | Power                                      | -| `_`        | x     | Negative Numbers and Negation              | -| Backtick   |       |                                            | -| `a`        | x     | Asciify                                    | -| `b`        | x     | Absolute Value                             | -| `c`        | x     | Clear Stack                                | -| `d`        | x     | Duplication of Top of Stack                | -| `e`        | x     | Else in Conditional Execution of Registers | -| `f`        | x     | Printing the Stack                         | -| `g`        | x     | Global Settings                            | -| `h`        | x     | Shift Right                                | -| `i`        | x     | Set `ibase`                                | -| `j`        | x     | Set `seed`                                 | -| `k`        | x     | Set `scale`                                | -| `l`        | x     | Load from Register                         | -| `m`        | x     | Boolean Or Operator                        | -| `n`        | x     | Print and Pop                              | -| `o`        | x     | Set `obase`                                | -| `p`        | x     | Print with Newline                         | -| `q`        | x     | Quit Two Macros                            | -| `r`        | x     | Swap Top Two Items                         | -| `s`        | x     | Store into Register                        | -| `t`        |       |                                            | -| `u`        |       |                                            | -| `v`        | x     | Square Root                                | -| `w`        |       |                                            | -| `x`        | x     | Execute String                             | -| `y`        | x     | Current Depth of a Register                | -| `z`        | x     | Current Depth of Stack                     | -| `{`        | x     | Greater Than or Equal Operator             | -| `\|`       | x     | Moduler Exponentiation                     | -| `}`        | x     | Less Than or Equal Operator                | -| `~`        | x     | Division and Modulus Combined              | - -#### `bc` Parsing - -`bc`'s parser is, by far, the most sensitive piece of code in this software, and -there is a very big reason for that: `bc`'s standard is awful and defined a very -poor language. - -The standard says that either semicolons or newlines can end statements. Trying -to parse the end of a statement when it can either be a newline or a semicolon -is subtle. Doing it in the presence of control flow constructs that do not have -to use braces is even harder. - -And then comes the biggest complication of all: `bc` has to assume that it is -*always* at a REPL (Read-Eval-Print Loop). `bc` is, first and foremost, an -*interactive* utility. - -##### Flags - -All of this means that `bc` has to be able to partially parse something, store -enough data to recreate that state later, and return, making sure to not -execute anything in the meantime. - -*That* is what the flags in [`include/bc.h`][106] are: they are the state that -`bc` is saving for itself. - -It saves them in a stack, by the way, because it's possible to nest -structures, just like any other programming language. Thus, not only does it -have to store state, it needs to do it arbitrarily, and still be able to -come back to it. - -So `bc` stores its parser state with flags in a stack. Careful setting of these -flags, along with properly using them and maintaining the flag stack, are what -make `bc` parsing work, but it's complicated. In fact, as I mentioned, the `bc` -parser is the single most subtle, fickle, and sensitive piece of code in the -entire codebase. Only one thing came close once: square root, and that was only -sensitive because I wrote it wrong. This parser is pretty good, and it is -*still* sensitive. And flags are the reason why. - -For more information about what individual flags there are, see the comments in -[`include/bc.h`][106]. - -##### Labels - -`bc`'s language is Turing-complete. That means that code needs the ability to -jump around, specifically to implement control flow like `if` statements and -loops. - -`bc` handles this while parsing with what I called "labels." - -Labels are markers in the bytecode. They are stored in functions alongside the -bytecode, and they are just indices into the bytecode. - -When the `bc` parser creates a label, it pushes an index onto the labels array, -and the index of the label in that array is the index that will be inserted into -the bytecode. - -Then, when a jump happens, the index pulled out of the bytecode is used to index -the labels array, and the label (index) at the index is then used to set the -instruction pointer. - -##### Cond Labels - -"Cond" labels are so-called because they are used by conditionals. - -The key to them is that they come *before* the code that uses them. In other -words, when jumping to a condition, code is jumping *backwards*. - -This means that when a cond label is created, the value that should go there is -well-known. Cond labels are easy. - -However, they are still stored on a stack so that the parser knows what cond -label to use. - -##### Exit Labels - -Exit labels are not so easy. - -"Exit" labels are so-called because they are used by code "exiting" out of `if` -statements or loops. - -The key to them is that they come *after* the code that uses them. In other -words, when jumping to an exit, code is jumping *forwards*. - -But this means that when an exit label is created, the value that should go -there is *not* known. The code that needs it must be parsed and generated first. - -That means that exit labels are created with the index of `SIZE_MAX`, which is -then specifically checked for with an assert in `bc_program_exec()` before using -those indices. - -There should ***NEVER*** be a case when an exit label is not filled in properly -if the parser has no bugs. This is because every `if` statement, every loop, -must have an exit, so the exit must be set. If not, there is a bug. - -Exit labels are also stored on a stack so that the parser knows what exit label -to use. - -##### Expression Parsing - -`bc` has expressions like you might expect in a typical programming language. -This means [infix notation][107]. - -One thing about infix notation is that you can't just generate code straight -from it like you can with [Reverse Polish notation][108]. It requires more work -to shape it into a form that works for execution on a stack machine. - -That extra work is called the [Shunting-Yard algorithm][109], and the form it -translates infix notation into is...[Reverse Polish notation][108]. - -In order to understand the rest of this section, you must understand the -[Shunting-Yard algorithm][109]. Go do that before you read on. - -###### Operator Stack - -In `bc`, the [Shunting-Yard algorithm][109] is implemented with bytecode as the -output and an explicit operator stack (the `ops` field in `BcParse`) as the -operator stack. It stores tokens from `BcLex`. - -However, there is one **HUGE** hangup: multiple expressions can stack. This -means that multiple expressions can be parsed at one time (think an array element -expression in the middle of a larger expression). Because of that, we need to -keep track of where the previous expression ended. That's what `start` parameter -to `bc_parse_operator()` is. - -Parsing multiple expressions on one operator stack only works because -expressions can only *stack*; this means that, if an expression begins before -another ends, it must *also* end before that other expression ends. This -property ensures that operators will never interfere with each other on the -operator stack. - -###### Recursion - -Because expressions can stack, parsing expressions actually requires recursion. -Well, it doesn't *require* it, but the code is much more readable that way. - -This recursion is indirect; the functions that `bc_parse_expr_err()` (the actual -expression parsing function) calls can, in turn, call it. - -###### Expression Flags - -There is one more big thing: not all expressions in `bc` are equal. - -Some expressions have requirements that others don't have. For example, only -array arguments can be arrays (which are technically not expressions, but are -treated as such for parsing), and some operators (in POSIX) are not allowed in -certain places. - -For this reason, functions that are part of the expression parsing -infrastructure in `bc`'s parser usually take a `flags` argument. This is meant -to be passed to children, and somewhere, they will be checked to ensure that the -resulting expression meets its requirements. - -There are also places where the flags are changed. This is because the -requirements change. - -Maintaining the integrity of the requirements flag set is an important part of -the `bc` parser. However, they do not have to be stored on a stack because their -stack is implicit from the recursion that expression parsing uses. - -### Functions - -Functions, in `bc`, are data structures that contain the bytecode and data -produced by the parsers. Functions are what the `BcProgram` program executes. - -#### Main and Read Functions - -There are two functions that always exist, which I call the "main" and "read" -functions. - -The "main" function is the function in which any code and data outside other -functions is put. Basically, it is the function where the scripting code ends -up. - -The "read" function is the function that is reset and parsed every time a call -to the `read()` builtin function happens. - -#### `dc` Strings - -In `dc`, strings can be executed, and since there are no actual "functions" in -`dc`, strings are handled as functions. In fact, they are effectively translated -into functions by parsing. - -##### Tail Calls - -Since strings in `dc` are functions, and the fact that `dc` has no native loops, -such loops are implemented in `dc` code using strings with conditional execution -commands at the end of strings. - -When such conditional execution, or even unconditional execution, commands are -the very last commands in a string, then `dc` can perform a [tail call][202]. - -This is done by recording the fact that a tail call happened, done by -incrementing an integer on a stack. When a string is executed *without* a tail -call, a new entry is pushed onto the stack with the integer `1`. - -When a string finally quits that followed tail calls, its stack entry is popped, -eliminating all of those tail calls. - -Why perform tail calls? Because otherwise, `dc` would be subject to the same -thing that plagues [functional programming languages][203]: stack overflow. In -`dc`'s case, that would manifest itself as a growing [heap][204], because the -execution stack is stored on the heap, until a fatal allocation failure would -occur. - -#### Execution - -Execution is handled by an interpreter implemented using `BcProgram` and code -in [`src/program.c`][53]. - -The interpreter is a mix between a [stack machine][210] and a [register -machine][211]. It is a stack machine in that operations happen on a stack I call -the "results stack," but it is a register machine in that items on the stack can -be stored to and loaded from "registers" (`dc` terminology), variables (`bc` -terminology), and arrays. - -##### Stacks - -There are two stacks in the interpreter: - -* The "results" stack (as mentioned above). -* The "execution" stack. - -The results stack (the `results` field of the `BcProgram` struct) is the stack -where the results of computations are stored. It is what makes the interpreter -part [stack machine][210]. It is filled with `BcResult`'s. - -The execution stack (the `stack` field of the `BcProgram` struct) is the stack -that tracks the current execution state of the interpreter. It is the presence -of this separate stack that allows the interpreter to implement the machine as a -loop, rather than recursively. It is filled with `BcInstPtr`'s, which are the -"instruction pointers." - -These instruction pointers have three fields, all integers: - -* `func`, the index of the function that is currently executing. -* `idx`, the index of the next bytecode instruction to execute in the function's -  bytecode array. -* `len`, which is the length of the results stack when the function started -  executing. This is not used by `dc`, but it used by `bc` because functions -  in `bc` should never affect the results stack of their callers. - -With these three fields, and always executing using the instruction pointer at -the top of the execution stack, the interpreter can always keep track of its -execution. - -When a function or a string starts executing, a new `BcInstPtr` is pushed onto -the execution stack for it. This includes if a function was called recursively. -And then, when the function or string returns, its `BcInstPtr` is popped off of -the execution stack. - -##### Bytecode - -Execution of functions are done through bytecode produced directly by the -parsers (see the [Parsing][209]). This bytecode is stored in the `code` -[vector][111] of the `BcFunc` struct. - -This is a vector for two reasons: - -* It makes it easier to add bytecode to the vector in the parsers. -* `bc` allows users to redefine functions. - -The reason I can use bytecode is because there are less than 256 instructions, -so an `unsigned char` can store all the bytecodes. - -###### Bytecode Indices - -There is one other factor to bytecode: there are instructions that need to -reference strings, constants, variables, or arrays. Bytecode need some way to -reference those things. - -Fortunately, all of those things can be referenced in the same way: with indices -because all of the items are in vectors. - -So `bc` has a way of encoding an index into bytecode. It does this by, after -pushing the instruction that references anything, pushing a byte set to the -length of the index in bytes, then the bytes of the index are pushed in -little-endian order. - -Then, when the interpreter encounters an instruction that needs one or more -items, it decodes the index or indices there and updates the `idx` field of the -current `BcInstPtr` to point to the byte after the index or indices. - -One more thing: the encoder of the indices only pushes as many bytes as -necessary to encode the index. It stops pushing when the index has no more bytes -with any 1 bits. - -##### Variables - -In `bc`, the vector of variables, `vars` in `BcProgram`, is not a vector of -numbers; it is a vector of vector of numbers. The first vector is the vector of -variables, the second is the variable stack, and the last level is the actual -number. - -This is because both `bc` and `dc` need variables to be stacks. - -For `dc`, registers are *defined* to be stacks. - -For `bc`, variables as stacks is how function arguments/parameters and function -`auto` variables are implemented. - -When a function is called, and a value needs to be used as a function argument, -a copy of the value is pushed onto the stack corresponding to the variable with -the same name as the function's parameter. For `auto` variables, a new number -set to zero is pushed onto each stack corresponding to the `auto` variables. -(Zero is used because the [`bc` spec][2] requires that `auto` variables are set -to zero.) - -It is in this way that the old value of the variable, which may not even be -related to the function parameter or `auto` variable, is preserved while the -variable is used as a function parameter or `auto` variable. - -When the function returns, of course, the stacks of the variables for the -parameters and `auto`'s will have their top item popped, restoring the old value -as it was before the function call. - -##### Arrays - -Like variables, arrays are also implemented as stacks. However, because they are -arrays, there is yet another level; the `arrs` field in `BcProgram` is a vector -of vectors of vectors of numbers. The first of the two levels is the vector of -arrays, the second the stack of for each array, the third the actual array, and -last the numbers in the array. - -`dc` has no need of this extra stack, but `bc` does because arrays can be -function parameters themselves. - -When arrays are used for function arguments, they are copied with a deep copy; -each item of the source vector is copied. This is because in `bc`, according to -the [`bc` spec][2], all function arguments are passed by value. - -However, array references are possible (see below). - -When arrays are used as `auto`'s, a new vector is pushed with one element; if -more elements are needed, the array is grown automatically, and new elements are -given the value of zero. - -In fact, if *any* array is accessed and does not have an element at that index, -the array is automaticall grown to that size, and all new elements are given the -value zero. This behavior is guaranteed by the [`bc` spec][2]. - -###### Array References - -Array references had to be implemented as vectors themselves because they must -be pushed on the vectors stacks, which, as seen above, expect vectors -themselves. - -So thus, references are implemented as vectors on the vector stacks. These -vectors are not vectors of vectors themselves; they are vectors of bytes; in -fact, the fact that they are byte vectors and not vector vectors is how a -reference vector is detected. - -These reference vectors always have the same two things pushed: a byte encoding -(the same way bytecode indices are) of the referenced vector's index in the -`arrs` vector, and a byte encoding of the referenced vectors index in the vector -stack. - -If an item in a referenced vector is needed, then the reference is dereferenced, -and the item is returned. - -If a reference vector is passed to a function that does *not* expect a -reference, the vector is dereferenced and a deep copy is done, in the same way -as vectors are copied for normal array function parameters. - -### Callbacks - -There are many places in `bc` and `dc` where function pointers are used: - -* To implement destructors in vectors. (See the [Vectors][111] section.) -* To select the correct lex and parse functions for `bc` and `dc`. -* To select the correct function to execute unary operators. -* To select the correct function to execute binary operators. -* To calculate the correct number size for binary operators. -* To print a "digit" of a number. -* To seed the pseudo-random number generator. - -And there might be more. - -In every case, they are used for reducing the amount of code. Instead of -`if`/`else` chains, such as: - -``` -if (BC_IS_BC) { -	bc_parse_parse(vm.parse); -} -else { -	dc_parse_parse(vm.parse); -} -``` - -The best example of this is `bc_num_binary()`. It is called by every binary -operator. It figures out if it needs to allocate space for a new `BcNum`. If so, -it allocates the space and then calls the function pointer to the *true* -operation. - -Doing it like that shrunk the code *immensely*. First, instead of every single -binary operator duplicating the allocation code, it only exists in one place. -Second, `bc_num_binary()` itself does not have a massive `if`/`else` chain or a -`switch` statement. - -But perhaps the most important use was for destructors in vectors. - -Most of the data structures in `bc` are stored in vectors. If I hadn't made -destructors available for vectors, then ensuring that `bc` had no memory leaks -would have been nigh impossible. As it is, I check `bc` for memory leaks every -release when I change the code, and I have not released `bc` after version -`1.0.0` with any memory leaks, as far as I can remember anyway. - -### Numbers - -In order to do arbitrary-precision math, as `bc` must do, there must be some way -of representing arbitrary-precision numbers. `BcNum` in [`include/num.h`][184] -is `bc`'s way of doing that. - -(Note: the word ["limb"][214] is used below; it has a specific meaning when -applied to arbitrary-precision numbers. It means one piece of the number. It can -have a single digit, which is what GNU `bc` does, or it can have multiple, which -is what this `bc` does.) - -This struct needs to store several things: - -* The array of limbs of the number. This is the `num` field. -* The location of the decimal point. This is the `rdx` (short for [radix][215]) -  field. -* The number of limbs the number has. This is the `len` field. -* Whether the number is negative or not. This is the least significant bit of -  the `rdx` field. More on that later. - -In addition, `bc`'s number stores the capacity of the limb array; this is the -`cap` field. - -If the number needs to grow, and the capacity of the number is big enough, the -number is not reallocated; the number of limbs is just added to. - -There is one additional wrinkle: to make the usual operations (binary operators) -fast, the decimal point is *not* allowed to be in the middle of a limb; it must -always be between limbs, after all limbs (integer), or before all limbs (real -between -1 and 1). - -The reason for this is because addition, subtraction, multiplication, and -division expect digits to be lined up on the decimal point. By requiring that it -be between limbs, no extra alignment is needed, and those operations can proceed -without extra overhead. - -This does make some operations, most notably extending, truncating, and -shifting, more expensive, but the overhead is constant, and these operations are -usually cheap compared to the binary operators anyway. - -This also requires something else: `bc` numbers need to know *exactly* how many -decimal places they have after the decimal point. If the decimal point must be -inbetween limbs, the last decimal place could be in the middle of a limb. The -amount of decimal places in a number is carefully tracked and stored in the -`scale` field, and this number must always coincide with the `rdx` field by the -following formula: - -``` -scale + (BC_BASE_DIGS - 1) / BC_BASE_DIGS == rdx >> 1 -``` - -(`BC_BASE_DIGS` is the number of decimal digits stored in one limb. It is 9 on -64-bit systems and 4 on other systems.) - -Yes, `rdx` is shifted; that is because the negative bit is stored in the least -significant bit of the `rdx` field, and the actual radix (amount of limbs after -the decimal/radix point) is stored in the rest of the bits. This is safe because -`BC_BASE_DIGS` is always at least 4, which means `rdx` will always need at least -2 bits less than `scale`. - -In addition to `rdx` always matching `scale`, another invariant is that `rdx` -must always be less than or equal to `len`. (Because `scale` may be greater than -`rdx`, `scale` does not have to be less than or equal to `len`.) - -Another invariant is that `len` must always be less than or equal to `cap`, for -obvious reasons. - -The last thing programmers need to know is that the limb array is stored in -little-endian order. This means that the last decimal places are in the limb -stored at index 0, and the most significant digits are stored at index `len-1`. - -This is done to make the most important operations fast. Addition and -subtraction are done from least significant to most significant limbs, which -means they can speed through memory in the way most computers are best at. -Multiplication does the same, sort of, and with division, it matters less. -Comparison does need to go backwards, but that's after exhausting all other -alternatives, including for example, checking the length of the integer portion -of each limb array. - -Finally, here are some possible special situations with numbers and what they -mean: - -* `len == 0`: the number equals 0. -* `len == 0 && scale != 0`: the number equals 0, but it has a `scale` value. -  This is the only case where `scale` does not have to coincide with `rdx` -  This can happen with division, for example, that sets a specific `scale` for -  the result value but may produce 0. -* `(rdx >> 1) < len`: the number is greater than or equal to 1, or less than or -  equal to -1. -* `(rdx >> 1) == len`: the number is greater than -1 and less than 1, not -  including 0, although this will be true for 0 as well. However, 0 is always -  assumed to be represented by `len == 0`. -* `(rdx >> 1) == 0`: the number is an integer. In this case, `scale` must also -  equal 0. - -#### Math Style - -When I wrote the math for `bc`, I adopted a certain style that, if known, will -make it easier to understand the code. The style follows these rules: - -* `BcNum` arguments always come before arguments of other types. -* Among the `BcNum` arguments, the operands always come first, and the `BcNum` -  where the result(s) will be stored come last. -* Error checking is placed first in the function. -* Easy cases are placed next. -* Preparation, such as allocating temporaries, comes next. -* The actual math. -* Cleanup and ensuring invariants. - -While these rules are not hard and fast, using them as a guide will probably -help. - -### Strings as Numbers - -Strings can be assigned to variables. This is a problem because the vectors for -variable stacks expect `BcNum` structs only. - -While I could have made a union, I decided that the complexity of adding an -entirely new type, with destructor and everything, was not worth it. Instead, I -took advantage of the fact that `free()`, when passed a `NULL` pointer, will do -nothing. - -Using that, I made it so `BcNum`'s could store strings instead. This is marked -by the `BcNum` having a `NULL` limb array (`num`) and a `cap` of 0 (which should -*never* happen with a real number, though the other fields could be 0). - -The `BcNum` stores the function that stores the string in the `rdx` field, and -it stores the index of the string in the `scale` field. This is used to actually -load the string if necessary. - -Note that historically, string information was stored in the `loc` field of -the `d` union in a `BcResult`. This was changed recently to standardize; now, -all string information are stored in the `n` field of the `d` union regardless. -This means that all string information is stored in `BcNum`'s. This removes -extra cases. - -Also, if a temp is made with a string, then the result type should still be -`BC_RESULT_STR`, not `BC_RESULT_TEMP`. This is to make it easier to do type -checks. - -### Pseudo-Random Number Generator - -In order to understand this section, I suggest you read the information in the -manpages about the pseudo-random number generator (PRNG) first; that will help -you understand the guarantees it has, which is important because this section -delves into implementation details. - -First, the PRNG I use is seeded; this is because most OS's have an excellent -cryptographically secure PRNG available via command-line, usually -`/dev/urandom`, but the only *seeded* PRNG available is usually `bash`'s -`$RANDOM`, which is essentially a wrapper around C's `rand()`. - -`rand()` is...bad. It is only guaranteed to return 15 bits of random data. -Obviously, getting good random data out of that would be hard with that alone, -but implementations also seem to be poor. - -On top of that, `bc` is an arbitrary-precision calculator; if I made it able to -generate random numbers, I could make it generate random numbers of any size, -and since it would be seeded, results would be reproducible, when wanted. - -So to get that, I needed a seeded PRNG with good characteristics. After scouring -the Internet, I decided on the [PCG PRNG][215], mostly because of [this blog -post][216]. Part of the reason was the behavior of the xoroshiro128+ author, who -hates on PCG and its author, but also because PCG seemed to do better when -tested by independent parties. - -After that decision, I faced a challenge: PCG requires 255 bits of seed: 128 for -the actual seed, and 127 for the "increment." (Melissa O'Neill, the PCG author, -likens the increment to selecting a codebook.) - -I could, of course, put the entire 255 bits into one massive arbitrary-precision -number; `bc` is good at that, after all. But that didn't sit right with me -because it would mean any seed selected by users would have the real portion -ignored, which is stupid in a program like `bc`. - -Instead, I decided to make the integer portion the increment (clamped down to -size), and the real portion the seed. - -In most cases, this would be a bad idea because you cannot, in general, know how -many decimal places you need to represent any number with `n` real digits in -base `b` in another base. However, there is an easy to how many decimal digits -after the decimal point it takes to represent reals of base 2 in base 10: the -power of two. - -It turns out that, for base 2 represented in base 10, the power of 2 is -*exactly* how many digits are necessary to represent *any* number `n/2^p`, where -`p` is the power of 2. This is because at every halving, the number of decimal -places increases by 1: - -``` -0.5 -0.25 -0.125 -0.0625 -0.03125 -0.015625 -... -``` - -So the algorithm to convert all 255 bits of the seed is as follows: - -1.	Convert the increment to a `BcNum`. -2.	Convert the seed to a `BcNum`. -3.	Divide the seed by `2^128` with a `scale` of 128. (For 32-bit systems, -	substitute 64 bits for 128.) -4.	Add the two numbers together. - -Likewise, the algorithm to convert from a user-supplied number to a seed is: - -1.	Truncate a copy of the number. -2.	Subtract the result from #1 from the original number. This gives the real -	portion of the number. -3.	Clamp the result of #1 to 127 (or 63) bits. This is the increment. -4.	Multiply the result of #2 by `2^128`. -5.	Truncate the result of #4. This is the seed. - -#### Generating Arbitrary-Precision Numbers - -I wrote a function (`bc_rand_bounded()`) that will return unbiased results with -any bound below the max that PCG can generate. - -To generate an integer of arbitrary size using a bound, `bc` simply uses -`bc_rand_bounded()` to generate numbers with a bound `10^BC_BASE_DIGS` for as -many limbs as needed to satisfy the bigger bound. - -To generate numbers with arbitrary precision after the decimal point, `bc` -merely generates an arbitrary precision integer with the bound `10^p`, where `p` -is the desired number of decimal places, then divides in by `10^p` with a -`scale` of `p`. - -## Debug Code - -Besides building `bc` in debug mode with the `-g` flag to [`configure.sh`][69], -programmers can also add `-DBC_DEBUG_CODE=1` to the `CFLAGS`. This will enable -the inclusion of *a lot* of extra code to assist with debugging. - -For more information, see all of the code guarded by `#if BC_DEBUG_CODE` in the -[`include/`][212] directory and in the [`src/`][213] directory. - -Yes, all of the code is guarded by `#if` preprocessor statements; this is -because the code should *never* be in a release build, and by making programmers -add this manually (not even an option to [`configure.sh`][69]), it is easier to -ensure that never happens. - -However, that said, the extra debug code is useful; that was why I kept it in. - -## Performance - -While I have put in a lot of effort to make `bc` as fast as possible, there -might be some things you can do to speed it up without changing the code. - -First, you can probably use [profile-guided optimization][217] to optimize even -better, using the test suite to profile. - -Second, I included macros that might help branch placement and prediction: - -* `BC_ERR(e)` -* `BC_UNLIKELY(e)` -* `BC_NO_ERR(e)` -* `BC_LIKELY(e)` - -`BC_ERR` is the same as `BC_UNLIKELY`, and `BC_NO_ERR` is the same as -`BC_LIKELY`; I just added them to also document branches that lead to error -conditions or *away* from error conditions. - -Anyway, if `BC_LIKELY` and `BC_UNLIKELY` are not defined during compilation, -they expand to nothing but the argument they were given. - -They can, however, be defined to `__builtin_expect((e), 1)` and -`__builtin_expect((e), 0)`, respectively, on GCC and Clang for better branch -prediction and placement. (For more information about `__builtin_expect()` see -the [GCC documentation][218].) - -There might be other compilers that can take advantage of that, but I don't know -anything about that. - -Also, as stated in the [build manual][219], link-time optimization is excellent -at optimizing this `bc`. Use it. - -### Benchmarks - -To help programmers improve performance, I have built and assembled -infrastructure to make benchmarking easy. - -First, in order to easily run benchmarks, I created -[`scripts/benchmark.sh`][220]. - -Second, I copied and adapted [`ministat.c`][223] [from FreeBSD][221], to make it -easier to judge whether the results are significant or not. - -Third, I made the `make` clean target `make clean_benchmarks`, to clean -`scripts/ministat` and the generated benchmark files. - -Fourth, I made it so [`scripts/benchmark.sh`][220] outputs the timing and memory -data in a format that is easy for `scripts/ministat` to digest. - -To add a benchmark, add a script in the right directory to generate the -benchmark. Yes, generate. - -All of the benchmarks are generated first, from `.bc` and `.dc` files in the -[`benchmarks/bc/`][91] and [`benchmarks/dc/`][224]. This is so that massive -amounts of data can be generated and then pushed through the calculators. - -If you need to benchmark `bc` or `dc` with simple loops, have the generator -files simply print the loop code. - -### Caching of Numbers - -In order to provide some performance boost, `bc` tries to reuse old `BcNum`'s -that have the default capacity (`BC_NUM_DEF_SIZE`). - -It does this by allowing `bc_num_free()` to put the limb array onto a -statically-allocated stack (it's just a global array with a set size). Then, -when a `BcNum` with the default capacity is needed, `bc_num_init()` asks if any -are available. If the answer is yes, the one on top of the stack is returned. -Otherwise, `NULL` is returned, and `bc_num_free()` knows it needs to `malloc()` -a new limb array. - -When the stack is filled, any numbers that `bc` attempts to put on it are just -freed. - -This setup saved a few percent in my testing for version [3.0.0][32], which is -when I added it. - -## `bcl` - -At the request of one of my biggest users, I spent the time to make a build mode -where the number and math code of `bc` could be wrapped into a library, which I -called `bcl`. - -This mode is exclusive; `bc` and `dc` themselves are *not* built when building -`bcl`. - -The only things in the `bc` math code that is not included is: - -* Printing newlines (clients do not care about `bc`'s line lenth restriction). -* `dc`'s stream print. - -Even the [pseudo-random number generator][179] is included, with extra support -for generating real numbers with it. (In `bc`, such support is in -[`lib2.bc`][26].) - -### Signal Handling - -Like signal handling in `bc` proper (see the [Async-Signal-Safe Signal -Handling][173] section), `bcl` has the infrastructure for signal handling. - -This infrastructure is different, however, as `bcl` assumes that clients will -implement their own signal handling. - -So instead of doing signal handling on its own, `bcl` provides the capability to -interrupt executions and return to the clients almost immediately. Like in `bc`, -this is done with `setjmp()` and `longjmp()`, although the jump series is -stopped before returning normally to client code. - -### Contexts - -Contexts were an idea by the same user that requested `bcl`. They are meant to -make it so multiple clients in one program can keep their data separate from -each other. - -### Numbers - -Numbers in `bcl` are literally indices into an encapsulated array of numbers, -hidden in the context. These indices are then passed to clients to refer to -numbers later. - -### Operand Consumption - -Most math functions in `bcl` "consume" their operand arguments; the arguments -are freed, whether or not an error is returned. - -This is to make it easy to implement math code, like this: - -``` -n = bcl_add(bcl_mul(a, b), bcl_div(c, d)); -``` - -If numbers need to be preserved, they can be with `bcl_dup()`: - -``` -n = bcl_add(bcl_mul(bcl_dup(a), bc_dup(b)), bcl_div(bcl_dup(c), bcl_dup(d))); -``` - -### Errors - -Errors can be encoded in the indices representing numbers, and where necessary, -clients are responsible for checking those errors. - -The encoding of errors is this: if an error happens, the value `0-error` is -returned. To decode, do the exact same thing. Thus, any index above -`0-num_errors` is an error. - -If an index that represents an error is passed to a math function, that function -propagates the error to its result and does not perform the math operation. - -All of this is to, once again, make it easy to implement the math code as above. - -However, where possible, errors are returned directly. - -[1]: https://en.wikipedia.org/wiki/Bus_factor -[2]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html#top -[3]: https://en.wikipedia.org/wiki/Dc_(Unix) -[4]: https://en.wikipedia.org/wiki/Reverse_Polish_notation -[5]: ./bc/A.1.md#standard-library -[6]: https://github.com/torvalds/linux/blob/master/kernel/time/timeconst.bc -[7]: ./bc/A.1.md#extended-library -[8]: #libbc-2 -[9]: #strgensh -[10]: https://vimeo.com/230142234 -[11]: https://gavinhoward.com/2019/12/values-for-yao/ -[12]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf -[13]: ./build.md#cross-compiling -[14]: ./build.md -[15]: #strgenc -[16]: http://landley.net/toybox/about.html -[17]: https://www.busybox.net/ -[18]: https://en.wikipedia.org/wiki/Karatsuba_algorithm -[19]: https://clang-analyzer.llvm.org/scan-build.html -[20]: https://www.valgrind.org/ -[21]: https://clang.llvm.org/docs/AddressSanitizer.html -[22]: https://gavinhoward.com/2019/11/finishing-software/ -[23]: #history -[24]: https://clang.llvm.org/docs/ClangFormat.html -[25]: ./algorithms.md -[26]: #lib2bc -[27]: #vmh -[28]: https://github.com/rain-1/linenoise-mob -[29]: https://github.com/antirez/linenoise -[30]: #bclh -[31]: #argsh -[32]: ../NEWS.md#3-0-0 -[33]: ../NEWS.md -[34]: https://github.com/skeeto/optparse -[35]: #opth -[36]: #historyh -[37]: #randh -[38]: #langh -[39]: #numc -[40]: #bcc -[41]: #bc_lexc -[42]: #bc_parsec -[43]: #libraryc -[44]: #dcc -[45]: #dc_lexc -[46]: #dc_parsec -[47]: #filec -[48]: #historyc -[49]: #langc -[50]: #lexc -[51]: #optc -[52]: #parsec -[53]: #programc -[54]: #randc -[55]: #fileh -[56]: #readc -[57]: #programh -[58]: #vmc -[59]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/gencat.html#top -[60]: #manpagesh -[61]: #bcl3md -[62]: #bcl3 -[63]: #bclvcxproj -[64]: #bclvcxprojfilters -[65]: #bclsln -[66]: #bcvcxproj -[67]: #bcvcxprojfilters -[68]: #bcsln -[69]: #configuresh -[70]: #makefilein -[71]: #functionsh -[72]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html#top -[73]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18 -[74]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html#top -[75]: #versionh -[76]: ##posix-shell-scripts -[77]: #tests -[78]: #karatsubapy -[79]: #bc-1 -[80]: #dc-1 -[81]: ./build.md#build-type -[82]: #fuzzing-1 -[83]: #releasesh -[84]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_02 -[85]: #locales-1 -[86]: #manuals-1 -[87]: #locale_installsh -[88]: #locale_uninstallsh -[89]: #bc1mdin -[90]: #dc1mdin -[91]: #bc -[92]: https://pandoc.org/ -[93]: #release_settingstxt -[94]: #aflpy -[95]: #randmathpy -[96]: #caching-of-numbers -[97]: #error-handling -[98]: #radamsatxt -[99]: https://gitlab.com/akihe/radamsa -[100]: #radamsash -[101]: https://musl.libc.org/ -[102]: ./build.md#settings -[103]: #test_settingstxt -[104]: #test_settingssh -[105]: #functionssh -[106]: #bch -[107]: https://en.wikipedia.org/wiki/Infix_notation -[108]: https://en.wikipedia.org/wiki/Reverse_Polish_notation -[109]: https://en.wikipedia.org/wiki/Shunting-yard_algorithm -[110]: #bc-parsing -[111]: #vectors -[112]: https://git.yzena.com/Yzena/Yc/src/branch/master/include/yc/vector.h -[113]: https://en.wikipedia.org/wiki/Signal_(IPC) -[114]: #custom-io -[115]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03 -[116]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setjmp.html -[117]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/longjmp.html -[118]: https://www.youtube.com/watch?v=4PaWFYm0kEw -[119]: #fuzz_prepsh -[120]: #bc_aflyaml -[121]: #bc_afl_continueyaml -[122]: https://github.com/tmux/tmux -[123]: https://tmuxp.git-pull.com/ -[124]: #test-suite -[125]: https://aflplus.plus/ -[126]: #link-time-optimization -[127]: #fuzzing-performance -[128]: #radamsa -[129]: #afl-quickstart -[130]: #convenience -[131]: #datac -[132]: https://git.yzena.com/gavin/vim-bc -[133]: https://git.yzena.com/gavin/bc_libs -[134]: #debugging -[135]: #asserts -[136]: #portability -[137]: https://pexpect.readthedocs.io/en/stable/ -[138]: #test-suite-portability -[139]: #historypy -[140]: #historysh -[141]: #group-tests -[142]: #build-system -[143]: #generated-tests -[144]: #benchmarks-1 -[145]: #gen -[146]: #test-coverage -[147]: #integration-with-the-build-system -[148]: #test-scripts -[149]: #standard-tests -[150]: #script-tests -[151]: #error-tests -[152]: #stdin-tests -[153]: #read-tests -[154]: #other-tests -[155]: #history-tests -[156]: #bcl -[157]: #bcl-test -[158]: #bclc -[159]: #valgrind -[160]: #addresssanitizer-and-friends -[161]: #bc-2 -[162]: #dc-2 -[163]: #alltxt-1 -[164]: #errorstxt -[165]: #posix_errorstxt -[166]: #timeconstsh -[167]: #alltxt-3 -[168]: #errorstxt-1 -[169]: #scripts-1 -[170]: #scripts-2 -[171]: #alltxt-2 -[172]: #alltxt-4 -[173]: #async-signal-safe-signal-handling -[174]: #vectorh -[175]: #read_errorstxt -[176]: #statush -[177]: #numbers -[178]: #math-style -[179]: #pseudo-random-number-generator -[180]: #lexh -[181]: #parseh -[182]: #dch -[183]: #libraryh -[184]: #numh -[185]: #readh -[186]: #maps -[187]: #slabs-and-slab-vectors -[188]: ./build.md#extra-math -[189]: #command-line-history -[190]: #scriptsed -[191]: #linux-timeconstbc-script -[192]: #corpuses -[193]: ./build.md#history -[194]: https://www.valgrind.org/docs/manual/mc-manual.html -[195]: #othersh -[196]: https://scan.coverity.com/ -[197]: https://clang-analyzer.llvm.org/ -[198]: https://unix.stackexchange.com/questions/253349/eintr-is-there-a-rationale-behind-it -[199]: https://cr.yp.to/docs/selfpipe.html -[200]: https://skarnet.org/cgi-bin/archive.cgi?2:mss:1607:201701:dfblejammjllfkggpcph -[201]: https://slembcke.github.io/2020/10/12/CustomAllocators.html#1-slab-allocator -[202]: https://en.wikipedia.org/wiki/Tail_call -[203]: https://en.wikipedia.org/wiki/Functional_programming_language -[204]: https://en.wikipedia.org/wiki/C_dynamic_memory_allocation -[205]: #mainc -[206]: #argc -[207]: https://en.wikipedia.org/wiki/Abstract_syntax_tree -[208]: #functions -[209]: #parsing -[210]: https://en.wikipedia.org/wiki/Stack_machine -[211]: https://en.wikipedia.org/wiki/Register_machine -[212]: #include -[213]: #src -[214]: https://gmplib.org/manual/Nomenclature-and-Types -[215]: https://en.wikipedia.org/wiki/Radix_point -[216]: #main-and-read-functions -[215]: https://www.pcg-random.org/ -[216]: https://lemire.me/blog/2017/08/22/testing-non-cryptographic-random-number-generators-my-results/ -[217]: https://en.wikipedia.org/wiki/Profile-guided_optimization -[218]: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fexpect -[219]: ./build.md#optimization -[220]: #benchmarksh -[221]: https://cgit.freebsd.org/src/tree/usr.bin/ministat/ministat.c -[222]: https://www.freebsd.org/cgi/man.cgi?query=ministat&apropos=0&sektion=0&manpath=FreeBSD+13.0-RELEASE+and+Ports&arch=default&format=html -[223]: #ministatc -[224]: #dc -[225]: #allsh -[226]: #errorssh -[227]: #errorsh diff --git a/manuals/header.txt b/manuals/header.txt deleted file mode 100644 index d805e14ad691..000000000000 --- a/manuals/header.txt +++ /dev/null @@ -1,27 +0,0 @@ -.\" -.\" 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. -.\" diff --git a/manuals/header_bc.txt b/manuals/header_bc.txt deleted file mode 100644 index fc2e6bdcb9c5..000000000000 --- a/manuals/header_bc.txt +++ /dev/null @@ -1 +0,0 @@ -.TH "BC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual" diff --git a/manuals/header_bcl.txt b/manuals/header_bcl.txt deleted file mode 100644 index 4b1c6974f3df..000000000000 --- a/manuals/header_bcl.txt +++ /dev/null @@ -1 +0,0 @@ -.TH "BCL" "3" "June 2021" "Gavin D. Howard" "Libraries Manual" diff --git a/manuals/header_dc.txt b/manuals/header_dc.txt deleted file mode 100644 index aad9e7cea50a..000000000000 --- a/manuals/header_dc.txt +++ /dev/null @@ -1 +0,0 @@ -.TH "DC" "1" "June 2021" "Gavin D. Howard" "General Commands Manual" diff --git a/manuals/release.md b/manuals/release.md deleted file mode 100644 index aa2de7ca9acb..000000000000 --- a/manuals/release.md +++ /dev/null @@ -1,72 +0,0 @@ -# Release Checklist - -This is the checklist for cutting a release. - -For a lot of these steps, they are only needed if the code that would be -affected was changed. For example, I don't need to run the `scripts/randmath.py` -test if I did not change any of the math code. - -1.	Update the README. -2.	Update the manuals. -3.	Test history manually. -4.	Test with POSIX test suite. -5.	Run the `scripts/randmath.py` script an excessive amount and add failing -	tests to test suite. -	* debug -	* release -	* minrelease -6.	Fuzz with AFL. -	* reldebug -7.	Fix AFL crashes. -8.	Find ASan crashes on AFL test cases. -9.	Fix ASan crashes. -10.	Build on Windows, no errors or warnings. -	* Debug/`x64`. -	* Debug/`x86`. -	* Release{MD,MT}/`x64`. -	* Release{MD,MT}/`x86`. -11.	Run and pass the `scripts/release.sh` script on my own machine. -12.	Run and pass the `scripts/release.sh` script, without generated tests and -	sanitizers, on FreeBSD. -13.	Run and pass the `scripts/release.sh` script, without generated tests, -	sanitizers, and 64-bit, on an ARM server. -14.	Run and pass the release script, with no generated tests, no clang, no -	sanitizers, and no valgrind, on NetBSD. -15.	Run and pass the release script, with no generated tests, no sanitizers, and -	no valgrind, on OpenBSD. -16.	Run `scan-build make`. -17.	Repeat steps 3-16 again and repeat until nothing is found. -18.	Update the benchmarks. -19.	Update the version and `NEWS.md` and commit. -20. Boot into Windows. -21. Build all release versions of everything. -	* Release/`x64` for `bc`. -	* Release/`x64` for `dc`. -	* Release{MD,MT}/`x64` for `bcl`. -	* Release/`x86` for `bc`. -	* Release/`x86` for `dc`. -	* Release{MD,MT}/`x86` for `bcl`. -22.	Put the builds where Linux can access them. -23. Boot back into Linux. -24.	Run `make clean_tests`. -25.	Run the `scripts/package.sh` script. -26.	Upload the custom tarball and Windows builds to Yzena Gitea. -27.	Add output from `scripts/package.sh` to Yzena Gitea release notes. -28.	Edit Yzena Gitea release notes for the changelog. -29.	Upload the custom tarball to GitHub. -30.	Add output from `scripts/package.sh` to GitHub release notes. -31.	Edit GitHub release notes for the changelog. -32.	Notify the following: -	* FreeBSD -	* Adelie Linux -	* Ataraxia Linux -	* Sabotage -	* xstatic -	* OpenBSD -	* NetBSD -33.	Submit new packages for the following: -	* Alpine Linux -	* Void Linux -	* Gentoo Linux -	* Linux from Scratch -	* Arch Linux diff --git a/scripts/afl.py b/scripts/afl.py deleted file mode 100755 index c4312ce84f83..000000000000 --- a/scripts/afl.py +++ /dev/null @@ -1,245 +0,0 @@ -#! /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 shutil -import subprocess - - -# Print the usage and exit with an error. -def usage(): -	print("usage: {} [--asan] dir [results_dir [exe options...]]".format(script)) -	print("       The valid values for dir are: 'bc1', 'bc2', 'bc3', and 'dc'.") -	sys.exit(1) - - -# Check for a crash. -# @param exebase  The calculator that crashed. -# @param out      The file to copy the crash file to. -# @param error    The error code (negative). -# @param file     The crash file. -# @param type     The type of run that caused the crash. This is just a string -#                 that would make sense to the user. -# @param test     The contents of the crash file, or which line caused the crash -#                 for a run through stdin. -def check_crash(exebase, out, error, file, type, test): -	if error < 0: -		print("\n{} crashed ({}) on {}:\n".format(exebase, -error, type)) -		print("    {}".format(test)) -		print("\nCopying to \"{}\"".format(out)) -		shutil.copy2(file, out) -		print("\nexiting...") -		sys.exit(error) - - -# Runs a test. This function is used to ensure that if a test times out, it is -# discarded. Otherwise, some tests result in incredibly long runtimes. We need -# to ignore those. -# -# @param cmd      The command to run. -# @param exebase  The calculator to test. -# @param tout     The timeout to use. -# @param indata   The data to push through stdin for the test. -# @param out      The file to copy the test file to if it causes a crash. -# @param file     The test file. -# @param type     The type of test. This is just a string that would make sense -#                 to the user. -# @param test     The test. It could be an entire file, or just one line. -# @param environ  The environment to run the command under. -def run_test(cmd, exebase, tout, indata, out, file, type, test, environ=None): -	try: -		p = subprocess.run(cmd, timeout=tout, input=indata, stdout=subprocess.PIPE, -		                   stderr=subprocess.PIPE, env=environ) -		check_crash(exebase, out, p.returncode, file, type, test) -	except subprocess.TimeoutExpired: -		print("\n    {} timed out. Continuing...\n".format(exebase)) - - -# Creates and runs a test. This basically just takes a file, runs it through the -# appropriate calculator as a whole file, then runs it through the calculator -# using stdin. -# @param file     The file to test. -# @param tout     The timeout to use. -# @param environ  The environment to run under. -def create_test(file, tout, environ=None): - -	print("    {}".format(file)) - -	base = os.path.basename(file) - -	if base == "README.txt": -		return - -	with open(file, "rb") as f: -		lines = f.readlines() - -	print("        Running whole file...") - -	run_test(exe + [ file ], exebase, tout, halt.encode(), out, file, "file", file, environ) - -	print("        Running file through stdin...") - -	with open(file, "rb") as f: -		content = f.read() - -	run_test(exe, exebase, tout, content, out, file, -	         "running {} through stdin".format(file), file, environ) - - -# Get the children of a directory. -# @param dir        The directory to get the children of. -# @param get_files  True if files should be gotten, false if directories should -#                   be gotten. -def get_children(dir, get_files): -	dirs = [] -	with os.scandir(dir) as it: -		for entry in it: -			if not entry.name.startswith('.') and     \ -			   ((entry.is_dir() and not get_files) or \ -			    (entry.is_file() and get_files)): -				dirs.append(entry.name) -	dirs.sort() -	return dirs - - -# Returns the correct executable name for the directory under test. -# @param d  The directory under test. -def exe_name(d): -	return "bc" if d == "bc1" or d == "bc2" or d == "bc3" else "dc" - - -# Housekeeping. -script = sys.argv[0] -scriptdir = os.path.dirname(script) - -# Must run this script alone. -if __name__ != "__main__": -	usage() - -timeout = 2.5 - -if len(sys.argv) < 2: -	usage() - -idx = 1 - -exedir = sys.argv[idx] - -asan = (exedir == "--asan") - -# We could possibly run under ASan. See later for what that means. -if asan: -	idx += 1 -	if len(sys.argv) < idx + 1: -		usage() -	exedir = sys.argv[idx] - -print("exedir: {}".format(exedir)) - -# Grab the correct directory of AFL++ results. -if len(sys.argv) >= idx + 2: -	resultsdir = sys.argv[idx + 1] -else: -	if exedir == "bc1": -		resultsdir = scriptdir + "/../tests/fuzzing/bc_outputs1" -	elif exedir == "bc2": -		resultsdir = scriptdir + "/../tests/fuzzing/bc_outputs2" -	elif exedir == "bc3": -		resultsdir = scriptdir + "/../tests/fuzzing/bc_outputs3" -	elif exedir == "dc": -		resultsdir = scriptdir + "/../tests/fuzzing/dc_outputs" -	else: -		raise ValueError("exedir must be either bc1, bc2, bc3, or dc"); - -print("resultsdir: {}".format(resultsdir)) - -# More command-line processing. -if len(sys.argv) >= idx + 3: -	exe = sys.argv[idx + 2] -else: -	exe = scriptdir + "/../bin/" + exe_name(exedir) - -exebase = os.path.basename(exe) - - -# Use the correct options. -if exebase == "bc": -	halt = "halt\n" -	options = "-lq" -	seed = ["-e", "seed = 1280937142.20981723890730892738902938071028973408912703984712093", "-f-" ] -else: -	halt = "q\n" -	options = "-x" -	seed = ["-e", "1280937142.20981723890730892738902938071028973408912703984712093j", "-f-" ] - -# More command-line processing. -if len(sys.argv) >= idx + 4: -	exe = [ exe, sys.argv[idx + 3:], options ] + seed -else: -	exe = [ exe, options ] + seed -for i in range(4, len(sys.argv)): -	exe.append(sys.argv[i]) - -out = scriptdir + "/../.test.txt" - -print(os.path.realpath(os.getcwd())) - -dirs = get_children(resultsdir, False) - -# Set the correct ASAN_OPTIONS. -if asan: -	env = os.environ.copy() -	env['ASAN_OPTIONS'] = 'abort_on_error=1:allocator_may_return_null=1' - -for d in dirs: - -	d = resultsdir + "/" + d - -	print(d) - -	# Check the crash files. -	files = get_children(d + "/crashes/", True) - -	for file in files: -		file = d + "/crashes/" + file -		create_test(file, timeout) - -	# If we are running under ASan, we want to check all files. Otherwise, skip. -	if not asan: -		continue - -	# Check all of the test cases found by AFL++. -	files = get_children(d + "/queue/", True) - -	for file in files: -		file = d + "/queue/" + file -		create_test(file, timeout * 2, env) - -print("Done") diff --git a/scripts/alloc.sh b/scripts/alloc.sh deleted file mode 100755 index c5c46febe0b3..000000000000 --- a/scripts/alloc.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/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 only really useful for running on Linux. It tests the code to -# free temps in order to make an allocation work. In order to see it work, I -# suggest adding code after the following line in src/vm.c: -# -# if (BC_ERR(ptr == NULL)) bc_vm_fatalError(BC_ERR_FATAL_ALLOC_ERR); -# -# The code you should add is the following: -# -# bc_file_printf(&vm.ferr, "If you see this, the code worked.\n"); -# bc_file_flush(&vm.ferr, bc_flush_none); -# -# If you do not see the that message printed, the code did not work. Or, in the -# case of some allocators, like jemalloc, the allocator just isn't great with -# turning a bunch of small allocations into a bigger allocation, - -script="$0" -scriptdir=$(dirname "$script") - -export LANG=C - -virtlimit=1000000 - -ulimit -v $virtlimit - -# This script is designed to allocate lots of memory with a lot of caching of -# numbers (the function f() specifically). Then, it's designed allocate one -# large number and grow it until allocation failure (the function g()). -"$scriptdir/../bin/bc" <<*EOF - -define f(i, n) { -	if (n == 0) return i; -	return f(i + 1, n - 1) -} - -define g(n) { -	t = (10^9)^(2^24) -	while (n) { -		n *= t -		print "success\n" -	} -} - -iterations=2000000 - -for (l=0; l < 100; l++) { -    iterations -    j = f(0, iterations$) -    iterations += 100000 -    print "here\n" -    n=10^235929600 -    g(n) -    print "success\n" -    n=0 -} -*EOF diff --git a/scripts/benchmark.sh b/scripts/benchmark.sh deleted file mode 100755 index 35f92452ce78..000000000000 --- a/scripts/benchmark.sh +++ /dev/null @@ -1,159 +0,0 @@ -#! /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 depends on the GNU time utility, but I am okay with that because -# this script is only for maintainers. - -# Just print the usage and exit with an error. -usage() { -	printf 'usage: %s [-n<runs>] [-p<pause>] dir benchmark...\n' "$0" 1>&2 -	printf '    -n runs is how many runs to run the benchmark, default 10.\n' -	printf '    -p pause is how many seconds to pause before running the benchmarks.\n' -	printf '\n' -	printf 'The fields are put in this order:\n' -	printf '1.  Elapsed Time\n' -	printf '2.  System Time\n' -	printf '3.  User Time\n' -	printf '4.  Max RSS\n' -	printf '5.  Average RSS\n' -	printf '6.  Average Total Memory Use\n' -	printf '7.  Average Unshared Data\n' -	printf '8.  Average Unshared Stack\n' -	printf '9.  Average Shared Text\n' -	printf '10. Major Page Faults\n' -	printf '11. Minor Page Faults\n' -	printf '12. Swaps\n' -	printf '13. Involuntary Context Switches\n' -	printf '14. Voluntary Context Switches\n' -	printf '15. Inputs\n' -	printf '16. Outputs\n' -	printf '17. Signals Delivered\n' -	exit 1 -} - -script="$0" -scriptdir=$(dirname "$script") - -runs=10 -pause=0 - -# Process command-line arguments. -while getopts "n:p:" opt; do - -	case "$opt" in -		n) runs="$OPTARG" ;; -		p) pause="$OPTARG" ;; -		?) usage "Invalid option: $opt" ;; -	esac - -done - -while [ "$#" -gt 0 ] && [ "$OPTIND" -gt 1 ]; do - -	OPTIND=$(bin/bc -e "$OPTIND - 1") -	shift - -done - -if [ "$#" -lt 2 ]; then -	usage -fi - -cd "$scriptdir/.." - -d="$1" -shift - -benchmarks="" - -# Create the list of benchmarks from the arguments. -while [ "$#" -gt 0 ]; do - -	if [ "$benchmarks" = "" ]; then -		benchmarks="$1" -	else -		benchmarks="$benchmarks $1" -	fi - -	shift -done - -files="" - -# Create the list of files from the benchmarks. -for b in $benchmarks; do - -	f=$(printf "benchmarks/%s/%s.txt" "$d" "$b") - -	if [ "$files" = "" ]; then -		files="$f" -	else -		files="$files $f" -	fi - -done - -if [ "$d" = "bc" ]; then -	opts="-lq" -	halt="halt" -else -	opts="-x" -	halt="q" -fi - -# Generate all of the benchmarks. -for b in $benchmarks; do - -	if [ ! -f "./benchmarks/$d/$b.txt" ]; then -		printf 'Benchmarking generation of benchmarks/%s/%s.txt...\n' "$d" "$b" >&2 -		printf '%s\n' "$halt" | /usr/bin/time -v bin/$d $opts "./benchmarks/$d/$b.$d" \ -			> "./benchmarks/$d/$b.txt" -	fi -done - -# We use this format to make things easier to use with ministat. -format="%e %S %U %M %t %K %D %p %X %F %R %W %c %w %I %O %k" - -printf 'Benchmarking %s...\n' "$files" >&2 - -if [ "$pause" -gt 0 ]; then -	sleep "$pause" -fi - -i=0 - -# Run the benchmarks as many times as told to. -while [ "$i" -lt "$runs" ]; do - -	printf '%s\n' "$halt" | /usr/bin/time -f "$format" bin/$d $opts $files 2>&1 > /dev/null - -	# Might as well use the existing bc. -	i=$(printf '%s + 1\n' "$i" | bin/bc) - -done diff --git a/scripts/bitfuncgen.c b/scripts/bitfuncgen.c deleted file mode 100644 index 8fae531b9286..000000000000 --- a/scripts/bitfuncgen.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * ***************************************************************************** - * - * 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. - * - * ***************************************************************************** - * - * A generator for bitwise operations test. - * - */ - -#include <assert.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <limits.h> - -#define NTESTS (100) - -/** - * Abort with an error message. - * @param msg  The error message. - */ -void err(const char *msg) { -	fprintf(stderr, "%s\n", msg); -	abort(); -} - -uint64_t rev(uint64_t a, size_t bits) { - -	size_t i; -	uint64_t res = 0; - -	for (i = 0; i < bits; ++i) { -		res <<= 1; -		res |= a & 1; -		a >>= 1; -	} - -	return res; -} - -uint64_t mod(uint64_t a, size_t bits) { - -	uint64_t mod; - -	if (bits < 64) mod = (uint64_t) ((1ULL << bits) - 1); -	else mod = UINT64_MAX; - -	return a & mod; -} - -uint64_t rol(uint64_t a, uint64_t p, size_t bits) { - -	uint64_t res; - -	assert(bits <= 64); - -	p %= bits; - -	if (!p) return a; - -	res = (a << p) | (a >> (bits - p)); - -	return mod(res, bits); -} - -uint64_t ror(uint64_t a, uint64_t p, size_t bits) { - -	uint64_t res; - -	assert(bits <= 64); - -	p %= bits; - -	if (!p) return a; - -	res = (a << (bits - p)) | (a >> p); - -	return mod(res, bits); -} - -int main(void) { - -	uint64_t a = 0, b = 0, t; -	size_t i; - -	// We attempt to open this or /dev/random to get random data. -	int fd = open("/dev/urandom", O_RDONLY); - -	if (fd < 0) { - -		fd = open("/dev/random", O_RDONLY); - -		if (fd < 0) err("cannot open a random number generator"); -	} - -	// Generate NTESTS tests. -	for (i = 0; i < NTESTS; ++i) { - -		ssize_t nread; - -		// Generate random data for the first operand. -		nread = read(fd, (char*) &a, sizeof(uint64_t)); -		if (nread != sizeof(uint64_t)) err("I/O error"); - -		// Generate random data for the second operand. -		nread = read(fd, (char*) &b, sizeof(uint64_t)); -		if (nread != sizeof(uint64_t)) err("I/O error"); - -		// Output the tests to stdout. -		printf("band(%lu, %lu)\n", a, b); -		printf("bor(%lu, %lu)\n", a, b); -		printf("bxor(%lu, %lu)\n", a, b); -		printf("bshl(%lu, %lu)\n", mod(a, 32), mod(b, 5)); -		printf("bshr(%lu, %lu)\n", mod(a, 32), mod(b, 5)); -		printf("bshl(%lu, %lu)\n", mod(b, 32), mod(a, 5)); -		printf("bshr(%lu, %lu)\n", mod(b, 32), mod(a, 5)); -		printf("bnot8(%lu)\nbnot8(%lu)\n", a, mod(a, 8)); -		printf("bnot16(%lu)\nbnot16(%lu)\n", a, mod(a, 16)); -		printf("bnot32(%lu)\nbnot32(%lu)\n", a, mod(a, 32)); -		printf("bnot64(%lu)\n", a); -		printf("brev8(%lu)\nbrev8(%lu)\n", a, mod(a, 8)); -		printf("brev16(%lu)\nbrev16(%lu)\n", a, mod(a, 16)); -		printf("brev32(%lu)\nbrev32(%lu)\n", a, mod(a, 32)); -		printf("brev64(%lu)\n", a); -		printf("brol8(%lu, %lu)\n", a, b); -		printf("brol8(%lu, %lu)\n", mod(a, 8), b); -		printf("brol8(%lu, %lu)\n", a, mod(b, 8)); -		printf("brol8(%lu, %lu)\n", mod(a, 8), mod(b, 8)); -		printf("brol16(%lu, %lu)\n", a, b); -		printf("brol16(%lu, %lu)\n", mod(a, 16), b); -		printf("brol16(%lu, %lu)\n", a, mod(b, 16)); -		printf("brol16(%lu, %lu)\n", mod(a, 16), mod(b, 16)); -		printf("brol32(%lu, %lu)\n", a, b); -		printf("brol32(%lu, %lu)\n", mod(a, 32), b); -		printf("brol32(%lu, %lu)\n", a, mod(b, 32)); -		printf("brol32(%lu, %lu)\n", mod(a, 32), mod(b, 32)); -		printf("brol64(%lu, %lu)\n", a, b); -		printf("bror8(%lu, %lu)\n", a, b); -		printf("bror8(%lu, %lu)\n", mod(a, 8), b); -		printf("bror8(%lu, %lu)\n", a, mod(b, 8)); -		printf("bror8(%lu, %lu)\n", mod(a, 8), mod(b, 8)); -		printf("bror16(%lu, %lu)\n", a, b); -		printf("bror16(%lu, %lu)\n", mod(a, 16), b); -		printf("bror16(%lu, %lu)\n", a, mod(b, 16)); -		printf("bror16(%lu, %lu)\n", mod(a, 16), mod(b, 16)); -		printf("bror32(%lu, %lu)\n", a, b); -		printf("bror32(%lu, %lu)\n", mod(a, 32), b); -		printf("bror32(%lu, %lu)\n", a, mod(b, 32)); -		printf("bror32(%lu, %lu)\n", mod(a, 32), mod(b, 32)); -		printf("bror64(%lu, %lu)\n", a, b); -		printf("bmod8(%lu)\nbmod8(%lu)\n", a, mod(a, 8)); -		printf("bmod16(%lu)\nbmod16(%lu)\n", a, mod(a, 16)); -		printf("bmod32(%lu)\nbmod32(%lu)\n", a, mod(a, 32)); -		printf("bmod64(%lu)\n", a); - -		// Output the results to stderr. -		fprintf(stderr, "%lu\n", a & b); -		fprintf(stderr, "%lu\n", a | b); -		fprintf(stderr, "%lu\n", a ^ b); -		fprintf(stderr, "%lu\n", mod(a, 32) << mod(b, 5)); -		fprintf(stderr, "%lu\n", mod(a, 32) >> mod(b, 5)); -		fprintf(stderr, "%lu\n", mod(b, 32) << mod(a, 5)); -		fprintf(stderr, "%lu\n", mod(b, 32) >> mod(a, 5)); -		t = mod(~a, 8); -		fprintf(stderr, "%lu\n%lu\n", t, t); -		t = mod(~a, 16); -		fprintf(stderr, "%lu\n%lu\n", t, t); -		t = mod(~a, 32); -		fprintf(stderr, "%lu\n%lu\n", t, t); -		fprintf(stderr, "%lu\n", ~a); -		t = rev(a, 8); -		fprintf(stderr, "%lu\n%lu\n", t, t); -		t = rev(a, 16); -		fprintf(stderr, "%lu\n%lu\n", t, t); -		t = rev(a, 32); -		fprintf(stderr, "%lu\n%lu\n", t, t); -		t = rev(a, 64); -		fprintf(stderr, "%lu\n", t); -		fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", rol(a, b, 64)); -		fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); -		fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); -		fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); -		fprintf(stderr, "%lu\n", ror(a, b, 64)); -		fprintf(stderr, "%lu\n%lu\n", mod(a, 8), mod(a, 8)); -		fprintf(stderr, "%lu\n%lu\n", mod(a, 16), mod(a, 16)); -		fprintf(stderr, "%lu\n%lu\n", mod(a, 32), mod(a, 32)); -		fprintf(stderr, "%lu\n", a); -	} - -	return 0; -} diff --git a/scripts/fuzz_prep.sh b/scripts/fuzz_prep.sh deleted file mode 100755 index 0441f94e340c..000000000000 --- a/scripts/fuzz_prep.sh +++ /dev/null @@ -1,81 +0,0 @@ -#! /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() { -	printf 'usage: %s [-a] [afl_compiler]\n' "$0" 1>&2 -	printf '\n' -	printf '       If -a is given, then an ASan ready build is created.\n' -	printf '       Otherwise, a normal fuzz build is created.\n' -	printf '       The ASan-ready build is for running under\n' -	printf '       `tests/afl.py --asan`, which checks that there were no\n' -	printf '       memory errors in any path found by the fuzzer.\n' -	printf '       It might also be useful to run scripts/randmath.py on an\n' -	printf '       ASan-ready binary.\n' -	exit 1 -} - -script="$0" -scriptdir=$(dirname "$script") - -asan=0 - -# Process command-line arguments. -while getopts "a" opt; do - -	case "$opt" in -		a) asan=1 ; shift ;; -		?) usage "Invalid option: $opt" ;; -	esac - -done - -if [ $# -lt 1 ]; then -	CC=afl-clang-lto -else -	CC="$1" -fi - -# We want this for extra sensitive crashing -AFL_HARDEN=1 - -cd "$scriptdir/.." - -set -e - -if [ "$asan" -ne 0 ]; then -	CFLAGS="-flto -fsanitize=address" -else -	CFLAGS="-flto" -fi - -# We want a debug build because asserts are counted as crashes too. -CC="$CC" CFLAGS="$CFLAGS" ./configure.sh -gO3 -z - -make -j16 diff --git a/scripts/manpage.sh b/scripts/manpage.sh deleted file mode 100755 index c1429a6ed51f..000000000000 --- a/scripts/manpage.sh +++ /dev/null @@ -1,175 +0,0 @@ -#! /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 the usage and exit with an error. -usage() { -	printf "usage: %s manpage\n" "$0" 1>&2 -	exit 1 -} - -# Generate a manpage and print it to a file. -# @param md   The markdown manual to generate a manpage for. -# @param out  The file to print the manpage to. -gen_manpage() { - -	_gen_manpage_md="$1" -	shift - -	_gen_manpage_out="$1" -	shift - -	cat "$manualsdir/header.txt" > "$_gen_manpage_out" -	cat "$manualsdir/header_${manpage}.txt" >> "$_gen_manpage_out" - -	pandoc -f commonmark_x -t man "$_gen_manpage_md" >> "$_gen_manpage_out" -} - -# Generate a manual from a template and print it to a file before generating -# its manpage. -# param args  The type of markdown manual to generate. This is a string that -#             corresponds to build type (see the Build Type section of the -#             manuals/build.md manual). -gen_manual() { - -	_gen_manual_args="$1" -	shift - -	# Set up some local variables. $manualsdir and $manpage from from the -	# variables outside the function. -	_gen_manual_status="$ALL" -	_gen_manual_out="$manualsdir/$manpage/$_gen_manual_args.1" -	_gen_manual_md="$manualsdir/$manpage/$_gen_manual_args.1.md" -	_gen_manual_temp="$manualsdir/temp.1.md" - -	# We need to set IFS, so we store it here for restoration later. -	_gen_manual_ifs="$IFS" - -	# Remove the files that will be generated. -	rm -rf "$_gen_manual_out" "$_gen_manual_md" - -	# Here is the magic. This loop reads the template line-by-line, and based on -	# _gen_manual_status, either prints it to the markdown manual or not. -	# -	# Here is how the template is set up: it is a normal markdown file except -	# that there are sections surrounded tags that look like this: -	# -	# {{ <build_type_list> }} -	# ... -	# {{ end }} -	# -	# Those tags mean that whatever build types are found in the -	# <build_type_list> get to keep that section. Otherwise, skip. -	# -	# Obviously, the tag itself and its end are not printed to the markdown -	# manual. -	while IFS= read -r line; do - -		# If we have found an end, reset the status. -		if [ "$line" = "{{ end }}" ]; then - -			# Some error checking. This helps when editing the templates. -			if [ "$_gen_manual_status" -eq "$ALL" ]; then -				err_exit "{{ end }} tag without corresponding start tag" 2 -			fi - -			_gen_manual_status="$ALL" - -		# We have found a tag that allows our build type to use it. -		elif [ "${line#\{\{* $_gen_manual_args *\}\}}" != "$line" ]; then - -			# More error checking. We don't want tags nested. -			if [ "$_gen_manual_status" -ne "$ALL" ]; then -				err_exit "start tag nested in start tag" 3 -			fi - -			_gen_manual_status="$NOSKIP" - -		# We have found a tag that is *not* allowed for our build type. -		elif [ "${line#\{\{*\}\}}" != "$line" ]; then - -			if [ "$_gen_manual_status" -ne "$ALL" ]; then -				err_exit "start tag nested in start tag" 3 -			fi - -			_gen_manual_status="$SKIP" - -		# This is for normal lines. If we are not skipping, print. -		else -			if [ "$_gen_manual_status" -ne "$SKIP" ]; then -				printf '%s\n' "$line" >> "$_gen_manual_temp" -			fi -		fi - -	done < "$manualsdir/${manpage}.1.md.in" - -	# Remove multiple blank lines. -	uniq "$_gen_manual_temp" "$_gen_manual_md" - -	# Remove the temp file. -	rm -rf "$_gen_manual_temp" - -	# Reset IFS. -	IFS="$_gen_manual_ifs" - -	# Generate the manpage. -	gen_manpage "$_gen_manual_md" "$_gen_manual_out" -} - -set -e - -script="$0" -scriptdir=$(dirname "$script") -manualsdir="$scriptdir/../manuals" - -. "$scriptdir/functions.sh" - -# Constants for use later. If the set of build types is changed, $ARGS must be -# updated. -ARGS="A E H N EH EN HN EHN" -ALL=0 -NOSKIP=1 -SKIP=2 - -# Process command-line arguments. -test "$#" -eq 1 || usage - -manpage="$1" -shift - -if [ "$manpage" != "bcl" ]; then - -	# Generate a manual and manpage for each build type. -	for a in $ARGS; do -		gen_manual "$a" -	done - -else -	# For bcl, just generate the manpage. -	gen_manpage "$manualsdir/${manpage}.3.md" "$manualsdir/${manpage}.3" -fi diff --git a/scripts/ministat.c b/scripts/ministat.c deleted file mode 100644 index e5b7cd47b3e4..000000000000 --- a/scripts/ministat.c +++ /dev/null @@ -1,675 +0,0 @@ -/*- - * SPDX-License-Identifier: Beerware - * - * ---------------------------------------------------------------------------- - * "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 - * ---------------------------------------------------------------------------- - * - */ - -#ifdef __GNU_LIBRARY__ -#include <sys/cdefs.h> -#endif // __GNU_LIBRARY__ - -#include <sys/ioctl.h> - -#ifdef __GNU_LIBRARY__ -#include <sys/queue.h> -#endif // __GNU_LIBRARY__ - -#include <assert.h> -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#define NSTUDENT 100 -#define NCONF 6 -static double const studentpct[] = { 80, 90, 95, 98, 99, 99.5 }; -static double const student[NSTUDENT + 1][NCONF] = { -/* inf */	{	1.282,	1.645,	1.960,	2.326,	2.576,	3.090  }, -/* 1. */	{	3.078,	6.314,	12.706,	31.821,	63.657,	318.313  }, -/* 2. */	{	1.886,	2.920,	4.303,	6.965,	9.925,	22.327  }, -/* 3. */	{	1.638,	2.353,	3.182,	4.541,	5.841,	10.215  }, -/* 4. */	{	1.533,	2.132,	2.776,	3.747,	4.604,	7.173  }, -/* 5. */	{	1.476,	2.015,	2.571,	3.365,	4.032,	5.893  }, -/* 6. */	{	1.440,	1.943,	2.447,	3.143,	3.707,	5.208  }, -/* 7. */	{	1.415,	1.895,	2.365,	2.998,	3.499,	4.782  }, -/* 8. */	{	1.397,	1.860,	2.306,	2.896,	3.355,	4.499  }, -/* 9. */	{	1.383,	1.833,	2.262,	2.821,	3.250,	4.296  }, -/* 10. */	{	1.372,	1.812,	2.228,	2.764,	3.169,	4.143  }, -/* 11. */	{	1.363,	1.796,	2.201,	2.718,	3.106,	4.024  }, -/* 12. */	{	1.356,	1.782,	2.179,	2.681,	3.055,	3.929  }, -/* 13. */	{	1.350,	1.771,	2.160,	2.650,	3.012,	3.852  }, -/* 14. */	{	1.345,	1.761,	2.145,	2.624,	2.977,	3.787  }, -/* 15. */	{	1.341,	1.753,	2.131,	2.602,	2.947,	3.733  }, -/* 16. */	{	1.337,	1.746,	2.120,	2.583,	2.921,	3.686  }, -/* 17. */	{	1.333,	1.740,	2.110,	2.567,	2.898,	3.646  }, -/* 18. */	{	1.330,	1.734,	2.101,	2.552,	2.878,	3.610  }, -/* 19. */	{	1.328,	1.729,	2.093,	2.539,	2.861,	3.579  }, -/* 20. */	{	1.325,	1.725,	2.086,	2.528,	2.845,	3.552  }, -/* 21. */	{	1.323,	1.721,	2.080,	2.518,	2.831,	3.527  }, -/* 22. */	{	1.321,	1.717,	2.074,	2.508,	2.819,	3.505  }, -/* 23. */	{	1.319,	1.714,	2.069,	2.500,	2.807,	3.485  }, -/* 24. */	{	1.318,	1.711,	2.064,	2.492,	2.797,	3.467  }, -/* 25. */	{	1.316,	1.708,	2.060,	2.485,	2.787,	3.450  }, -/* 26. */	{	1.315,	1.706,	2.056,	2.479,	2.779,	3.435  }, -/* 27. */	{	1.314,	1.703,	2.052,	2.473,	2.771,	3.421  }, -/* 28. */	{	1.313,	1.701,	2.048,	2.467,	2.763,	3.408  }, -/* 29. */	{	1.311,	1.699,	2.045,	2.462,	2.756,	3.396  }, -/* 30. */	{	1.310,	1.697,	2.042,	2.457,	2.750,	3.385  }, -/* 31. */	{	1.309,	1.696,	2.040,	2.453,	2.744,	3.375  }, -/* 32. */	{	1.309,	1.694,	2.037,	2.449,	2.738,	3.365  }, -/* 33. */	{	1.308,	1.692,	2.035,	2.445,	2.733,	3.356  }, -/* 34. */	{	1.307,	1.691,	2.032,	2.441,	2.728,	3.348  }, -/* 35. */	{	1.306,	1.690,	2.030,	2.438,	2.724,	3.340  }, -/* 36. */	{	1.306,	1.688,	2.028,	2.434,	2.719,	3.333  }, -/* 37. */	{	1.305,	1.687,	2.026,	2.431,	2.715,	3.326  }, -/* 38. */	{	1.304,	1.686,	2.024,	2.429,	2.712,	3.319  }, -/* 39. */	{	1.304,	1.685,	2.023,	2.426,	2.708,	3.313  }, -/* 40. */	{	1.303,	1.684,	2.021,	2.423,	2.704,	3.307  }, -/* 41. */	{	1.303,	1.683,	2.020,	2.421,	2.701,	3.301  }, -/* 42. */	{	1.302,	1.682,	2.018,	2.418,	2.698,	3.296  }, -/* 43. */	{	1.302,	1.681,	2.017,	2.416,	2.695,	3.291  }, -/* 44. */	{	1.301,	1.680,	2.015,	2.414,	2.692,	3.286  }, -/* 45. */	{	1.301,	1.679,	2.014,	2.412,	2.690,	3.281  }, -/* 46. */	{	1.300,	1.679,	2.013,	2.410,	2.687,	3.277  }, -/* 47. */	{	1.300,	1.678,	2.012,	2.408,	2.685,	3.273  }, -/* 48. */	{	1.299,	1.677,	2.011,	2.407,	2.682,	3.269  }, -/* 49. */	{	1.299,	1.677,	2.010,	2.405,	2.680,	3.265  }, -/* 50. */	{	1.299,	1.676,	2.009,	2.403,	2.678,	3.261  }, -/* 51. */	{	1.298,	1.675,	2.008,	2.402,	2.676,	3.258  }, -/* 52. */	{	1.298,	1.675,	2.007,	2.400,	2.674,	3.255  }, -/* 53. */	{	1.298,	1.674,	2.006,	2.399,	2.672,	3.251  }, -/* 54. */	{	1.297,	1.674,	2.005,	2.397,	2.670,	3.248  }, -/* 55. */	{	1.297,	1.673,	2.004,	2.396,	2.668,	3.245  }, -/* 56. */	{	1.297,	1.673,	2.003,	2.395,	2.667,	3.242  }, -/* 57. */	{	1.297,	1.672,	2.002,	2.394,	2.665,	3.239  }, -/* 58. */	{	1.296,	1.672,	2.002,	2.392,	2.663,	3.237  }, -/* 59. */	{	1.296,	1.671,	2.001,	2.391,	2.662,	3.234  }, -/* 60. */	{	1.296,	1.671,	2.000,	2.390,	2.660,	3.232  }, -/* 61. */	{	1.296,	1.670,	2.000,	2.389,	2.659,	3.229  }, -/* 62. */	{	1.295,	1.670,	1.999,	2.388,	2.657,	3.227  }, -/* 63. */	{	1.295,	1.669,	1.998,	2.387,	2.656,	3.225  }, -/* 64. */	{	1.295,	1.669,	1.998,	2.386,	2.655,	3.223  }, -/* 65. */	{	1.295,	1.669,	1.997,	2.385,	2.654,	3.220  }, -/* 66. */	{	1.295,	1.668,	1.997,	2.384,	2.652,	3.218  }, -/* 67. */	{	1.294,	1.668,	1.996,	2.383,	2.651,	3.216  }, -/* 68. */	{	1.294,	1.668,	1.995,	2.382,	2.650,	3.214  }, -/* 69. */	{	1.294,	1.667,	1.995,	2.382,	2.649,	3.213  }, -/* 70. */	{	1.294,	1.667,	1.994,	2.381,	2.648,	3.211  }, -/* 71. */	{	1.294,	1.667,	1.994,	2.380,	2.647,	3.209  }, -/* 72. */	{	1.293,	1.666,	1.993,	2.379,	2.646,	3.207  }, -/* 73. */	{	1.293,	1.666,	1.993,	2.379,	2.645,	3.206  }, -/* 74. */	{	1.293,	1.666,	1.993,	2.378,	2.644,	3.204  }, -/* 75. */	{	1.293,	1.665,	1.992,	2.377,	2.643,	3.202  }, -/* 76. */	{	1.293,	1.665,	1.992,	2.376,	2.642,	3.201  }, -/* 77. */	{	1.293,	1.665,	1.991,	2.376,	2.641,	3.199  }, -/* 78. */	{	1.292,	1.665,	1.991,	2.375,	2.640,	3.198  }, -/* 79. */	{	1.292,	1.664,	1.990,	2.374,	2.640,	3.197  }, -/* 80. */	{	1.292,	1.664,	1.990,	2.374,	2.639,	3.195  }, -/* 81. */	{	1.292,	1.664,	1.990,	2.373,	2.638,	3.194  }, -/* 82. */	{	1.292,	1.664,	1.989,	2.373,	2.637,	3.193  }, -/* 83. */	{	1.292,	1.663,	1.989,	2.372,	2.636,	3.191  }, -/* 84. */	{	1.292,	1.663,	1.989,	2.372,	2.636,	3.190  }, -/* 85. */	{	1.292,	1.663,	1.988,	2.371,	2.635,	3.189  }, -/* 86. */	{	1.291,	1.663,	1.988,	2.370,	2.634,	3.188  }, -/* 87. */	{	1.291,	1.663,	1.988,	2.370,	2.634,	3.187  }, -/* 88. */	{	1.291,	1.662,	1.987,	2.369,	2.633,	3.185  }, -/* 89. */	{	1.291,	1.662,	1.987,	2.369,	2.632,	3.184  }, -/* 90. */	{	1.291,	1.662,	1.987,	2.368,	2.632,	3.183  }, -/* 91. */	{	1.291,	1.662,	1.986,	2.368,	2.631,	3.182  }, -/* 92. */	{	1.291,	1.662,	1.986,	2.368,	2.630,	3.181  }, -/* 93. */	{	1.291,	1.661,	1.986,	2.367,	2.630,	3.180  }, -/* 94. */	{	1.291,	1.661,	1.986,	2.367,	2.629,	3.179  }, -/* 95. */	{	1.291,	1.661,	1.985,	2.366,	2.629,	3.178  }, -/* 96. */	{	1.290,	1.661,	1.985,	2.366,	2.628,	3.177  }, -/* 97. */	{	1.290,	1.661,	1.985,	2.365,	2.627,	3.176  }, -/* 98. */	{	1.290,	1.661,	1.984,	2.365,	2.627,	3.175  }, -/* 99. */	{	1.290,	1.660,	1.984,	2.365,	2.626,	3.175  }, -/* 100. */	{	1.290,	1.660,	1.984,	2.364,	2.626,	3.174  } -}; - -#define	MAX_DS	8 -static char symbol[MAX_DS] = { ' ', 'x', '+', '*', '%', '#', '@', 'O' }; - -struct dataset { -	char *name; -	double	*points; -	size_t lpoints; -	double sy, syy; -	size_t n; -}; - -static struct dataset * -NewSet(void) -{ -	struct dataset *ds; - -	ds = calloc(1, sizeof *ds); -	assert(ds != NULL); -	ds->lpoints = 100000; -	ds->points = calloc(sizeof *ds->points, ds->lpoints); -	assert(ds->points != NULL); -	ds->syy = NAN; -	return(ds); -} - -static void -AddPoint(struct dataset *ds, double a) -{ -	double *dp; - -	if (ds->n >= ds->lpoints) { -		dp = ds->points; -		ds->lpoints *= 4; -		ds->points = calloc(sizeof *ds->points, ds->lpoints); -		assert(ds->points != NULL); -		memcpy(ds->points, dp, sizeof *dp * ds->n); -		free(dp); -	} -	ds->points[ds->n++] = a; -	ds->sy += a; -} - -static double -Min(const struct dataset *ds) -{ - -	return (ds->points[0]); -} - -static double -Max(const struct dataset *ds) -{ - -	return (ds->points[ds->n -1]); -} - -static double -Avg(const struct dataset *ds) -{ - -	return(ds->sy / ds->n); -} - -static double -Median(const struct dataset *ds) -{ -	const size_t m = ds->n / 2; - -	if ((ds->n % 2) == 0) -		return ((ds->points[m] + (ds->points[m - 1])) / 2); -	return (ds->points[m]); -} - -static double -Var(struct dataset *ds) -{ -	size_t z; -	const double a = Avg(ds); - -	if (isnan(ds->syy)) { -		ds->syy = 0.0; -		for (z = 0; z < ds->n; z++) -			ds->syy += (ds->points[z] - a) * (ds->points[z] - a); -	} - -	return (ds->syy / (ds->n - 1.0)); -} - -static double -Stddev(struct dataset *ds) -{ - -	return sqrt(Var(ds)); -} - -static void -VitalsHead(void) -{ - -	printf("    N           Min           Max        Median           Avg        Stddev\n"); -} - -static void -Vitals(struct dataset *ds, int flag) -{ - -	printf("%c %3zu %13.8g %13.8g %13.8g %13.8g %13.8g", symbol[flag], -	    ds->n, Min(ds), Max(ds), Median(ds), Avg(ds), Stddev(ds)); -	printf("\n"); -} - -static void -Relative(struct dataset *ds, struct dataset *rs, int confidx) -{ -	double spool, s, d, e, t; -	double re; -	size_t z; - -	z = ds->n + rs->n - 2; -	if (z > NSTUDENT) -		t = student[0][confidx]; -	else -		t = student[z][confidx]; -	spool = (ds->n - 1) * Var(ds) + (rs->n - 1) * Var(rs); -	spool /= ds->n + rs->n - 2; -	spool = sqrt(spool); -	s = spool * sqrt(1.0 / ds->n + 1.0 / rs->n); -	d = Avg(ds) - Avg(rs); -	e = t * s; - -	re = (ds->n - 1) * Var(ds) + (rs->n - 1) * Var(rs) * -	    (Avg(ds) * Avg(ds)) / (Avg(rs) * Avg(rs)); -	re *= (ds->n + rs->n) / (ds->n * rs->n * (ds->n + rs->n - 2.0)); -	re = t * sqrt(re); - -	if (fabs(d) > e) { -		printf("Difference at %.1f%% confidence\n", studentpct[confidx]); -		printf("	%g +/- %g\n", d, e); -		printf("	%g%% +/- %g%%\n", d * 100 / Avg(rs), re * 100 / Avg(rs)); -		printf("	(Student's t, pooled s = %g)\n", spool); -	} else { -		printf("No difference proven at %.1f%% confidence\n", -		    studentpct[confidx]); -	} -} - -struct plot { -	double		min; -	double		max; -	double		span; -	int		width; - -	double		x0, dx; -	size_t		height; -	char		*data; -	char		**bar; -	int		separate_bars; -	int		num_datasets; -}; - -static struct plot plot; - -static void -SetupPlot(int width, int separate, int num_datasets) -{ -	struct plot *pl; - -	pl = &plot; -	pl->width = width; -	pl->height = 0; -	pl->data = NULL; -	pl->bar = NULL; -	pl->separate_bars = separate; -	pl->num_datasets = num_datasets; -	pl->min = 999e99; -	pl->max = -999e99; -} - -static void -AdjPlot(double a) -{ -	struct plot *pl; - -	pl = &plot; -	if (a < pl->min) -		pl->min = a; -	if (a > pl->max) -		pl->max = a; -	pl->span = pl->max - pl->min; -	pl->dx = pl->span / (pl->width - 1.0); -	pl->x0 = pl->min - .5 * pl->dx; -} - -static void -DimPlot(struct dataset *ds) -{ -	AdjPlot(Min(ds)); -	AdjPlot(Max(ds)); -	AdjPlot(Avg(ds) - Stddev(ds)); -	AdjPlot(Avg(ds) + Stddev(ds)); -} - -static void -PlotSet(struct dataset *ds, int val) -{ -	struct plot *pl; -	int i, x; -	size_t m, j, z; -	size_t n; -	int bar; -	double av, sd; - -	pl = &plot; -	if (pl->span == 0) -		return; - -	if (pl->separate_bars) -		bar = val-1; -	else -		bar = 0; - -	if (pl->bar == NULL) { -		pl->bar = calloc(sizeof(char *), pl->num_datasets); -		assert(pl->bar != NULL); -	} - -	if (pl->bar[bar] == NULL) { -		pl->bar[bar] = malloc(pl->width); -		assert(pl->bar[bar] != NULL); -		memset(pl->bar[bar], 0, pl->width); -	} - -	m = 1; -	i = -1; -	j = 0; -	/* Set m to max(j) + 1, to allocate required memory */ -	for (n = 0; n < ds->n; n++) { -		x = (ds->points[n] - pl->x0) / pl->dx; -		if (x == i) { -			j++; -			if (j > m) -				m = j; -		} else { -			j = 1; -			i = x; -		} -	} -	m += 1; -	if (m > pl->height) { -		pl->data = realloc(pl->data, pl->width * m); -		assert(pl->data != NULL); -		memset(pl->data + pl->height * pl->width, 0, -		    (m - pl->height) * pl->width); -	} -	pl->height = m; -	i = -1; -	for (n = 0; n < ds->n; n++) { -		x = (ds->points[n] - pl->x0) / pl->dx; -		if (x == i) { -			j++; -		} else { -			j = 1; -			i = x; -		} -		pl->data[j * pl->width + x] |= val; -	} -	av = Avg(ds); -	sd = Stddev(ds); -	if (!isnan(sd)) { -		x = ((av - sd) - pl->x0) / pl->dx; -		m = ((av + sd) - pl->x0) / pl->dx; -		pl->bar[bar][m] = '|'; -		pl->bar[bar][x] = '|'; -		for (z = x + 1; z < m; z++) -			if (pl->bar[bar][z] == 0) -				pl->bar[bar][z] = '_'; -	} -	x = (Median(ds) - pl->x0) / pl->dx; -	pl->bar[bar][x] = 'M'; -	x = (av - pl->x0) / pl->dx; -	pl->bar[bar][x] = 'A'; -} - -static void -DumpPlot(void) -{ -	struct plot *pl; -	int i, j, k; -	size_t z; - -	pl = &plot; -	if (pl->span == 0) { -		printf("[no plot, span is zero width]\n"); -		return; -	} - -	putchar('+'); -	for (i = 0; i < pl->width; i++) -		putchar('-'); -	putchar('+'); -	putchar('\n'); -	for (z = 1; z < pl->height; z++) { -		putchar('|'); -		for (j = 0; j < pl->width; j++) { -			k = pl->data[(pl->height - z) * pl->width + j]; -			if (k >= 0 && k < MAX_DS) -				putchar(symbol[k]); -			else -				printf("[%02x]", k); -		} -		putchar('|'); -		putchar('\n'); -	} -	for (i = 0; i < pl->num_datasets; i++) { -		if (pl->bar[i] == NULL) -			continue; -		putchar('|'); -		for (j = 0; j < pl->width; j++) { -			k = pl->bar[i][j]; -			if (k == 0) -				k = ' '; -			putchar(k); -		} -		putchar('|'); -		putchar('\n'); -	} -	putchar('+'); -	for (i = 0; i < pl->width; i++) -		putchar('-'); -	putchar('+'); -	putchar('\n'); -} - -static int -dbl_cmp(const void *a, const void *b) -{ -	const double *aa = a; -	const double *bb = b; - -	if (*aa < *bb) -		return (-1); -	else if (*aa > *bb) -		return (1); -	else -		return (0); -} - -static struct dataset * -ReadSet(FILE *f, const char *n, int column, const char *delim) -{ -	char buf[BUFSIZ], *p, *t; -	struct dataset *s; -	double d; -	int line; -	int i; - -	s = NewSet(); -	s->name = strdup(n); -	assert(s->name != NULL); -	line = 0; -	while (fgets(buf, sizeof buf, f) != NULL) { -		line++; - -		i = strlen(buf); -		while (i > 0 && isspace(buf[i - 1])) -			buf[--i] = '\0'; -		for (i = 1, t = strtok(buf, delim); -		     t != NULL && *t != '#'; -		     i++, t = strtok(NULL, delim)) { -			if (i == column) -				break; -		} -		if (t == NULL || *t == '#') -			continue; - -		d = strtod(t, &p); -		if (p != NULL && *p != '\0') -			errx(2, "Invalid data on line %d in %s", line, n); -		if (*buf != '\0') -			AddPoint(s, d); -	} -	if (s->n < 3) { -		fprintf(stderr, -		    "Dataset %s must contain at least 3 data points\n", n); -		exit (2); -	} -	qsort(s->points, s->n, sizeof *s->points, dbl_cmp); -	return (s); -} - -static void -usage(char const *whine) -{ -	int i; - -	fprintf(stderr, "%s\n", whine); -	fprintf(stderr, -	    "Usage: ministat [-C column] [-c confidence] [-d delimiter(s)] [-Ans] [-w width] [file [file ...]]\n"); -	fprintf(stderr, "\tconfidence = {"); -	for (i = 0; i < NCONF; i++) { -		fprintf(stderr, "%s%g%%", -		    i ? ", " : "", -		    studentpct[i]); -	} -	fprintf(stderr, "}\n"); -	fprintf(stderr, "\t-A : print statistics only. suppress the graph.\n"); -	fprintf(stderr, "\t-C : column number to extract (starts and defaults to 1)\n"); -	fprintf(stderr, "\t-d : delimiter(s) string, default to \" \\t\"\n"); -	fprintf(stderr, "\t-n : print summary statistics only, no graph/test\n"); -	fprintf(stderr, "\t-s : print avg/median/stddev bars on separate lines\n"); -	fprintf(stderr, "\t-w : width of graph/test output (default 74 or terminal width)\n"); -	exit (2); -} - -int -main(int argc, char **argv) -{ -	const char *setfilenames[MAX_DS - 1]; -	struct dataset *ds[MAX_DS - 1]; -	FILE *setfiles[MAX_DS - 1]; -	int nds; -	double a; -	const char *delim = " \t"; -	char *p; -	int c, i, ci; -	int column = 1; -	int flag_s = 0; -	int flag_n = 0; -	int termwidth = 74; -	int suppress_plot = 0; - -	if (isatty(STDOUT_FILENO)) { -		struct winsize wsz; - -		if ((p = getenv("COLUMNS")) != NULL && *p != '\0') -			termwidth = atoi(p); -		else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &wsz) != -1 && -			 wsz.ws_col > 0) -			termwidth = wsz.ws_col - 2; -	} - -	ci = -1; -	while ((c = getopt(argc, argv, "AC:c:d:snw:")) != -1) -		switch (c) { -		case 'A': -			suppress_plot = 1; -			break; -		case 'C': -			column = strtol(optarg, &p, 10); -			if (p != NULL && *p != '\0') -				usage("Invalid column number."); -			if (column <= 0) -				usage("Column number should be positive."); -			break; -		case 'c': -			a = strtod(optarg, &p); -			if (p != NULL && *p != '\0') -				usage("Not a floating point number"); -			for (i = 0; i < NCONF; i++) -				if (a == studentpct[i]) -					ci = i; -			if (ci == -1) -				usage("No support for confidence level"); -			break; -		case 'd': -			if (*optarg == '\0') -				usage("Can't use empty delimiter string"); -			delim = optarg; -			break; -		case 'n': -			flag_n = 1; -			break; -		case 's': -			flag_s = 1; -			break; -		case 'w': -			termwidth = strtol(optarg, &p, 10); -			if (p != NULL && *p != '\0') -				usage("Invalid width, not a number."); -			if (termwidth < 0) -				usage("Unable to move beyond left margin."); -			break; -		default: -			usage("Unknown option"); -			break; -		} -	if (ci == -1) -		ci = 2; -	argc -= optind; -	argv += optind; - -	if (argc == 0) { -		setfilenames[0] = "<stdin>"; -		setfiles[0] = stdin; -		nds = 1; -	} else { -		if (argc > (MAX_DS - 1)) -			usage("Too many datasets."); -		nds = argc; -		for (i = 0; i < nds; i++) { -			setfilenames[i] = argv[i]; -			if (!strcmp(argv[i], "-")) -				setfiles[0] = stdin; -			else -				setfiles[i] = fopen(argv[i], "r"); -			if (setfiles[i] == NULL) -				err(2, "Cannot open %s", argv[i]); -		} -	} - -	for (i = 0; i < nds; i++) { -		ds[i] = ReadSet(setfiles[i], setfilenames[i], column, delim); -		if (setfiles[i] != stdin) -			fclose(setfiles[i]); -	} - -	for (i = 0; i < nds; i++) -		printf("%c %s\n", symbol[i+1], ds[i]->name); - -	if (!flag_n && !suppress_plot) { -		SetupPlot(termwidth, flag_s, nds); -		for (i = 0; i < nds; i++) -			DimPlot(ds[i]); -		for (i = 0; i < nds; i++) -			PlotSet(ds[i], i + 1); -		DumpPlot(); -	} -	VitalsHead(); -	Vitals(ds[0], 1); -	for (i = 1; i < nds; i++) { -		Vitals(ds[i], i + 1); -		if (!flag_n) -			Relative(ds[i], ds[0], ci); -	} -	exit(0); -} diff --git a/scripts/package.sh b/scripts/package.sh deleted file mode 100755 index e3a35b0fe65d..000000000000 --- a/scripts/package.sh +++ /dev/null @@ -1,261 +0,0 @@ -#!/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 requires some non-POSIX utilities, but that's okay because it's -# really for maintainer use only. -# -# The non-POSIX utilities include: -# -# * git -# * stat -# * tar -# * gzip -# * xz -# * sha512sum -# * sha256sum -# * gpg -# * zip -# * unzip - -shasum() { - -	f="$1" -	shift - -	# All this fancy stuff takes the sha512 and sha256 sums and signs it. The -	# output after this point is what I usually copy into the release notes. -	# (See manuals/release.md for more information.) -	printf '$ sha512sum %s\n' "$f" -	sha512sum "$f" -	printf '\n' -	printf '$ sha256sum %s\n' "$f" -	sha256sum "$f" -	printf '\n' -	printf "$ stat -c '%%s  %%n'\n" "$f" -	stat -c '%s  %n' "$f" - -	if [ -f "$f.sig" ]; then -		rm -f "$f.sig" -	fi - -	gpg --detach-sig -o "$f.sig" "$f" 2> /dev/null - -	printf '\n' -	printf '$ sha512sum %s.sig\n' "$f" -	sha512sum "$f.sig" -	printf '\n' -	printf '$ sha256sum %s.sig\n' "$f" -	sha256sum "$f.sig" -	printf '\n' -	printf "$ stat -c '%%s  %%n'\n" "$f.sig" -	stat -c '%s  %n' "$f.sig" -} - -script="$0" -scriptdir=$(dirname "$script") - -repo="$scriptdir/.." -proj="bc" - -cd "$repo" - -if [ ! -f "../vs.zip" ]; then -	printf 'Must have Windows builds!\n' -	exit 1 -fi - -# We want the absolute path for later. -repo=$(pwd) - -# This convoluted mess does pull the version out. If you change the format of -# include/version.h, you may have to change this line. -version=$(cat include/version.h | grep "VERSION " - | awk '{ print $3 }' -) - -tag_msg="Version $version" -projver="${proj}-${version}" - -tempdir="/tmp/${projver}" -rm -rf $tempdir -mkdir -p $tempdir - -make clean_tests > /dev/null 2> /dev/null - -# Delete the tag and recreate it. This is the part of the script that makes it -# so you cannot run it twice on the same version, unless you know what you are -# doing. In fact, you cannot run it again if users have already started to use -# the old version of the tag. -if git rev-parse "$version" > /dev/null 2>&1; then -	git push --delete origin "$version" > /dev/null 2> /dev/null -	git tag --delete "$version" > /dev/null 2> /dev/null -fi - -git push > /dev/null 2> /dev/null -git tg "$version" -m "$tag_msg" > /dev/null 2> /dev/null -git push --tags > /dev/null 2> /dev/null - -# This line grabs the names of all of the files in .gitignore that still exist. -ignores=$(git check-ignore * **/*) - -cp -r ./* "$tempdir" - -cd $tempdir - -# Delete all the ignored files. -for i in $ignores; do -	rm -rf "./$i" -done - -# This is a list of files that end users (including *software packagers* and -# *distro maintainers*!) do not care about. In particular, they *do* care about -# the testing infrastructure for the regular test suite because distro -# maintainers probably want to ensure the test suite runs. However, they -# probably don't care about fuzzing or other randomized testing. Also, I -# technically can't distribute tests/bc/scripts/timeconst.bc because it's from -# the Linux kernel, which is GPL. -extras=$(cat <<*EOF -.git/ -.gitignore -.gitattributes -benchmarks/ -manuals/bc.1.md.in -manuals/dc.1.md.in -manuals/benchmarks.md -manuals/development.md -manuals/header_bcl.txt -manuals/header_bc.txt -manuals/header_dc.txt -manuals/header.txt -manuals/release.md -scripts/afl.py -scripts/alloc.sh -scripts/benchmark.sh -scripts/bitfuncgen.c -scripts/fuzz_prep.sh -scripts/manpage.sh -scripts/ministat.c -scripts/package.sh -scripts/radamsa.sh -scripts/radamsa.txt -scripts/randmath.py -scripts/release_settings.txt -scripts/release.sh -scripts/test_settings.sh -scripts/test_settings.txt -tests/bc_outputs/ -tests/dc_outputs/ -tests/fuzzing/ -tests/bc/scripts/timeconst.bc -*EOF -) - -for i in $extras; do -	rm -rf "./$i" -done - -cd .. - -parent="$repo/.." - -# Cleanup old stuff. -if [ -f "$projver.tar.gz" ]; then -	rm -rf "$projver.tar.gz" -fi - -if [ -f "$projver.tar.gz.sig" ]; then -	rm -rf "$projver.tar.gz.sig" -fi - -if [ -f "$projver.tar.xz" ]; then -	rm -rf "$projver.tar.xz" -fi - -if [ -f "$projver.tar.xz.sig" ]; then -	rm -rf "$projver.tar.xz.sig" -fi - -# Tar and compress and move into the parent directory of the repo. -tar cf "$projver.tar" "$projver/" -gzip -k "$projver.tar" -mv "$projver.tar.gz" "$parent" -xz -z -v -9 -e "$projver.tar" > /dev/null 2> /dev/null -mv "$projver.tar.xz" "$parent" - -cd "$parent" - -# Clean up old Windows stuff. -if [ -d windows ]; then -	rm -rf windows -fi - -if [ -f windows.zip ]; then -	rm -rf $projver-windows.zip -fi - -# Prepare Windows stuff. -unzip vs.zip > /dev/null -mv vs windows - -# Remove unneeded Windows stuff. -rm -rf windows/*.vcxproj.user -rm -rf windows/src2 -rm -rf windows/tests -rm -rf windows/*.sln -rm -rf windows/*.vcxproj -rm -rf windows/*.vcxproj.filters - -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/*.obj -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/*.iobj -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.exe.recipe -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.ilk -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.log -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.tlog -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.pdb -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.ipdb -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.vcxproj.FileListAbsolute.txt -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/strgen.exe -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/vc142.idb -rm -rf windows/bin/{Win32,x64}/{Debug,Release}/vc142.pdb - -rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/*.obj -rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.lib.recipe -rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.log -rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.tlog -rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.idb -rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.pdb -rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.vcxproj.FileListAbsolute.txt - -# Zip the Windows stuff. -zip -r $projver-windows.zip windows > /dev/null - -printf '\n' -shasum "$projver.tar.gz" -printf '\n' -shasum "$projver.tar.xz" -printf '\n' -shasum "$projver-windows.zip" diff --git a/scripts/radamsa.sh b/scripts/radamsa.sh deleted file mode 100755 index c92923ddadc4..000000000000 --- a/scripts/radamsa.sh +++ /dev/null @@ -1,133 +0,0 @@ -#! /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 uses some non-POSIX behavior, but since it's meant for bc -# maintainers only, I can accept that. - -# Get an entry from the file. If an argument exists, it is an index. Get that -# line. Otherwise, get a random line. -getentry() { - -	# Figure out if we get a specific or random line. -	if [ $# -gt 0 ]; then -		entnum="$1" -	else -		entnum=0 -	fi - -	# Get data from stdin and figure out how many lines there are. -	e=$(cat -) -	num=$(printf '%s\n' "$e" | wc -l) - -	# Figure out what line we are going to get. Uses bc's own PRNG. -	if [ "$entnum" -eq 0 ]; then -		rand=$(printf 'irand(%s) + 1\n' "$num" | "$bcdir/bc") -	else -		rand="$entnum" -	fi - -	# Get the line. -	ent=$(printf '%s\n' "$e" | tail -n +$rand | head -n 1) - -	printf '%s\n' "$ent" -} - -script="$0" -dir=$(dirname "$script") - -. "$dir/functions.sh" - -# Command-line processing. -if [ "$#" -lt 1 ]; then -	printf 'usage: %s dir\n' "$0" -	exit 1 -fi - -d="$1" -shift - -bcdir="$dir/../bin" - -# Figure out the correct input directory. -if [ "$d" = "bc" ]; then -	inputs="$dir/../tests/fuzzing/bc_inputs1" -	opts="-lq" -elif [ "$d" = "dc" ]; then -	inputs="$dir/../test/fuzzing/dc_inputs" -	opts="-x" -else -	err_exit "wrong type of executable" 1 -fi - -export ASAN_OPTIONS="abort_on_error=1:allocator_may_return_null=1" - -entries=$(cat "$dir/radamsa.txt") - -IFS=$'\n' - -go=1 - -# Infinite loop. -while [ "$go" -ne 0 ]; do - -	# If we are running bc, fuzz command-line arguments in BC_ENV_ARGS. -	if [ "$d" = "bc" ]; then - -		entry=$(cat -- "$dir/radamsa.txt" | getentry) -		items=$(printf '%s\n' "$entry" | radamsa -n 10) - -		printf '%s\n' "$items" - -		for i in `seq 1 10`; do - -			item=$(printf '%s\n' "$items" | getentry "$i") - -			export BC_ENV_ARGS="$item" -			echo 'halt' | "$bcdir/$d" -			err=$? - -			checkcrash "$d" "$err" "radamsa env args: \"$item\"" -		done - -	fi - -	f=$(ls "$inputs" | getentry) -	l=$(cat "$inputs/$f" | wc -l) -	ll=$(printf '%s^2\n' "$l" | bc) - -	# Fuzz on the AFL++ inputs. -	for i in $(seq 1 2); do -		data=$(cat "$inputs/$f" | radamsa -n 1) -		printf '%s\n' "$data" > "$dir/../.log_${d}_test.txt" -		printf '%s\n' "$data" | timeout -s SIGTERM 5 "$bcdir/$d" "$opts" > /dev/null -		err=$? -		checkcrash "$d" "$err" "radamsa stdin" -	done - -done diff --git a/scripts/radamsa.txt b/scripts/radamsa.txt deleted file mode 100644 index 4bf28907bead..000000000000 --- a/scripts/radamsa.txt +++ /dev/null @@ -1,17 +0,0 @@ --lq '/home/gavin/.bcrc' --lq "/home/gavin/.bcrc" --lqg '/home/gavin/bc stuff.bc' --lqg "/home/gavin/bc stuff.bc" --lqg '/home/gavin/"bc" stuff.bc' --lqg "/home/gavin/'bc' stuff.bc" --lqg '/home/gavin/bc stuff.bc --lqg "/home/gavin/bc stuff.bc --lqg '/home/gavin/"bc" stuff.bc --lqg "/home/gavin/'bc' stuff.bc ---mathlib --expand ---file="/home/gavin/.bcrc" ---file=/home/gavin/.bcrc ---file="/home/gavin/bc stuff.bc" ---file ---expression "4+4" --e "irand(128)" -f /home/gavin/.bcrc diff --git a/scripts/randmath.py b/scripts/randmath.py deleted file mode 100755 index 896f0e46c97f..000000000000 --- a/scripts/randmath.py +++ /dev/null @@ -1,421 +0,0 @@ -#! /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, errno -import random -import sys -import subprocess - -# I want line length to *not* affect differences between the two, so I set it -# as high as possible. -env = { -	"BC_LINE_LENGTH": "65535", -	"DC_LINE_LENGTH": "65535" -} - - -# Generate a random integer between 0 and 2^limit. -# @param limit  The power of two for the upper limit. -def gen(limit=4): -	return random.randint(0, 2 ** (8 * limit)) - - -# Returns a random boolean for whether a number should be negative or not. -def negative(): -	return random.randint(0, 1) == 1 - - -# Returns a random boolean for whether a number should be 0 or not. I decided to -# have it be 0 every 2^4 times since sometimes it is used to make a number less -# than 1. -def zero(): -	return random.randint(0, 2 ** (4) - 1) == 0 - - -# Generate a real portion of a number. -def gen_real(): - -	# Figure out if we should have a real portion. If so generate it. -	if negative(): -		n = str(gen(25)) -		length = gen(7 / 8) -		if len(n) < length: -			n = ("0" * (length - len(n))) + n -	else: -		n = "0" - -	return n - - -# Generates a number (as a string) based on the parameters. -# @param op     The operation under test. -# @param neg    Whether the number can be negative. -# @param real   Whether the number can be a non-integer. -# @param z      Whether the number can be zero. -# @param limit  The power of 2 upper limit for the number. -def num(op, neg, real, z, limit=4): - -	# Handle zero first. -	if z: -		z = zero() -	else: -		z = False - -	if z: -		# Generate a real portion maybe -		if real: -			n = gen_real() -			if n != "0": -				return "0." + n -		return "0" - -	# Figure out if we should be negative. -	if neg: -		neg = negative() - -	# Generate the integer portion. -	g = gen(limit) - -	# Figure out if we should have a real number. negative() is used to give a -	# 50/50 chance of getting a negative number. -	if real: -		n = gen_real() -	else: -		n = "0" - -	# Generate the string. -	g = str(g) -	if n != "0": -		g = g + "." + n - -	# Make sure to use the right negative sign. -	if neg and g != "0": -		if op != modexp: -			g = "-" + g -		else: -			g = "_" + g - -	return g - - -# Add a failed test to the list. -# @param test  The test that failed. -# @param op    The operation for the test. -def add(test, op): -	tests.append(test) -	gen_ops.append(op) - - -# Compare the output between the two. -# @param exe       The executable under test. -# @param options   The command-line options. -# @param p         The object returned from subprocess.run() for the calculator -#                  under test. -# @param test      The test. -# @param halt      The halt string for the calculator under test. -# @param expected  The expected result. -# @param op        The operation under test. -# @param do_add    If true, add a failing test to the list, otherwise, don't. -def compare(exe, options, p, test, halt, expected, op, do_add=True): - -	# Check for error from the calculator under test. -	if p.returncode != 0: - -		print("    {} returned an error ({})".format(exe, p.returncode)) - -		if do_add: -			print("    adding to checklist...") -			add(test, op) - -		return - -	actual = p.stdout.decode() - -	# Check for a difference in output. -	if actual != expected: - -		if op >= exponent: - -			# This is here because GNU bc, like mine can be flaky on the -			# functions in the math library. This is basically testing if adding -			# 10 to the scale works to make them match. If so, the difference is -			# only because of that. -			indata = "scale += 10; {}; {}".format(test, halt) -			args = [ exe, options ] -			p2 = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) -			expected = p2.stdout[:-10].decode() - -			if actual == expected: -				print("    failed because of bug in other {}".format(exe)) -				print("    continuing...") -				return - -		# Do the correct output for the situation. -		if do_add: -			print("   failed; adding to checklist...") -			add(test, op) -		else: -			print("   failed {}".format(test)) -			print("    expected:") -			print("        {}".format(expected)) -			print("    actual:") -			print("        {}".format(actual)) - - -# Generates a test for op. I made sure that there was no clashing between -# calculators. Each calculator is responsible for certain ops. -# @param op  The operation to test. -def gen_test(op): - -	# First, figure out how big the scale should be. -	scale = num(op, False, False, True, 5 / 8) - -	# Do the right thing for each op. Generate the test based on the format -	# string and the constraints of each op. For example, some ops can't accept -	# 0 in some arguments, and some must have integers in some arguments. -	if op < div: -		s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, True)) -	elif op == div or op == mod: -		s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, False)) -	elif op == power: -		s = fmts[op].format(scale, num(op, True, True, True, 7 / 8), num(op, True, False, True, 6 / 8)) -	elif op == modexp: -		s = fmts[op].format(scale, num(op, True, False, True), num(op, True, False, True), -		                    num(op, True, False, False)) -	elif op == sqrt: -		s = "1" -		while s == "1": -			s = num(op, False, True, True, 1) -		s = fmts[op].format(scale, s) -	else: - -		if op == exponent: -			first = num(op, True, True, True, 6 / 8) -		elif op == bessel: -			first = num(op, False, True, True, 6 / 8) -		else: -			first = num(op, True, True, True) - -		if op != bessel: -			s = fmts[op].format(scale, first) -		else: -			s = fmts[op].format(scale, first, 6 / 8) - -	return s - - -# Runs a test with number t. -# @param t  The number of the test. -def run_test(t): - -	# Randomly select the operation. -	op = random.randrange(bessel + 1) - -	# Select the right calculator. -	if op != modexp: -		exe = "bc" -		halt = "halt" -		options = "-lq" -	else: -		exe = "dc" -		halt = "q" -		options = "" - -	# Generate the test. -	test = gen_test(op) - -	# These don't work very well for some reason. -	if "c(0)" in test or "scale = 4; j(4" in test: -		return - -	# Make sure the calculator will halt. -	bcexe = exedir + "/" + exe -	indata = test + "\n" + halt - -	print("Test {}: {}".format(t, test)) - -	# Only bc has options. -	if exe == "bc": -		args = [ exe, options ] -	else: -		args = [ exe ] - -	# Run the GNU bc. -	p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) - -	output1 = p.stdout.decode() - -	# Error checking for GNU. -	if p.returncode != 0 or output1 == "": -		print("    other {} returned an error ({}); continuing...".format(exe, p.returncode)) -		return - -	if output1 == "\n": -		print("   other {} has a bug; continuing...".format(exe)) -		return - -	# Don't know why GNU has this problem... -	if output1 == "-0\n": -		output1 = "0\n" -	elif output1 == "-0": -		output1 = "0" - -	args = [ bcexe, options ] - -	# Run this bc/dc and compare. -	p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) -	compare(exe, options, p, test, halt, output1, op) - - -# This script must be run by itself. -if __name__ != "__main__": -	sys.exit(1) - -script = sys.argv[0] -testdir = os.path.dirname(script) - -exedir = testdir + "/../bin" - -# The following are tables used to generate numbers. - -# The operations to test. -ops = [ '+', '-', '*', '/', '%', '^', '|' ] - -# The functions that can be tested. -funcs = [ "sqrt", "e", "l", "a", "s", "c", "j" ] - -# The files (corresponding to the operations with the functions appended) to add -# tests to if they fail. -files = [ "add", "subtract", "multiply", "divide", "modulus", "power", "modexp", -          "sqrt", "exponent", "log", "arctangent", "sine", "cosine", "bessel" ] - -# The format strings corresponding to each operation and then each function. -fmts = [ "scale = {}; {} + {}", "scale = {}; {} - {}", "scale = {}; {} * {}", -         "scale = {}; {} / {}", "scale = {}; {} % {}", "scale = {}; {} ^ {}", -         "{}k {} {} {}|pR", "scale = {}; sqrt({})", "scale = {}; e({})", -         "scale = {}; l({})", "scale = {}; a({})", "scale = {}; s({})", -         "scale = {}; c({})", "scale = {}; j({}, {})" ] - -# Constants to make some code easier later. -div = 3 -mod = 4 -power = 5 -modexp = 6 -sqrt = 7 -exponent = 8 -bessel = 13 - -gen_ops = [] -tests = [] - -# Infinite loop until the user sends SIGINT. -try: -	i = 0 -	while True: -		run_test(i) -		i = i + 1 -except KeyboardInterrupt: -	pass - -# This is where we start processing the checklist of possible failures. Why only -# possible failures? Because some operations, specifically the functions in the -# math library, are not guaranteed to be exactly correct. Because of that, we -# need to present every failed test to the user for a final check before we -# add them as test cases. - -# No items, just exit. -if len(tests) == 0: -	print("\nNo items in checklist.") -	print("Exiting") -	sys.exit(0) - -print("\nGoing through the checklist...\n") - -# Just do some error checking. If this fails here, it's a bug in this script. -if len(tests) != len(gen_ops): -	print("Corrupted checklist!") -	print("Exiting...") -	sys.exit(1) - -# Go through each item in the checklist. -for i in range(0, len(tests)): - -	# Yes, there's some code duplication. Sue me. - -	print("\n{}".format(tests[i])) - -	op = int(gen_ops[i]) - -	if op != modexp: -		exe = "bc" -		halt = "halt" -		options = "-lq" -	else: -		exe = "dc" -		halt = "q" -		options = "" - -	# We want to run the test again to show the user the difference. -	indata = tests[i] + "\n" + halt - -	args = [ exe, options ] - -	p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) - -	expected = p.stdout.decode() - -	bcexe = exedir + "/" + exe -	args = [ bcexe, options ] - -	p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) - -	compare(exe, options, p, tests[i], halt, expected, op, False) - -	# Ask the user to make a decision on the failed test. -	answer = input("\nAdd test ({}/{}) to test suite? [y/N]: ".format(i + 1, len(tests))) - -	# Quick and dirty answer parsing. -	if 'Y' in answer or 'y' in answer: - -		print("Yes") - -		name = testdir + "/" + exe + "/" + files[op] - -		# Write the test to the test file and the expected result to the -		# results file. -		with open(name + ".txt", "a") as f: -			f.write(tests[i] + "\n") - -		with open(name + "_results.txt", "a") as f: -			f.write(expected) - -	else: -		print("No") - -print("Done!") diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index 02d3dd5dae24..000000000000 --- a/scripts/release.sh +++ /dev/null @@ -1,811 +0,0 @@ -#! /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. -# - -# For OpenBSD, run using the following: -# -# scripts/release.sh 1 0 1 0 0 0 0 1 0 0 0 0 0 0 -# -# For FreeBSD, run using the following: -# -# scripts/release.sh 1 0 1 0 0 0 0 1 0 1 0 0 0 0 -# -# There is one problem with running this script on FreeBSD: it takes overcommit -# to the extreme. This means that some tests that try to create allocation -# failures instead make bc and dc crash. So running this script on FreeBSD does -# not work right now. -# -# For Linux, run two separate ones (in different checkouts), like so: -# -# scripts/release.sh 1 1 1 0 1 0 0 1 0 1 0 1 0 0 -# cd build; ../scripts/release.sh 1 1 0 1 0 1 0 1 0 1 0 0 1 1 -# -# Yes, I usually do sanitizers with Clang and Valgrind with GCC, and I also do -# out-of-source builds with GCC. -# -# To run sanitizers or Valgrind with generated tests, use the following: -# -# scripts/release.sh 1 1 1 0 1 0 0 1 0 1 0 1 0 0 -# cd build; ../scripts/release.sh 1 1 0 1 0 1 0 1 0 1 0 0 1 1 -# -# The reason I run history tests with GCC and not with Clang is because Clang -# already runs slower as a result of running with sanitizers, and the history -# tests are a little sensitive to load on a system. -# -# If this script fails on any platform when starting the Karatsuba test, check -# that Python is installed, especially if the error says something like: -# "karatsuba.py: not found". - -# Print the usage and exit with an error. Each parameter should be an integer. -# Non-zero activates, and zero deactivates. -usage() { -	printf 'usage: %s [run_tests] [generate_tests] [test_with_clang] [test_with_gcc] \n' "$script" -	printf '          [run_sanitizers] [run_valgrind] [test_settings] [run_64_bit] \n' -	printf '          [run_gen_script] [test_c11] [test_128_bit] [test_computed_goto]\n' -	printf '          [test_karatsuba] [test_history]\n' -	exit 1 -} - -# Print a header with a message. This is just to make it easy to track progress. -# @param msg  The message to print in the header. -header() { - -	_header_msg="$1" -	shift - -	printf '\n' -	printf '*******************\n' -	printf "$_header_msg" -	printf '\n' -	printf '*******************\n' -	printf '\n' -} - -# Easy way to call make. -do_make() { -	# No reason to do 64 except to see if I actually can overload my system. :) -	# Well, also that it might actually improve throughput as other jobs can run -	# while some are waiting. -	make -j64 "$@" -} - -# Run configure.sh. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param GEN_HOST         The setting for GEN_HOST. -# @param LONG_BIT         The setting for LONG_BIT. -configure() { - -	_configure_CFLAGS="$1" -	shift - -	_configure_CC="$1" -	shift - -	_configure_configure_flags="$1" -	shift - -	_configure_GEN_HOST="$1" -	shift - -	_configure_LONG_BIT="$1" -	shift - -	# Make sure to not generate tests if necessary. -	if [ "$gen_tests" -eq 0 ]; then -		_configure_configure_flags="-G $_configure_configure_flags" -	fi - -	# Choose the right extra flags. -	if [ "$_configure_CC" = "clang" ]; then -		_configure_CFLAGS="$clang_flags $_configure_CFLAGS" -	elif [ "$_configure_CC" = "gcc" ]; then -		_configure_CFLAGS="$gcc_flags $_configure_CFLAGS" -	fi - -	# Print the header and do the job. -	_configure_header=$(printf 'Running configure.sh %s ...' "$_configure_configure_flags") -	_configure_header=$(printf "$_configure_header\n    CC=\"%s\"\n" "$_configure_CC") -	_configure_header=$(printf "$_configure_header\n    CFLAGS=\"%s\"\n" "$_configure_CFLAGS") -	_configure_header=$(printf "$_configure_header\n    LONG_BIT=%s" "$_configure_LONG_BIT") -	_configure_header=$(printf "$_configure_header\n    GEN_HOST=%s" "$_configure_GEN_HOST") - -	header "$_configure_header" -	CFLAGS="$_configure_CFLAGS" CC="$_configure_CC" GEN_HOST="$_configure_GEN_HOST" \ -		LONG_BIT="$_configure_LONG_BIT" "$real/configure.sh" $_configure_configure_flags > /dev/null -} - -# Build with make. This function also captures and outputs any warnings if they -# exists because as far as I am concerned, warnings are not acceptable for -# release. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param GEN_HOST         The setting for GEN_HOST. -# @param LONG_BIT         The setting for LONG_BIT. -build() { - -	_build_CFLAGS="$1" -	shift - -	_build_CC="$1" -	shift - -	_build_configure_flags="$1" -	shift - -	_build_GEN_HOST="$1" -	shift - -	_build_LONG_BIT="$1" -	shift - -	configure "$_build_CFLAGS" "$_build_CC" "$_build_configure_flags" "$_build_GEN_HOST" "$_build_LONG_BIT" - -	_build_header=$(printf 'Building...\n    CC=%s' "$_build_CC") -	_build_header=$(printf "$_build_header\n    CFLAGS=\"%s\"" "$_build_CFLAGS") -	_build_header=$(printf "$_build_header\n    LONG_BIT=%s" "$_build_LONG_BIT") -	_build_header=$(printf "$_build_header\n    GEN_HOST=%s" "$_build_GEN_HOST") - -	header "$_build_header" - -	# Capture and print warnings. -	do_make > /dev/null 2> "./.test.txt" - -	if [ -s "./.test.txt" ]; then -		printf '%s generated warning(s):\n' "$_build_CC" -		printf '\n' -		cat "./.test.txt" -		exit 1 -	fi -} - -# Run tests with make. -runtest() { - -	header "Running tests" - -	if [ "$#" -gt 0 ]; then -		do_make "$@" -	else - -		do_make test - -		if [ "$test_history" -ne 0 ]; then -			do_make test_history -		fi -	fi -} - -# Builds and runs tests with both calculators, then bc only, then dc only. If -# run_tests is false, then it just does the builds. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param GEN_HOST         The setting for GEN_HOST. -# @param LONG_BIT         The setting for LONG_BIT. -# @param run_tests        Whether to run tests or not. -runconfigtests() { - -	_runconfigtests_CFLAGS="$1" -	shift - -	_runconfigtests_CC="$1" -	shift - -	_runconfigtests_configure_flags="$1" -	shift - -	_runconfigtests_GEN_HOST="$1" -	shift - -	_runconfigtests_LONG_BIT="$1" -	shift - -	_runconfigtests_run_tests="$1" -	shift - -	if [ "$_runconfigtests_run_tests" -ne 0 ]; then -		_runconfigtests_header=$(printf 'Running tests with configure flags') -	else -		_runconfigtests_header=$(printf 'Building with configure flags') -	fi - -	_runconfigtests_header=$(printf "$_runconfigtests_header \"%s\" ...\n" "$_runconfigtests_configure_flags") -	_runconfigtests_header=$(printf "$_runconfigtests_header\n    CC=%s\n" "$_runconfigseries_CC") -	_runconfigtests_header=$(printf "$_runconfigtests_header\n    CFLAGS=\"%s\"" "$_runconfigseries_CFLAGS") -	_runconfigtests_header=$(printf "$_runconfigtests_header\n    LONG_BIT=%s" "$_runconfigtests_LONG_BIT") -	_runconfigtests_header=$(printf "$_runconfigtests_header\n    GEN_HOST=%s" "$_runconfigtests_GEN_HOST") - -	header "$_runconfigtests_header" - -	build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ -		"$_runconfigtests_configure_flags" "$_runconfigtests_GEN_HOST" \ -		"$_runconfigtests_LONG_BIT" - -	if [ "$_runconfigtests_run_tests" -ne 0 ]; then -		runtest -	fi - -	do_make clean - -	build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ -		"$_runconfigtests_configure_flags -b" "$_runconfigtests_GEN_HOST" \ -		"$_runconfigtests_LONG_BIT" - -	if [ "$_runconfigtests_run_tests" -ne 0 ]; then -		runtest -	fi - -	do_make clean - -	build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ -		"$_runconfigtests_configure_flags -d" "$_runconfigtests_GEN_HOST" \ -		"$_runconfigtests_LONG_BIT" - -	if [ "$_runconfigtests_run_tests" -ne 0 ]; then -		runtest -	fi - -	do_make clean -} - -# Builds and runs tests with runconfigtests(), but also does 64-bit, 32-bit, and -# 128-bit rand, if requested. It also does it with the gen script (strgen.sh) if -# requested. If run_tests is false, it just does the builds. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param run_tests        Whether to run tests or not. -runconfigseries() { - -	_runconfigseries_CFLAGS="$1" -	shift - -	_runconfigseries_CC="$1" -	shift - -	_runconfigseries_configure_flags="$1" -	shift - -	_runconfigseries_run_tests="$1" -	shift - -	if [ "$run_64_bit" -ne 0 ]; then - -		if [ "$test_128_bit" -ne 0 ]; then -			runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ -				"$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" -		fi - -		if [ "$run_gen_script" -ne 0 ]; then -			runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ -				"$_runconfigseries_configure_flags" 0 64 "$_runconfigseries_run_tests" -		fi - -		runconfigtests "$_runconfigseries_CFLAGS -DBC_RAND_BUILTIN=0" "$_runconfigseries_CC" \ -			"$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" - -	fi - -	runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ -		"$_runconfigseries_configure_flags" 1 32 "$_runconfigseries_run_tests" - -	if [ "$run_gen_script" -ne 0 ]; then -		runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ -			"$_runconfigseries_configure_flags" 0 32 "$_runconfigseries_run_tests" -	fi -} - -# Builds and runs tests with each setting combo running runconfigseries(). If -# run_tests is false, it just does the builds. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param run_tests        Whether to run tests or not. -runsettingsseries() { - -	_runsettingsseries_CFLAGS="$1" -	shift - -	_runsettingsseries_CC="$1" -	shift - -	_runsettingsseries_configure_flags="$1" -	shift - -	_runsettingsseries_run_tests="$1" -	shift - -	if [ "$test_settings" -ne 0 ]; then - -		while read _runsettingsseries_s; do -			runconfigseries "$_runsettingsseries_CFLAGS" "$_runsettingsseries_CC" \ -				"$_runsettingsseries_configure_flags $_runsettingsseries_s" \ -				"$_runsettingsseries_run_tests" -		done < "$scriptdir/release_settings.txt" - -	else -		runconfigseries "$_runsettingsseries_CFLAGS" "$_runsettingsseries_CC" \ -			"$_runsettingsseries_configure_flags" "$_runsettingsseries_run_tests" -	fi -} - -# Builds and runs tests with each build type running runsettingsseries(). If -# run_tests is false, it just does the builds. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param run_tests        Whether to run tests or not. -runtestseries() { - -	_runtestseries_CFLAGS="$1" -	shift - -	_runtestseries_CC="$1" -	shift - -	_runtestseries_configure_flags="$1" -	shift - -	_runtestseries_run_tests="$1" -	shift - -	_runtestseries_flags="E H N EH EN HN EHN" - -	runsettingsseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ -		"$_runtestseries_configure_flags" "$_runtestseries_run_tests" - -	for _runtestseries_f in $_runtestseries_flags; do -		runsettingsseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ -			"$_runtestseries_configure_flags -$_runtestseries_f" "$_runtestseries_run_tests" -	done -} - -# Builds and runs the tests for bcl. If run_tests is false, it just does the -# builds. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param run_tests        Whether to run tests or not. -runlibtests() { - -	_runlibtests_CFLAGS="$1" -	shift - -	_runlibtests_CC="$1" -	shift - -	_runlibtests_configure_flags="$1" -	shift - -	_runlibtests_run_tests="$1" -	shift - -	_runlibtests_configure_flags="$_runlibtests_configure_flags -a" - -	build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 64 - -	if [ "$_runlibtests_run_tests" -ne 0 ]; then -		runtest test -	fi - -	build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 32 - -	if [ "$_runlibtests_run_tests" -ne 0 ]; then -		runtest test -	fi -} - -# Builds and runs tests under C99, then C11, if requested, using -# runtestseries(). If run_tests is false, it just does the builds. -# @param CFLAGS           The CFLAGS. -# @param CC               The C compiler. -# @param configure_flags  The flags for configure.sh itself. -# @param run_tests        Whether to run tests or not. -runtests() { - -	_runtests_CFLAGS="$1" -	shift - -	_runtests_CC="$1" -	shift - -	_runtests_configure_flags="$1" -	shift - -	_runtests_run_tests="$1" -	shift - -	runtestseries "-std=c99 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" - -	if [ "$test_c11" -ne 0 ]; then -		runtestseries "-std=c11 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" -	fi -} - -# Runs the karatsuba tests. -karatsuba() { - -	header "Running Karatsuba tests" -	do_make karatsuba_test -} - -# Builds and runs under valgrind. It runs both, bc only, then dc only. -vg() { - -	header "Running valgrind" - -	if [ "$run_64_bit" -ne 0 ]; then -		_vg_bits=64 -	else -		_vg_bits=32 -	fi - -	build "$debug -std=c99" "gcc" "-O3 -gv" "1" "$_vg_bits" -	runtest test - -	do_make clean_config - -	build "$debug -std=c99" "gcc" "-O3 -gvb" "1" "$_vg_bits" -	runtest test - -	do_make clean_config - -	build "$debug -std=c99" "gcc" "-O3 -gvd" "1" "$_vg_bits" -	runtest test - -	do_make clean_config - -	build "$debug -std=c99" "gcc" "-O3 -gva" "1" "$_vg_bits" -	runtest test - -	do_make clean_config -} - -# Builds the debug series and runs the tests if run_tests allows. If sanitizers -# are enabled, it also does UBSan. -# @param CC         The C compiler. -# @param run_tests  Whether to run tests or not. -debug() { - -	_debug_CC="$1" -	shift - -	_debug_run_tests="$1" -	shift - - -	if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then -		runtests "$debug -fsanitize=undefined" "$_debug_CC" "-gm" "$_debug_run_tests" -	else -		runtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" -	fi - - -	if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then -		runlibtests "$debug -fsanitize=undefined" "$_debug_CC" "-gm" "$_debug_run_tests" -	else -		runlibtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" -	fi -} - -# Builds the release series and runs the test if run_tests allows. -# @param CC         The C compiler. -# @param run_tests  Whether to run tests or not. -release() { - -	_release_CC="$1" -	shift - -	_release_run_tests="$1" -	shift - -	runtests "$release" "$_release_CC" "-O3" "$_release_run_tests" - -	runlibtests "$release" "$_release_CC" "-O3" "$_release_run_tests" -} - -# Builds the release debug series and runs the test if run_tests allows. If -# sanitizers are enabled, it also does ASan and MSan. -# @param CC         The C compiler. -# @param run_tests  Whether to run tests or not. -reldebug() { - -	_reldebug_CC="$1" -	shift - -	_reldebug_run_tests="$1" -	shift - - -	if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then -		runtests "$debug -fsanitize=address" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" -		runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" -	else -		runtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" -	fi - - -	if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then -		runlibtests "$debug -fsanitize=address" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" -		runlibtests "$debug -fsanitize=memory" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" -	else -		runlibtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" -	fi -} - -# Builds the min size release series and runs the test if run_tests allows. -# @param CC         The C compiler. -# @param run_tests  Whether to run tests or not. -minsize() { - -	_minsize_CC="$1" -	shift - -	_minsize_run_tests="$1" -	shift - -	runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" - -	runlibtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" -} - -# Builds all sets: debug, release, release debug, and min size, and runs the -# tests if run_tests allows. -# @param CC         The C compiler. -# @param run_tests  Whether to run tests or not. -build_set() { - -	_build_set_CC="$1" -	shift - -	_build_set_run_tests="$1" -	shift - -	debug "$_build_set_CC" "$_build_set_run_tests" -	release "$_build_set_CC" "$_build_set_run_tests" -	reldebug "$_build_set_CC" "$_build_set_run_tests" -	minsize "$_build_set_CC" "$_build_set_run_tests" -} - -# Set some strict warning flags. Clang's -Weverything can be way too strict, so -# we actually have to turn off some things. -clang_flags="-Weverything -Wno-padded -Wno-switch-enum -Wno-format-nonliteral" -clang_flags="$clang_flags -Wno-cast-align -Wno-missing-noreturn -Wno-disabled-macro-expansion" -clang_flags="$clang_flags -Wno-unreachable-code -Wno-unreachable-code-return" -clang_flags="$clang_flags -Wno-implicit-fallthrough -Wno-unused-macros -Wno-gnu-label-as-value" -clang_flags="$clang_flags -Wno-declaration-after-statement" -# -Wno-undef is here because Clang seems to think BC_C11 is undefined, when it's defined. -clang_flags="$clang_flags -Wno-undef" -gcc_flags="-Wno-maybe-uninitialized -Wno-clobbered" - -# Common CFLAGS. -cflags="-Wall -Wextra -Werror -pedantic -Wno-conditional-uninitialized" - -# Common debug and release flags. -debug="$cflags -fno-omit-frame-pointer" -release="$cflags -DNDEBUG" - -set -e - -script="$0" -scriptdir=$(dirname "$script") - -real=$(realpath "$scriptdir/../") - -# Whether to run tests. -if [ "$#" -gt 0 ]; then -	run_tests="$1" -	shift -else -	run_tests=1 -fi - -# Whether to generate tests. On platforms like OpenBSD, there is no GNU bc to -# generate tests, so this must be off. -if [ "$#" -gt 0 ]; then -	gen_tests="$1" -	shift -else -	gen_tests=1 -fi - -# Whether to test with clang. -if [ "$#" -gt 0 ]; then -	test_with_clang="$1" -	shift -else -	test_with_clang=1 -fi - -# Whether to test with gcc. -if [ "$#" -gt 0 ]; then -	test_with_gcc="$1" -	shift -else -	test_with_gcc=1 -fi - -# Whether to test with sanitizers. -if [ "$#" -gt 0 ]; then -	run_sanitizers="$1" -	shift -else -	run_sanitizers=1 -fi - -# Whether to test with valgrind. -if [ "$#" -gt 0 ]; then -	run_valgrind="$1" -	shift -else -	run_valgrind=1 -fi - -# Whether to test all settings combos. -if [ "$#" -gt 0 ]; then -	test_settings="$1" -	shift -else -	test_settings=1 -fi - -# Whether to test 64-bit in addition to 32-bit. -if [ "$#" -gt 0 ]; then -	run_64_bit="$1" -	shift -else -	run_64_bit=1 -fi - -# Whether to test with strgen.sh in addition to strgen.c. -if [ "$#" -gt 0 ]; then -	run_gen_script="$1" -	shift -else -	run_gen_script=0 -fi - -# Whether to test on C11 in addition to C99. -if [ "$#" -gt 0 ]; then -	test_c11="$1" -	shift -else -	test_c11=0 -fi - -# Whether to test 128-bit integers in addition to no 128-bit integers. -if [ "$#" -gt 0 ]; then -	test_128_bit="$1" -	shift -else -	test_128_bit=0 -fi - -# Whether to test with computed goto or not. -if [ "$#" -gt 0 ]; then -	test_computed_goto="$1" -	shift -else -	test_computed_goto=0 -fi - -# Whether to test history or not. -if [ "$#" -gt 0 ]; then -	test_karatsuba="$1" -	shift -else -	test_karatsuba=1 -fi - -# Whether to test history or not. -if [ "$#" -gt 0 ]; then -	test_history="$1" -	shift -else -	test_history=0 -fi - -if [ "$run_64_bit" -ne 0 ]; then -	bits=64 -else -	bits=32 -fi - -if [ "$test_computed_goto" -eq 0 ]; then -	clang_flags="-DBC_NO_COMPUTED_GOTO $clang_flags" -	gcc_flags="-DBC_NO_COMPUTED_GOTO $gcc_flags" -fi - -# Setup a default compiler. -if [ "$test_with_clang" -ne 0 ]; then -	defcc="clang" -elif [ "$test_with_gcc" -ne 0 ]; then -	defcc="gcc" -else -	defcc="c99" -fi - -export ASAN_OPTIONS="abort_on_error=1,allocator_may_return_null=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_invalid_pointer_pairs=2" -export UBSAN_OPTIONS="print_stack_trace=1,silence_unsigned_overflow=1" - -build "$debug -std=c99" "$defcc" "-g" "1" "$bits" - -header "Running math library under --standard" - -# Make sure the math library is POSIX compliant. -printf 'quit\n' | bin/bc -ls - -do_make clean_tests - -# Run the clang build sets. -if [ "$test_with_clang" -ne 0 ]; then -	build_set "clang" "$run_tests" -fi - -# Run the gcc build sets. -if [ "$test_with_gcc" -ne 0 ]; then -	build_set "gcc" "$run_tests" -fi - -if [ "$run_tests" -ne 0 ]; then - -	build "$release" "$defcc" "-O3" "1" "$bits" - -	# Run karatsuba. -	if [ "$test_karatsuba" -ne 0 ]; then -		karatsuba -	fi - -	# Valgrind. -	if [ "$run_valgrind" -ne 0 -a "$test_with_gcc" -ne 0 ]; then -		vg -	fi - -	printf '\n' -	printf 'Tests successful.\n' - -	# I just assume that I am going to be fuzzing when I am done. -	header "Building for AFL++..." - -	"$scriptdir/fuzz_prep.sh" - -	printf '\n' -	printf 'Ready for scripts/randmath.py and for fuzzing.\n' -	printf '\n' -	printf 'Run scripts/randmath.py if you changed any math code.\n' -	printf '\n' -	printf 'Then if there are no problems, run the fuzzer.\n' -	printf '\n' -	printf 'Then run `scripts/fuzz_prep.sh -a`.\n' -	printf '\n' -	printf 'Then run `scripts/afl.py --asan`.\n' - -fi diff --git a/scripts/release_settings.txt b/scripts/release_settings.txt deleted file mode 100644 index 1cf572347241..000000000000 --- a/scripts/release_settings.txt +++ /dev/null @@ -1,16 +0,0 @@ --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt diff --git a/scripts/test_settings.sh b/scripts/test_settings.sh deleted file mode 100755 index 563dbf0e58f3..000000000000 --- a/scripts/test_settings.sh +++ /dev/null @@ -1,77 +0,0 @@ -#! /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's argument is a number, which is the index of the setting set -# that is under test. This script is for maintainers only. -# -# The procedure is this: run the script with: -# -# ./scripts/test_settings.sh 1 -# -# Then run bc and dc to ensure their stuff is correct. Then run this script -# again with: -# -# ./scripts/test_settings.sh 2 -# -# And repeat. You can also test various environment variable sets with them. - -# Print the usage and exit with an error. -usage() { -	printf 'usage: %s index\n' "$0" 1>&2 -	exit 1 -} - -script="$0" -scriptdir=$(dirname "$script") - -cd "$scriptdir/.." - -test "$#" -eq 1 || usage - -target="$1" -shift - -line=0 - -# This loop just loops until it gets to the right line. Quick and dirty. -while read s; do - -	line=$(printf '%s + 1\n' "$line" | bc) - -	if [ "$line" -eq "$target" ]; then - -		# Configure, build, and exit. -		./configure.sh -O3 $s - -		make -j16 > /dev/null - -		exit -	fi - -done < "$scriptdir/test_settings.txt" diff --git a/scripts/test_settings.txt b/scripts/test_settings.txt deleted file mode 100644 index e6dd8ac92929..000000000000 --- a/scripts/test_settings.txt +++ /dev/null @@ -1,93 +0,0 @@ --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt --sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt --Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt diff --git a/src/history.c b/src/history.c index 0b2713857ec6..47ed6cda7f22 100644 --- a/src/history.c +++ b/src/history.c @@ -170,7 +170,12 @@ void  bc_history_init(BcHistory* h)  {  	BcVec v; -	char* home = getenv("HOME"); +	char* home; + +	// Just set a blank prompt when it is turned off. +	if (!BC_PROMPT) bc_history_prompt = ""; + +	home = getenv("HOME");  	// This will hold the true path to the editrc.  	bc_vec_init(&v, 1, BC_DTOR_NONE); @@ -214,7 +219,7 @@ bc_history_init(BcHistory* h)  void  bc_history_free(BcHistory* h)  { -	if (bc_history_prompt != NULL) free(bc_history_prompt); +	if (BC_PROMPT && bc_history_prompt != NULL) free(bc_history_prompt);  	el_end(h->el);  	history_end(h->hist);  } @@ -238,16 +243,19 @@ bc_history_line(BcHistory* h, BcVec* vec, const char* prompt)  	// This is so the signal handler can handle line libraries properly.  	bc_history_inlinelib = 1; -	// Make sure to set the prompt. -	if (bc_history_prompt != NULL) +	if (BC_PROMPT)  	{ -		if (strcmp(bc_history_prompt, prompt)) +		// Make sure to set the prompt. +		if (bc_history_prompt != NULL)  		{ -			free(bc_history_prompt); -			bc_history_prompt = bc_vm_strdup(prompt); +			if (strcmp(bc_history_prompt, prompt)) +			{ +				free(bc_history_prompt); +				bc_history_prompt = bc_vm_strdup(prompt); +			}  		} +		else bc_history_prompt = bc_vm_strdup(prompt);  	} -	else bc_history_prompt = bc_vm_strdup(prompt);  	// Get the line.  	line = el_gets(h->el, &len); @@ -261,7 +269,11 @@ bc_history_line(BcHistory* h, BcVec* vec, const char* prompt)  			if (errno == ENOMEM) bc_err(BC_ERR_FATAL_ALLOC_ERR);  			bc_err(BC_ERR_FATAL_IO_ERR);  		} -		else s = BC_STATUS_EOF; +		else +		{ +			bc_file_printf(&vm.fout, "\n"); +			s = BC_STATUS_EOF; +		}  	}  	// If there is a line...  	else @@ -341,7 +353,7 @@ bc_history_line(BcHistory* h, BcVec* vec, const char* prompt)  	}  	// Get the line. -	h->line = readline(prompt); +	h->line = readline(BC_PROMPT ? prompt : "");  	// If there was a line, add it to the history. Otherwise, just return an  	// empty line. Oh, and NULL actually means EOF. @@ -358,7 +370,7 @@ bc_history_line(BcHistory* h, BcVec* vec, const char* prompt)  	}  	else if (h->line == NULL)  	{ -		bc_file_printf(&vm.fout, "%s", "^D"); +		bc_file_printf(&vm.fout, "%s\n", "^D");  		s = BC_STATUS_EOF;  	}  	else bc_vec_string(vec, 1, "\n"); diff --git a/tests/fuzzing/bc_afl.yaml b/tests/fuzzing/bc_afl.yaml deleted file mode 100644 index 7d13bff95824..000000000000 --- a/tests/fuzzing/bc_afl.yaml +++ /dev/null @@ -1,125 +0,0 @@ -session_name: bc_afl - -windows: -  - window_name: control -    layout: even-horizontal -    panes: -      - shell_command: -        - echo core | doas tee /proc/sys/kernel/core_pattern -        - echo performance | doas tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor -        - rm -rf tests/fuzzing/bc_outputs1/ -        - rm -rf tests/fuzzing/bc_outputs2/ -        - rm -rf tests/fuzzing/bc_outputs3/ -        - rm -rf tests/fuzzing/dc_outputs/ -  - window_name: bc11 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 15 -        - afl-fuzz -i tests/fuzzing/bc_inputs1 -o tests/fuzzing/bc_outputs1 -p exploit -D -M bc11 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc12 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 16 -        - afl-fuzz -i tests/fuzzing/bc_inputs1 -o tests/fuzzing/bc_outputs1 -p coe -S bc12 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc13 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 17 -        - afl-fuzz -i tests/fuzzing/bc_inputs1 -o tests/fuzzing/bc_outputs1 -p fast -S bc13 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc14 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 18 -        - afl-fuzz -i tests/fuzzing/bc_inputs1 -o tests/fuzzing/bc_outputs1 -p explore -S bc14 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc21 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 19 -        - afl-fuzz -i tests/fuzzing/bc_inputs2 -o tests/fuzzing/bc_outputs2 -p exploit -D -M bc21 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc22 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 20 -        - afl-fuzz -i tests/fuzzing/bc_inputs2 -o tests/fuzzing/bc_outputs2 -p coe -S bc22 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc23 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 21 -        - afl-fuzz -i tests/fuzzing/bc_inputs2 -o tests/fuzzing/bc_outputs2 -p fast -S bc23 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc24 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 22 -        - afl-fuzz -i tests/fuzzing/bc_inputs2 -o tests/fuzzing/bc_outputs2 -p explore -S bc24 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc31 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 23 -        - afl-fuzz -i tests/fuzzing/bc_inputs3 -o tests/fuzzing/bc_outputs3 -p exploit -D -M bc31 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc32 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 24 -        - afl-fuzz -i tests/fuzzing/bc_inputs3 -o tests/fuzzing/bc_outputs3 -p coe -S bc32 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc33 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 25 -        - afl-fuzz -i tests/fuzzing/bc_inputs3 -o tests/fuzzing/bc_outputs3 -p fast -S bc33 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc34 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 26 -        - afl-fuzz -i tests/fuzzing/bc_inputs3 -o tests/fuzzing/bc_outputs3 -p explore -S bc34 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: dc11 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 27 -        - afl-fuzz -i tests/fuzzing/dc_inputs -o tests/fuzzing/dc_outputs -p exploit -D -M dc11 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- -  - window_name: dc12 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 28 -        - afl-fuzz -i tests/fuzzing/dc_inputs -o tests/fuzzing/dc_outputs -p coe -S dc12 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- -  - window_name: dc13 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 29 -        - afl-fuzz -i tests/fuzzing/dc_inputs -o tests/fuzzing/dc_outputs -p fast -S dc13 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- -  - window_name: dc14 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 30 -        - afl-fuzz -i tests/fuzzing/dc_inputs -o tests/fuzzing/dc_outputs -p explore -S dc14 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- diff --git a/tests/fuzzing/bc_afl_continue.yaml b/tests/fuzzing/bc_afl_continue.yaml deleted file mode 100644 index 486984bdaef5..000000000000 --- a/tests/fuzzing/bc_afl_continue.yaml +++ /dev/null @@ -1,122 +0,0 @@ -session_name: bc_afl_continue -start_directory: ./ - -windows: -  - window_name: control -    layout: even-horizontal -    panes: -      - shell_command: -        - echo core | doas tee /proc/sys/kernel/core_pattern -        - echo performance | doas tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor -  - window_name: bc11 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 4 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs1 -p exploit -D -M bc11 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc12 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 5 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs1 -p coe -S bc12 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc13 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 6 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs1 -p fast -S bc13 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc14 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 7 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs1 -p explore -S bc14 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc21 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 8 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs2 -p exploit -D -M bc21 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc22 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 9 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs2 -p coe -S bc22 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc23 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 10 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs2 -p fast -S bc23 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc24 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 11 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs2 -p explore -S bc24 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc31 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 12 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs3 -p exploit -D -M bc31 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc32 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 13 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs3 -p coe -S bc32 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc33 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 14 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs3 -p fast -S bc33 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: bc34 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 15 -        - afl-fuzz -i- -o tests/fuzzing/bc_outputs3 -p explore -S bc34 bin/bc -lq -e "seed = 1280937142.20981723890730892738902938071028973408912703984712093" -f- -  - window_name: dc11 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 16 -        - afl-fuzz -i- -o tests/fuzzing/dc_outputs -p exploit -D -M dc11 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- -  - window_name: dc12 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 17 -        - afl-fuzz -i- -o tests/fuzzing/dc_outputs -p coe -S dc12 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- -  - window_name: dc13 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 18 -        - afl-fuzz -i- -o tests/fuzzing/dc_outputs -p fast -S dc13 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- -  - window_name: dc14 -    layout: even-horizontal -    panes: -      - shell_command: -        - export AFL_AUTORESUME=1 -        - sleep 19 -        - afl-fuzz -i- -o tests/fuzzing/dc_outputs -p explore -S dc14 bin/dc -x -e "1280937142.20981723890730892738902938071028973408912703984712093j" -f- diff --git a/tests/fuzzing/bc_inputs1/array.bc b/tests/fuzzing/bc_inputs1/array.bc deleted file mode 100644 index dac232804914..000000000000 --- a/tests/fuzzing/bc_inputs1/array.bc +++ /dev/null @@ -1,60 +0,0 @@ -#! /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/tests/fuzzing/bc_inputs1/decimal.txt b/tests/fuzzing/bc_inputs1/decimal.txt deleted file mode 100644 index b79da99e3dd2..000000000000 --- a/tests/fuzzing/bc_inputs1/decimal.txt +++ /dev/null @@ -1,30 +0,0 @@ -0 -0.0 -000000000000000000000000.00000000000000000000000 -000000000000000000000000000135482346782356 -000000000000000000000000002 -1 -1023468723275435238491972521917846 -4343472432431705867392073517038270398027352709027389273920739037937960379637893607893607893670530278200795207952702873892786172916728961783907893607418973587857386079679267926737520730925372983782793652793 --1 --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 diff --git a/tests/fuzzing/bc_inputs1/functions.bc b/tests/fuzzing/bc_inputs1/functions.bc deleted file mode 100644 index 80d6d1623d8d..000000000000 --- a/tests/fuzzing/bc_inputs1/functions.bc +++ /dev/null @@ -1,7 +0,0 @@ -e(0.5) - -define e(x) { -	return x -} - -e(0.5) diff --git a/tests/fuzzing/bc_inputs1/len.bc b/tests/fuzzing/bc_inputs1/len.bc deleted file mode 100644 index ec931f2386a5..000000000000 --- a/tests/fuzzing/bc_inputs1/len.bc +++ /dev/null @@ -1,48 +0,0 @@ -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/tests/fuzzing/bc_inputs1/lib10.txt b/tests/fuzzing/bc_inputs1/lib10.txt deleted file mode 100644 index 7aa3fda19cc7..000000000000 --- a/tests/fuzzing/bc_inputs1/lib10.txt +++ /dev/null @@ -1,4 +0,0 @@ -l10(0) -l10(99) -l10(100) -l10(-100) diff --git a/tests/fuzzing/bc_inputs1/lib12.txt b/tests/fuzzing/bc_inputs1/lib12.txt deleted file mode 100644 index 7d70e1ccdd5e..000000000000 --- a/tests/fuzzing/bc_inputs1/lib12.txt +++ /dev/null @@ -1 +0,0 @@ -uint(0) diff --git a/tests/fuzzing/bc_inputs1/lib2.txt b/tests/fuzzing/bc_inputs1/lib2.txt deleted file mode 100644 index f345bd1669cb..000000000000 --- a/tests/fuzzing/bc_inputs1/lib2.txt +++ /dev/null @@ -1,15 +0,0 @@ -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(-1, 0) -r(-1, 3) -r(-1.4, 0) -r(-1.5, 0) -r(-34.45, 2) -r(-64.1223, 4) diff --git a/tests/fuzzing/bc_inputs1/lib3.txt b/tests/fuzzing/bc_inputs1/lib3.txt deleted file mode 100644 index 1da42385ea44..000000000000 --- a/tests/fuzzing/bc_inputs1/lib3.txt +++ /dev/null @@ -1,6 +0,0 @@ -f(0) -f(1) -f(2) -f(3) -f(4) -f(5) diff --git a/tests/fuzzing/bc_inputs1/lib6.txt b/tests/fuzzing/bc_inputs1/lib6.txt deleted file mode 100644 index 260e159f9fb6..000000000000 --- a/tests/fuzzing/bc_inputs1/lib6.txt +++ /dev/null @@ -1,5 +0,0 @@ -pi(5) -p=pi(scale) -r2d(-p) -d2r(180) -d2r(-180) diff --git a/tests/fuzzing/bc_inputs2/bitfuncs.txt b/tests/fuzzing/bc_inputs2/bitfuncs.txt deleted file mode 100644 index e0703a715c08..000000000000 --- a/tests/fuzzing/bc_inputs2/bitfuncs.txt +++ /dev/null @@ -1,42 +0,0 @@ -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, 64) -brol16(13946233938940740889, 12028823668264674112) -brol16(17689, 9024) -brol32(13946233938940740889, 12028823668264674112) -brol32(2366588185, 347743040) -brol64(13946233938940740889, 12028823668264674112) -bror8(13946233938940740889, 12028823668264674112) -bror8(25, 64) -bror16(13946233938940740889, 12028823668264674112) -bror16(17689, 9024) -bror32(13946233938940740889, 12028823668264674112) -bror32(2366588185, 347743040) -bror64(13946233938940740889, 12028823668264674112) -bmod8(13946233938940740889) -bmod8(25) -bmod16(13946233938940740889) -bmod16(17689) -bmod32(13946233938940740889) -bmod32(2366588185) -bmod64(13946233938940740889) diff --git a/tests/fuzzing/bc_inputs2/lib15.txt b/tests/fuzzing/bc_inputs2/lib15.txt deleted file mode 100644 index 13be33145ba3..000000000000 --- a/tests/fuzzing/bc_inputs2/lib15.txt +++ /dev/null @@ -1 +0,0 @@ -uint(1) diff --git a/tests/fuzzing/bc_inputs2/lib21.txt b/tests/fuzzing/bc_inputs2/lib21.txt deleted file mode 100644 index 82693695945d..000000000000 --- a/tests/fuzzing/bc_inputs2/lib21.txt +++ /dev/null @@ -1 +0,0 @@ -int(1) diff --git a/tests/fuzzing/bc_inputs2/misc3.txt b/tests/fuzzing/bc_inputs2/misc3.txt deleted file mode 100644 index 7aad374c4ef6..000000000000 --- a/tests/fuzzing/bc_inputs2/misc3.txt +++ /dev/null @@ -1,12 +0,0 @@ -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/tests/fuzzing/bc_inputs2/modulus.txt b/tests/fuzzing/bc_inputs2/modulus.txt deleted file mode 100644 index 049cd7dbd73c..000000000000 --- a/tests/fuzzing/bc_inputs2/modulus.txt +++ /dev/null @@ -1,27 +0,0 @@ -1 % 1 -2 % 1 -16 % 4 -17 % 4 -3496723859067234 % 298375462837546928347623059375486 --1 % 1 --2 % 1 --1274852934765 % 2387628935486273546 -1 % -1 -2 % -1 -2 % -3 -16 % 5 -89237423 % -237856923854 --1 % -1 --2 % -1 --2 % -2 --2 % -3 --13 % -7 --14 % -7 --15 % -7 --127849612 % -23712347682193 -scale = 0 -1 % 1 -2 % 1 -scale = 0; -899510228 % -2448300078.40314 -scale = 0; -7424863 % -207.2609738667 -scale = 0; 3769798918 % 0.6 diff --git a/tests/fuzzing/bc_inputs2/references.bc b/tests/fuzzing/bc_inputs2/references.bc deleted file mode 100644 index 8188f17aa017..000000000000 --- a/tests/fuzzing/bc_inputs2/references.bc +++ /dev/null @@ -1,408 +0,0 @@ -#! /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/tests/fuzzing/bc_inputs3/02.txt b/tests/fuzzing/bc_inputs3/02.txt deleted file mode 100644 index 8cf0f3e6fec1..000000000000 --- a/tests/fuzzing/bc_inputs3/02.txt +++ /dev/null @@ -1 +0,0 @@ -obase^= 20-f-b-4^-f-4-4^-f-4^-d diff --git a/tests/fuzzing/bc_inputs3/03.txt b/tests/fuzzing/bc_inputs3/03.txt deleted file mode 100644 index 00e645cea896..000000000000 --- a/tests/fuzzing/bc_inputs3/03.txt +++ /dev/null @@ -1,2 +0,0 @@ -for (i = 0; ; ) -for (i = 0; ;(p(s(ssqrtt()-p())))000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000#000 diff --git a/tests/fuzzing/bc_inputs3/06.txt b/tests/fuzzing/bc_inputs3/06.txt deleted file mode 100644 index 29fe6be37021..000000000000 --- a/tests/fuzzing/bc_inputs3/06.txt +++ /dev/null @@ -1 +0,0 @@ -while (i == 0) { diff --git a/tests/fuzzing/bc_inputs3/07.txt b/tests/fuzzing/bc_inputs3/07.txt deleted file mode 100644 index e899d8547868..000000000000 --- a/tests/fuzzing/bc_inputs3/07.txt +++ /dev/null @@ -1,8 +0,0 @@ -for(q=F;i<=020; ++i)  #00 -{print "0" -if(6)if(6){3 -} -{pr0n} -""} -{pr0n} -{print "" "" diff --git a/tests/fuzzing/bc_inputs3/10.txt b/tests/fuzzing/bc_inputs3/10.txt deleted file mode 100644 index 23fb8689f598..000000000000 --- a/tests/fuzzing/bc_inputs3/10.txt +++ /dev/null @@ -1 +0,0 @@ -d000$++ diff --git a/tests/fuzzing/bc_inputs3/12.txt b/tests/fuzzing/bc_inputs3/12.txt deleted file mode 100644 index 143bb71deeda..000000000000 --- a/tests/fuzzing/bc_inputs3/12.txt +++ /dev/null @@ -1,2 +0,0 @@ -for (v  ;!j -90-90; ++i) -a=  ibase       ++;0 diff --git a/tests/fuzzing/bc_inputs3/16.txt b/tests/fuzzing/bc_inputs3/16.txt deleted file mode 100644 index 977569bda330..000000000000 --- a/tests/fuzzing/bc_inputs3/16.txt +++ /dev/null @@ -1 +0,0 @@ -"0
\ No newline at end of file diff --git a/tests/fuzzing/bc_inputs3/trunc.txt b/tests/fuzzing/bc_inputs3/trunc.txt deleted file mode 100644 index 364bb224a2e3..000000000000 --- a/tests/fuzzing/bc_inputs3/trunc.txt +++ /dev/null @@ -1,15 +0,0 @@ -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/tests/fuzzing/dc_inputs/01.txt b/tests/fuzzing/dc_inputs/01.txt deleted file mode 100644 index 9622de95a241..000000000000 --- a/tests/fuzzing/dc_inputs/01.txt +++ /dev/null @@ -1,2 +0,0 @@ -[[000000000 -00000] diff --git a/tests/fuzzing/dc_inputs/02.txt b/tests/fuzzing/dc_inputs/02.txt deleted file mode 100644 index 79565935cf23..000000000000 --- a/tests/fuzzing/dc_inputs/02.txt +++ /dev/null @@ -1,5 +0,0 @@ -0 R -2 1 -1 0+pRpp -30.x -[00000000]ip1+pR diff --git a/tests/fuzzing/dc_inputs/03.txt b/tests/fuzzing/dc_inputs/03.txt deleted file mode 100644 index ecede2e05629..000000000000 --- a/tests/fuzzing/dc_inputs/03.txt +++ /dev/null @@ -1,2 +0,0 @@ -0 lip1-si0l0+200sx_9lq+pR	30.x -[li100L0dp1+s+sX10lM<0]sL0sJlLx diff --git a/tests/fuzzing/dc_inputs/04.txt b/tests/fuzzing/dc_inputs/04.txt deleted file mode 100644 index 209f50c16d52..000000000000 --- a/tests/fuzzing/dc_inputs/04.txt +++ /dev/null @@ -1,9 +0,0 @@ -zp100000000.000004p1+pR -0 1 1+kpR -1 1+pR -1 0IpR -2 9+iR -037 483+pR -999 999+pR -237467456283846vpR -.0000000ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsdddddddddddddddddddddddddddddddddddddddddddddddddddddsdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd/ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddfddddddddddddddddddddddddddddddddddddddddddddddddddddddcdddddddddddd9000000000000000000 diff --git a/tests/fuzzing/dc_inputs/05.txt b/tests/fuzzing/dc_inputs/05.txt deleted file mode 100644 index bf2ca982ed2b..000000000000 --- a/tests/fuzzing/dc_inputs/05.txt +++ /dev/null @@ -1,3 +0,0 @@ -04000000000000300sx_9000.00000syzpRlxlq+pR -30.x -[li1000000sxL0LLLL900000.00000sLLL]sL0s0lLx diff --git a/tests/fuzzing/dc_inputs/06.txt b/tests/fuzzing/dc_inputs/06.txt deleted file mode 100644 index eff417eb55b4..000000000000 --- a/tests/fuzzing/dc_inputs/06.txt +++ /dev/null @@ -1 +0,0 @@ -00Q;pd60 p d9S06+00I;pd60Q2 0^pR diff --git a/tests/fuzzing/dc_inputs/07.txt b/tests/fuzzing/dc_inputs/07.txt deleted file mode 100644 index 8a09152faf58..000000000000 --- a/tests/fuzzing/dc_inputs/07.txt +++ /dev/null @@ -1,3 +0,0 @@ -1 0 1|dR -1 [li0L]SL10sildR -1 [li0L]sL10|Lx diff --git a/tests/fuzzing/dc_inputs/08.txt b/tests/fuzzing/dc_inputs/08.txt deleted file mode 100644 index 156de2f536b6..000000000000 --- a/tests/fuzzing/dc_inputs/08.txt +++ /dev/null @@ -1 +0,0 @@ -0 2+p[lip1-si0li!=0^di>0]S098sil0x diff --git a/tests/fuzzing/dc_inputs/09.txt b/tests/fuzzing/dc_inputs/09.txt deleted file mode 100644 index ffc3a08908d4..000000000000 --- a/tests/fuzzing/dc_inputs/09.txt +++ /dev/null @@ -1,9 +0,0 @@ -#00000 -0sm[Nx]0s0[]0s0x[]zs0x[]0s0[]zs0c -0s0[Nx]0s0[]zs0x[]zs0x[Nx]0s0[]zs0#000000000 -0s0[Nx]0s_[]zs0x[li]zs^x[l0000000]0sm[]zs0x[liNx]zs0x[li;0lilix] -x[liN]zsWx[liN]zs0x[li;0lilix] -x[liNzs0x#000000000 -*sm[Nx]0sm[]zs0x[li]zs0x[Nx]0sm[]zsdc -0sm[Nx]0sm[]zs0x[li]zs0x[Nx]0sm[]x]zsxx#000000000 -*s0[Nx]0sm[]0s00[00]zs0x[Nx]0sm[]z0dc diff --git a/tests/fuzzing/dc_inputs/10.txt b/tests/fuzzing/dc_inputs/10.txt deleted file mode 100644 index 0fade4bb899f..000000000000 --- a/tests/fuzzing/dc_inputs/10.txt +++ /dev/null @@ -1,11 +0,0 @@ -#0000 -0sm[Nx]0sm[]0s0x[li]0s0x[Nfvfff[]0sm[]zs0x[li]zs0x[Nx]0sm[]zs0c -0sm[Nx]0sm[]x[li]zs0x[Nx]0sm[]zs0c -0sm[Nx]0sm[]zs0x[li]zs0x[Nx]0sm[]zs0c -0sm[Nx]0sm[]zs0x[li]zs0x[Nx]0sm[]zs0#000000000 -0sm[Nx]0s0[]zs0x[li]zs0x[0000000000]0sm[]zs0x[liNx]zs0x[li;0l0l0x] -x[liNx]zs0x#000000000 -0sm[Nx]0sm[]zs0x[li]zs0x[000]0sm[]x[li]zs0x[Nx]0sm[]zs0c -0sm[Nx]0sm[]zs0x[li]zs0x[Nx]0sm[]zs0#0000 -0sm[Nx]0sm[]zs0x[li]zs0x[Nx]0sm[]zs0#000000000 -0sm[Nx]0s_@]zs0x[li]s^x[0000000000]0s0[]zsW[0000]zsxx[000000000] diff --git a/tests/fuzzing/dc_inputs/11.txt b/tests/fuzzing/dc_inputs/11.txt deleted file mode 100644 index 73bbc7d88f1c..000000000000 --- a/tests/fuzzing/dc_inputs/11.txt +++ /dev/null @@ -1,4 +0,0 @@ -#00000000 -[[00000]aa]sM[lip1-si0li>0eM]s010sil0x -[[0000]00]sM[]s010sil0x -[R]sM[lip=000]s0;0 diff --git a/tests/fuzzing/dc_inputs/12.txt b/tests/fuzzing/dc_inputs/12.txt deleted file mode 100644 index aff25e7381cd..000000000000 --- a/tests/fuzzing/dc_inputs/12.txt +++ /dev/null @@ -1,2 +0,0 @@ -1;09R0si[lii000000000000000000000000000000000000000000]li1000 2346dvdddd;ddddddddddddd?-sdddddddddd0+dd0 1+pR -0dvdddd;ddSddddddddddd 0si[lid1+sil0sili10li?-s0]dsxx[00000000]li1000 2000dvddddddddddddddddddddddddd0 0+ddd 1+pR diff --git a/tests/fuzzing/dc_inputs/13.txt b/tests/fuzzing/dc_inputs/13.txt deleted file mode 100644 index e6af9463e38c..000000000000 --- a/tests/fuzzing/dc_inputs/13.txt +++ /dev/null @@ -1,7 +0,0 @@ -zp10[00000000\00]pppppppppppppppR -_1 _1(pR -_1 _2(pR -2 1{pR -_1 1{pR 990+pR -2000000 300000300000000+pR -2070000000aaaaaaaaaaaaaaxaaaaaaaaaaaaR diff --git a/tests/fuzzing/dc_inputs/14.txt b/tests/fuzzing/dc_inputs/14.txt deleted file mode 100644 index 741f3bfd7704..000000000000 --- a/tests/fuzzing/dc_inputs/14.txt +++ /dev/null @@ -1,7 +0,0 @@ -0bpR -1bpR -.200000bpR -100000.0000600bpR -_10bpR -_.1000000bpR -_30000.00bpR:
\ No newline at end of file diff --git a/tests/fuzzing/dc_inputs/15.txt b/tests/fuzzing/dc_inputs/15.txt deleted file mode 100644 index 828e8204a2aa..000000000000 --- a/tests/fuzzing/dc_inputs/15.txt +++ /dev/null @@ -1,11 +0,0 @@ -0bpax1bpR -1bpR -.30b900pR -_10bp/90 -_30_.1/10bp30_.1/90 -_300.1/90/90 -_30_.1/90 -_30000.1/90 -90 -_30000.1/90 -70.000 70u diff --git a/tests/fuzzing/dc_inputs/16.txt b/tests/fuzzing/dc_inputs/16.txt deleted file mode 100644 index b021dd66d7ff..000000000000 --- a/tests/fuzzing/dc_inputs/16.txt +++ /dev/null @@ -1 +0,0 @@ -0  0;^dddddRps0R@s016dddRRd^2ddRZ(b-P;;$p;;;;;;9;;;;;;$ppppppppppppp30 diff --git a/tests/fuzzing/dc_inputs/17.txt b/tests/fuzzing/dc_inputs/17.txt deleted file mode 100644 index fb46510fc3e3..000000000000 --- a/tests/fuzzing/dc_inputs/17.txt +++ /dev/null @@ -1,20 +0,0 @@ -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/tests/fuzzing/dc_inputs/18.txt b/tests/fuzzing/dc_inputs/18.txt deleted file mode 100644 index ed2659d097c2..000000000000 --- a/tests/fuzzing/dc_inputs/18.txt +++ /dev/null @@ -1,3 +0,0 @@ -1oVVf[li;WORli1S0Zli1;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;0=Rls1d:0li +i100>x]dsxx[0000000]dsxx[p000]l010000000 00000000000pR diff --git a/tests/fuzzing/dc_inputs/20.txt b/tests/fuzzing/dc_inputs/20.txt deleted file mode 100644 index aa7752a85c67..000000000000 --- a/tests/fuzzing/dc_inputs/20.txt +++ /dev/null @@ -1,3 +0,0 @@ -#0000 -I20PPrP PPPP PPs0daP1:0pR - PPP1d:0pRR diff --git a/tests/fuzzing/dc_inputs/21.txt b/tests/fuzzing/dc_inputs/21.txt deleted file mode 100644 index 01707d8256b6..000000000000 --- a/tests/fuzzing/dc_inputs/21.txt +++ /dev/null @@ -1,5 +0,0 @@ -0bpR -1bpR -.200000bpR -100000.0000600bpR -S09bpR diff --git a/tests/fuzzing/dc_inputs/22.txt b/tests/fuzzing/dc_inputs/22.txt deleted file mode 100644 index 898184649926..000000000000 --- a/tests/fuzzing/dc_inputs/22.txt +++ /dev/null @@ -1,36 +0,0 @@ -[0000000000000]ZpR -[He00 -[0000000\00000000]00 -[0000000\00000000]000 -[0000000\00000000]00 -[0000] -00000] -[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 diff --git a/tests/fuzzing/dc_inputs/23.txt b/tests/fuzzing/dc_inputs/23.txt deleted file mode 100644 index 1897dfbbb0aa..000000000000 --- a/tests/fuzzing/dc_inputs/23.txt +++ /dev/null @@ -1,2 +0,0 @@ -#00000000 -[[0000]00]SM[l0p1-s00l0`000]s010sil0x diff --git a/tests/fuzzing/dc_inputs/24.txt b/tests/fuzzing/dc_inputs/24.txt deleted file mode 100644 index fb9b04f7f5b8..000000000000 --- a/tests/fuzzing/dc_inputs/24.txt +++ /dev/null @@ -1 +0,0 @@ - [] 0:xX:0 0:0X:0n/dc.000C00}pR diff --git a/tests/fuzzing/dc_inputs/25.txt b/tests/fuzzing/dc_inputs/25.txt deleted file mode 100644 index d48a9b2e83fd..000000000000 --- a/tests/fuzzing/dc_inputs/25.txt +++ /dev/null @@ -1,6 +0,0 @@ -#00000000 -0s0[l0d:0l01;0d:0l01;0pRl01+s0l010>x]dsxx0sx0s0 -1 2 -s0[l0d:0l01;0d:0l01;0pRl01+s0l010>x]dsxx0sx0s0 -1 2 -€ diff --git a/tests/fuzzing/dc_inputs/26.txt b/tests/fuzzing/dc_inputs/26.txt deleted file mode 100644 index 731d3969ac3b..000000000000 --- a/tests/fuzzing/dc_inputs/26.txt +++ /dev/null @@ -1,155 +0,0 @@ -0bpR -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 -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 -70+p -70+p -70+p -70+p -22+p -20+p -20+p -20+p -20+p -20+p -20+p -20+p -30+p -30+p -30+p -30+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 -50+p -60+p -60+p -60bpR -1bp0 -.20bpR -100000.0070000bpR -_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 -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 -70+p -70+p -70+p -70+p -22+p -20+p -20+p -20+p -20+p -20+p -20+p -20+p -30+p -30+p -30+p -30+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 -50+p -60+p -60+p -60+p -60+p -60+p -60+p -60+p -60 -70+p -70+p -70+p -70+p -70+p -70+p -70+p -80+p -È diff --git a/tests/fuzzing/dc_inputs/27.txt b/tests/fuzzing/dc_inputs/27.txt deleted file mode 100644 index 69745b952afc..000000000000 --- a/tests/fuzzing/dc_inputs/27.txt +++ /dev/null @@ -1,2 +0,0 @@ -"0000000\ - diff --git a/tests/fuzzing/dc_inputs/28.txt b/tests/fuzzing/dc_inputs/28.txt deleted file mode 100644 index fe81732b3e38..000000000000 --- a/tests/fuzzing/dc_inputs/28.txt +++ /dev/null @@ -1 +0,0 @@ -10 4%0:i[000] 1:b 0;0 p 1;b0:b [000] 1:b 0;b p 1;b~b 0;b p 0;b~~~0k diff --git a/tests/fuzzing/dc_inputs/29.txt b/tests/fuzzing/dc_inputs/29.txt deleted file mode 100644 index 886eb8ee0a8e..000000000000 --- a/tests/fuzzing/dc_inputs/29.txt +++ /dev/null @@ -1,13 +0,0 @@ -10 4%0:b [200] 1:b 0;b 1;b X - 2000 1%p0 -3460:b [200] 1:b 0;b p bp0 -.2 1%pR -6 4%pR -10 4%0:b [200] 1:b 0;b p 1;b X - 20000 1%pR -b 0;b p 0;b2  -1bpb [200] 1:u 0;b p 1;b X - 2 -[000] 0:b [200] 0:b 0;b p S0b p -[s0]XpR - diff --git a/tests/fuzzing/dc_inputs/30.txt b/tests/fuzzing/dc_inputs/30.txt deleted file mode 100644 index e072e71617d8..000000000000 --- a/tests/fuzzing/dc_inputs/30.txt +++ /dev/null @@ -1 +0,0 @@ -0;0[]0:b;bs0l0x;0 diff --git a/tests/fuzzing/dc_inputs/abs.txt b/tests/fuzzing/dc_inputs/abs.txt deleted file mode 100644 index 9907dfc6679d..000000000000 --- a/tests/fuzzing/dc_inputs/abs.txt +++ /dev/null @@ -1,7 +0,0 @@ -0bpR -1bpR -.218933bpR -138963.9873645bpR -_19bpR -_.1298376bpR -_3892173.289375bpR diff --git a/tests/fuzzing/dc_inputs/add.txt b/tests/fuzzing/dc_inputs/add.txt deleted file mode 100644 index 42da2f1f309c..000000000000 --- a/tests/fuzzing/dc_inputs/add.txt +++ /dev/null @@ -1,33 +0,0 @@ -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/tests/fuzzing/dc_inputs/array.dc b/tests/fuzzing/dc_inputs/array.dc deleted file mode 100644 index 970f29a68768..000000000000 --- a/tests/fuzzing/dc_inputs/array.dc +++ /dev/null @@ -1,2 +0,0 @@ -#! /usr/bin/dc -0si[lid:rli1+sili100>x]dsxx[li;rpRli1-sili100!>x]li1+[li;rpRli1+sili100>x] diff --git a/tests/fuzzing/dc_inputs/boolean.txt b/tests/fuzzing/dc_inputs/boolean.txt deleted file mode 100644 index 815100f0d085..000000000000 --- a/tests/fuzzing/dc_inputs/boolean.txt +++ /dev/null @@ -1,80 +0,0 @@ -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/tests/fuzzing/dc_inputs/decimal.txt b/tests/fuzzing/dc_inputs/decimal.txt deleted file mode 100644 index fdc628c857e0..000000000000 --- a/tests/fuzzing/dc_inputs/decimal.txt +++ /dev/null @@ -1,41 +0,0 @@ -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/tests/fuzzing/dc_inputs/divide.txt b/tests/fuzzing/dc_inputs/divide.txt deleted file mode 100644 index 38b874e9f175..000000000000 --- a/tests/fuzzing/dc_inputs/divide.txt +++ /dev/null @@ -1,33 +0,0 @@ -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/tests/fuzzing/dc_inputs/divmod.txt b/tests/fuzzing/dc_inputs/divmod.txt deleted file mode 100644 index 1633203ff99f..000000000000 --- a/tests/fuzzing/dc_inputs/divmod.txt +++ /dev/null @@ -1,64 +0,0 @@ -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/tests/fuzzing/dc_inputs/else.dc b/tests/fuzzing/dc_inputs/else.dc deleted file mode 100644 index 84deb8754e9f..000000000000 --- a/tests/fuzzing/dc_inputs/else.dc +++ /dev/null @@ -1,4 +0,0 @@ -#! /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/tests/fuzzing/dc_inputs/engineering.txt b/tests/fuzzing/dc_inputs/engineering.txt deleted file mode 100644 index 90a35052b3cb..000000000000 --- a/tests/fuzzing/dc_inputs/engineering.txt +++ /dev/null @@ -1,19 +0,0 @@ -1o -0pR -1pR -_34pR -298pR -_8933pR -29488pR -_148232pR -8927559pR -.2pR -_.02pR -.002pR -_.0003pR -.0000209310pR -_.00000289362pR -.000000859289pR -_.02983672pR -.20201296pR -_.8907210897000000000000000000pR diff --git a/tests/fuzzing/dc_inputs/loop.dc b/tests/fuzzing/dc_inputs/loop.dc deleted file mode 100644 index 26cec23818df..000000000000 --- a/tests/fuzzing/dc_inputs/loop.dc +++ /dev/null @@ -1,3 +0,0 @@ -#! /usr/bin/dc -[lip1-si0li>L]sL10silLx -[lip1+si10li<L]sL0silLx diff --git a/tests/fuzzing/dc_inputs/misc.txt b/tests/fuzzing/dc_inputs/misc.txt deleted file mode 100644 index 222a3ad265d2..000000000000 --- a/tests/fuzzing/dc_inputs/misc.txt +++ /dev/null @@ -1 +0,0 @@ -zp198202389.289374pzp[Hello, World!]pzpzpfrfczpfR diff --git a/tests/fuzzing/dc_inputs/modexp.txt b/tests/fuzzing/dc_inputs/modexp.txt deleted file mode 100644 index a6afb998558e..000000000000 --- a/tests/fuzzing/dc_inputs/modexp.txt +++ /dev/null @@ -1,103 +0,0 @@ -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/tests/fuzzing/dc_inputs/modulus.txt b/tests/fuzzing/dc_inputs/modulus.txt deleted file mode 100644 index 613944b2001a..000000000000 --- a/tests/fuzzing/dc_inputs/modulus.txt +++ /dev/null @@ -1,70 +0,0 @@ -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/tests/fuzzing/dc_inputs/multiply.txt b/tests/fuzzing/dc_inputs/multiply.txt deleted file mode 100644 index 1f9041d06ea7..000000000000 --- a/tests/fuzzing/dc_inputs/multiply.txt +++ /dev/null @@ -1,42 +0,0 @@ -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/tests/fuzzing/dc_inputs/places.txt b/tests/fuzzing/dc_inputs/places.txt deleted file mode 100644 index 308ff1373d64..000000000000 --- a/tests/fuzzing/dc_inputs/places.txt +++ /dev/null @@ -1,14 +0,0 @@ -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 diff --git a/tests/fuzzing/dc_inputs/power.txt b/tests/fuzzing/dc_inputs/power.txt deleted file mode 100644 index 955e42557a15..000000000000 --- a/tests/fuzzing/dc_inputs/power.txt +++ /dev/null @@ -1,36 +0,0 @@ -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 8^pR -93762.2836 3^pR -1 _1^pR -2 _1^pR -10 _1^pR -683734768 _1^pR -38579623756.897937568235 _1^pR -1 _32467^pR -2 _53^pR -_1 1^pR -_1 2^pR -_2 1^pR -_2 2^pR -_237 294^pR -_3746 28^pR -_0.3548 35^pR -_1 _1^pR -_1 _2^pR -_2 _1^pR -_2 _2^pR -_86 _7^pR -0 _251^pR -_0.2959371298 27^pR diff --git a/tests/fuzzing/dc_inputs/quit.dc b/tests/fuzzing/dc_inputs/quit.dc deleted file mode 100644 index 81e6289af25b..000000000000 --- a/tests/fuzzing/dc_inputs/quit.dc +++ /dev/null @@ -1,2 +0,0 @@ -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/tests/fuzzing/dc_inputs/scientific.txt b/tests/fuzzing/dc_inputs/scientific.txt deleted file mode 100644 index 240473b0bbca..000000000000 --- a/tests/fuzzing/dc_inputs/scientific.txt +++ /dev/null @@ -1,55 +0,0 @@ -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/tests/fuzzing/dc_inputs/shift.txt b/tests/fuzzing/dc_inputs/shift.txt deleted file mode 100644 index 628b0a5bf6fe..000000000000 --- a/tests/fuzzing/dc_inputs/shift.txt +++ /dev/null @@ -1,42 +0,0 @@ -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/tests/fuzzing/dc_inputs/sqrt.txt b/tests/fuzzing/dc_inputs/sqrt.txt deleted file mode 100644 index 7c13fdd0bb5d..000000000000 --- a/tests/fuzzing/dc_inputs/sqrt.txt +++ /dev/null @@ -1,14 +0,0 @@ -20k -0vpR -2vpR -4vpR -9vpR -16vpR -25vpR -121vpR -48765vpR -9287356207356vpR -0.189274385967238956872354vpR -12389467137496823.134567829387456283946vpR -.0000000000000000000000000000123vpR -1vpR diff --git a/tests/fuzzing/dc_inputs/stack_len.txt b/tests/fuzzing/dc_inputs/stack_len.txt deleted file mode 100644 index 1b367f3affa8..000000000000 --- a/tests/fuzzing/dc_inputs/stack_len.txt +++ /dev/null @@ -1,15 +0,0 @@ -zp -zp -zp -zp -sa -yap -Sa -yap -Sa -yapR -La -yapR -La -yap -zp diff --git a/tests/fuzzing/dc_inputs/stdin.txt b/tests/fuzzing/dc_inputs/stdin.txt deleted file mode 100644 index 7bf8316b99af..000000000000 --- a/tests/fuzzing/dc_inputs/stdin.txt +++ /dev/null @@ -1,205 +0,0 @@ -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 -p diff --git a/tests/fuzzing/dc_inputs/stream.dc b/tests/fuzzing/dc_inputs/stream.dc deleted file mode 100644 index 5c61e7c931f9..000000000000 --- a/tests/fuzzing/dc_inputs/stream.dc +++ /dev/null @@ -1,2 +0,0 @@ -#! /usr/bin/dc -0si[liPlid1+sili4096>x]ddsxPx diff --git a/tests/fuzzing/dc_inputs/strings.txt b/tests/fuzzing/dc_inputs/strings.txt deleted file mode 100644 index 460976abbd9e..000000000000 --- a/tests/fuzzing/dc_inputs/strings.txt +++ /dev/null @@ -1,51 +0,0 @@ -[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/tests/fuzzing/dc_inputs/subtract.txt b/tests/fuzzing/dc_inputs/subtract.txt deleted file mode 100644 index 2cb4104fb717..000000000000 --- a/tests/fuzzing/dc_inputs/subtract.txt +++ /dev/null @@ -1,33 +0,0 @@ -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/tests/fuzzing/dc_inputs/vars.txt b/tests/fuzzing/dc_inputs/vars.txt deleted file mode 100644 index bbe73b47d81f..000000000000 --- a/tests/fuzzing/dc_inputs/vars.txt +++ /dev/null @@ -1,2 +0,0 @@ -298734.8921702348sx_928374892.28937syzpRlxly+pR -298734.8921702348S xotj _928374892.28937S yotp zpRl xotj l yotp-pRzpR L xotj L yotp-pR diff --git a/tests/fuzzing/dc_inputs/weird.dc b/tests/fuzzing/dc_inputs/weird.dc deleted file mode 100644 index 391ec05d6282..000000000000 --- a/tests/fuzzing/dc_inputs/weird.dc +++ /dev/null @@ -1,2 +0,0 @@ -#! /usr/bin/dc -zp198202389.289374pzp[He World!]SzpzXfrfxzpfR  | 
