1#! /bin/sh 2# 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2018-2021 Gavin D. Howard and contributors. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are met: 9# 10# * Redistributions of source code must retain the above copyright notice, this 11# list of conditions and the following disclaimer. 12# 13# * Redistributions in binary form must reproduce the above copyright notice, 14# this list of conditions and the following disclaimer in the documentation 15# and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30set -e 31 32script="$0" 33testdir=$(dirname "$script") 34 35. "$testdir/../scripts/functions.sh" 36 37outputdir=${BC_TEST_OUTPUT_DIR:-$testdir} 38 39# Command-line processing. 40if [ "$#" -ge 2 ]; then 41 42 d="$1" 43 shift 44 45 extra_math="$1" 46 shift 47 48else 49 err_exit "usage: $script dir extra_math [exec args...]" 1 50fi 51 52if [ "$#" -lt 1 ]; then 53 exe="$testdir/../bin/$d" 54else 55 exe="$1" 56 shift 57fi 58 59if [ "$d" = "bc" ]; then 60 halt="quit" 61else 62 halt="q" 63fi 64 65# For tests later. 66num=100000000000000000000000000000000000000000000000000000000000000000000000000000 67num2="$num" 68numres="$num" 69num70="10000000000000000000000000000000000000000000000000000000000000000000\\ 700000000000" 71 72# Set stuff for the correct calculator. 73if [ "$d" = "bc" ]; then 74 halt="halt" 75 opt="x" 76 lopt="extended-register" 77 line_var="BC_LINE_LENGTH" 78 lltest="line_length()" 79else 80 halt="q" 81 opt="l" 82 lopt="mathlib" 83 line_var="DC_LINE_LENGTH" 84 num="$num pR" 85 lltest="glpR" 86fi 87 88# I use these, so unset them to make the tests work. 89unset BC_ENV_ARGS 90unset BC_LINE_LENGTH 91unset DC_ENV_ARGS 92unset DC_LINE_LENGTH 93 94set +e 95 96printf '\nRunning %s quit test...' "$d" 97 98printf '%s\n' "$halt" | "$exe" "$@" > /dev/null 2>&1 99 100checktest_retcode "$d" "$?" "quit" 101 102# bc has two halt or quit commands, so test the second as well. 103if [ "$d" = bc ]; then 104 105 printf '%s\n' "quit" | "$exe" "$@" > /dev/null 2>&1 106 107 checktest_retcode "$d" "$?" quit 108 109 two=$("$exe" "$@" -e 1+1 -e quit) 110 111 checktest_retcode "$d" "$?" quit 112 113 if [ "$two" != "2" ]; then 114 err_exit "$d failed test quit" 1 115 fi 116fi 117 118printf 'pass\n' 119 120base=$(basename "$exe") 121 122printf 'Running %s environment var tests...' "$d" 123 124if [ "$d" = "bc" ]; then 125 126 export BC_ENV_ARGS=" '-l' '' -q" 127 128 printf 's(.02893)\n' | "$exe" "$@" > /dev/null 129 130 checktest_retcode "$d" "$?" "environment var" 131 132 "$exe" "$@" -e 4 > /dev/null 133 134 err="$?" 135 checktest_retcode "$d" "$?" "environment var" 136 137 printf 'pass\n' 138 139 printf 'Running keyword redefinition test...' 140 141 unset BC_ENV_ARGS 142 143 redefine_res="$outputdir/bc_outputs/redefine.txt" 144 redefine_out="$outputdir/bc_outputs/redefine_results.txt" 145 146 outdir=$(dirname "$easter_out") 147 148 if [ ! -d "$outdir" ]; then 149 mkdir -p "$outdir" 150 fi 151 152 printf '5\n0\n' > "$redefine_res" 153 154 "$exe" "$@" --redefine=print -e 'define print(x) { x }' -e 'print(5)' > "$redefine_out" 155 err="$?" 156 157 checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out" 158 159 "$exe" "$@" -r "abs" -r "else" -e 'abs = 5;else = 0' -e 'abs;else' > "$redefine_out" 160 err="$?" 161 162 checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out" 163 164 if [ "$extra_math" -ne 0 ]; then 165 166 "$exe" "$@" -lr abs -e "perm(5, 1)" -e "0" > "$redefine_out" 167 err="$?" 168 169 checktest "$d" "$err" "keyword not redefined in builtin library" "$redefine_res" "$redefine_out" 170 171 fi 172 173 "$exe" "$@" -r "break" -e 'define break(x) { x }' 2> "$redefine_out" 174 err="$?" 175 176 checkerrtest "$d" "$err" "keyword redefinition error" "$redefine_out" "$d" 177 178 "$exe" "$@" -e 'define read(x) { x }' 2> "$redefine_out" 179 err="$?" 180 181 checkerrtest "$d" "$err" "Keyword redefinition error without BC_REDEFINE_KEYWORDS" "$redefine_out" "$d" 182 183 printf 'pass\n' 184 printf 'Running multiline comment expression file test...' 185 186 multiline_expr_res="" 187 multiline_expr_out="$outputdir/bc_outputs/multiline_expr_results.txt" 188 189 # tests/bc/misc1.txt happens to have a multiline comment in it. 190 "$exe" "$@" -f "$testdir/bc/misc1.txt" > "$multiline_expr_out" 191 err="$?" 192 193 checktest "$d" "$err" "multiline comment in expression file" "$testdir/bc/misc1_results.txt" \ 194 "$multiline_expr_out" 195 196 printf 'pass\n' 197 printf 'Running multiline comment expression file error test...' 198 199 "$exe" "$@" -f "$testdir/bc/errors/05.txt" 2> "$multiline_expr_out" 200 err="$?" 201 202 checkerrtest "$d" "$err" "multiline comment in expression file error" \ 203 "$multiline_expr_out" "$d" 204 205 printf 'pass\n' 206 printf 'Running multiline string expression file test...' 207 208 # tests/bc/strings.txt happens to have a multiline string in it. 209 "$exe" "$@" -f "$testdir/bc/strings.txt" > "$multiline_expr_out" 210 err="$?" 211 212 checktest "$d" "$err" "multiline string in expression file" "$testdir/bc/strings_results.txt" \ 213 "$multiline_expr_out" 214 215 printf 'pass\n' 216 printf 'Running multiline string expression file error test...' 217 218 "$exe" "$@" -f "$testdir/bc/errors/16.txt" 2> "$multiline_expr_out" 219 err="$?" 220 221 checkerrtest "$d" "$err" "multiline string in expression file with backslash error" \ 222 "$multiline_expr_out" "$d" 223 224 "$exe" "$@" -f "$testdir/bc/errors/04.txt" 2> "$multiline_expr_out" 225 err="$?" 226 227 checkerrtest "$d" "$err" "multiline string in expression file error" \ 228 "$multiline_expr_out" "$d" 229 230 printf 'pass\n' 231 232else 233 234 export DC_ENV_ARGS="'-x'" 235 export DC_EXPR_EXIT="1" 236 237 printf '4s stuff\n' | "$exe" "$@" > /dev/null 238 239 checktest_retcode "$d" "$?" "environment var" 240 241 "$exe" "$@" -e 4pR > /dev/null 242 243 checktest_retcode "$d" "$?" "environment var" 244 245 printf 'pass\n' 246 247 set +e 248 249 # dc has an extra test for a case that someone found running this easter.dc 250 # script. It went into an infinite loop, so we want to check that we did not 251 # regress. 252 printf 'three\n' | cut -c1-3 > /dev/null 253 err=$? 254 255 if [ "$err" -eq 0 ]; then 256 257 printf 'Running dc Easter script...' 258 259 easter_res="$outputdir/dc_outputs/easter.txt" 260 easter_out="$outputdir/dc_outputs/easter_results.txt" 261 262 outdir=$(dirname "$easter_out") 263 264 if [ ! -d "$outdir" ]; then 265 mkdir -p "$outdir" 266 fi 267 268 printf '4 April 2021\n' > "$easter_res" 269 270 "$testdir/dc/scripts/easter.sh" "$exe" 2021 "$@" | cut -c1-12 > "$easter_out" 271 err="$?" 272 273 checktest "$d" "$err" "Easter script" "$easter_res" "$easter_out" 274 275 printf 'pass\n' 276 fi 277 278fi 279 280out1="$outputdir/${d}_outputs/${d}_other.txt" 281out2="$outputdir/${d}_outputs/${d}_other_test.txt" 282 283printf 'Running %s line length tests...' "$d" 284 285printf '%s\n' "$numres" > "$out1" 286 287export "$line_var"=80 288printf '%s\n' "$num" | "$exe" "$@" > "$out2" 289 290checktest "$d" "$?" "line length" "$out1" "$out2" 291 292printf '%s\n' "$num70" > "$out1" 293 294export "$line_var"=2147483647 295printf '%s\n' "$num" | "$exe" "$@" > "$out2" 296 297checktest "$d" "$?" "line length 2" "$out1" "$out2" 298 299printf '%s\n' "$num2" > "$out1" 300 301export "$line_var"=62 302printf '%s\n' "$num" | "$exe" "$@" -L > "$out2" 303 304checktest "$d" "$?" "line length 3" "$out1" "$out2" 305 306printf '0\n' > "$out1" 307printf '%s\n' "$lltest" | "$exe" "$@" -L > "$out2" 308 309checktest "$d" "$?" "line length 3" "$out1" "$out2" 310 311printf 'pass\n' 312 313printf '%s\n' "$numres" > "$out1" 314export "$line_var"=2147483647 315 316printf 'Running %s arg tests...' "$d" 317 318f="$testdir/$d/add.txt" 319exprs=$(cat "$f") 320results=$(cat "$testdir/$d/add_results.txt") 321 322printf '%s\n%s\n%s\n%s\n' "$results" "$results" "$results" "$results" > "$out1" 323 324"$exe" "$@" -e "$exprs" -f "$f" --expression "$exprs" --file "$f" -e "$halt" > "$out2" 325 326checktest "$d" "$?" "arg" "$out1" "$out2" 327 328printf '%s\n' "$halt" | "$exe" "$@" -- "$f" "$f" "$f" "$f" > "$out2" 329 330checktest "$d" "$?" "arg" "$out1" "$out2" 331 332if [ "$d" = "bc" ]; then 333 printf '%s\n' "$halt" | "$exe" "$@" -i > /dev/null 2>&1 334fi 335 336printf '%s\n' "$halt" | "$exe" "$@" -h > /dev/null 337checktest_retcode "$d" "$?" "arg" 338printf '%s\n' "$halt" | "$exe" "$@" -P > /dev/null 339checktest_retcode "$d" "$?" "arg" 340printf '%s\n' "$halt" | "$exe" "$@" -R > /dev/null 341checktest_retcode "$d" "$?" "arg" 342printf '%s\n' "$halt" | "$exe" "$@" -v > /dev/null 343checktest_retcode "$d" "$?" "arg" 344printf '%s\n' "$halt" | "$exe" "$@" -V > /dev/null 345checktest_retcode "$d" "$?" "arg" 346 347out=$(printf '0.1\n-0.1\n1.1\n-1.1\n0.1\n-0.1\n') 348printf '%s\n' "$out" > "$out1" 349 350if [ "$d" = "bc" ]; then 351 data=$(printf '0.1\n-0.1\n1.1\n-1.1\n.1\n-.1\n') 352else 353 data=$(printf '0.1pR\n_0.1pR\n1.1pR\n_1.1pR\n.1pR\n_.1pR\n') 354fi 355 356printf '%s\n' "$data" | "$exe" "$@" -z > "$out2" 357checktest "$d" "$?" "leading zero" "$out1" "$out2" 358 359if [ "$d" = "bc" ] && [ "$extra_math" -ne 0 ]; then 360 361 printf '%s\n' "$halt" | "$exe" "$@" -lz "$testdir/bc/leadingzero.txt" > "$out2" 362 363 checktest "$d" "$?" "leading zero script" "$testdir/bc/leadingzero_results.txt" "$out2" 364 365fi 366 367"$exe" "$@" -f "saotehasotnehasthistohntnsahxstnhalcrgxgrlpyasxtsaosysxsatnhoy.txt" > /dev/null 2> "$out2" 368err="$?" 369 370checkerrtest "$d" "$err" "invalid file argument" "$out2" "$d" 371 372"$exe" "$@" "-$opt" -e "$exprs" > /dev/null 2> "$out2" 373err="$?" 374 375checkerrtest "$d" "$err" "invalid option argument" "$out2" "$d" 376 377"$exe" "$@" "--$lopt" -e "$exprs" > /dev/null 2> "$out2" 378err="$?" 379 380checkerrtest "$d" "$err" "invalid long option argument" "$out2" "$d" 381 382"$exe" "$@" "-u" -e "$exprs" > /dev/null 2> "$out2" 383err="$?" 384 385checkerrtest "$d" "$err" "unrecognized option argument" "$out2" "$d" 386 387"$exe" "$@" "--uniform" -e "$exprs" > /dev/null 2> "$out2" 388err="$?" 389 390checkerrtest "$d" "$err" "unrecognized long option argument" "$out2" "$d" 391 392"$exe" "$@" -f > /dev/null 2> "$out2" 393err="$?" 394 395checkerrtest "$d" "$err" "missing required argument to short option" "$out2" "$d" 396 397"$exe" "$@" --file > /dev/null 2> "$out2" 398err="$?" 399 400checkerrtest "$d" "$err" "missing required argument to long option" "$out2" "$d" 401 402"$exe" "$@" --version=5 > /dev/null 2> "$out2" 403err="$?" 404 405checkerrtest "$d" "$err" "given argument to long option with no argument" "$out2" "$d" 406 407"$exe" "$@" -: > /dev/null 2> "$out2" 408err="$?" 409 410checkerrtest "$d" "$err" "colon short option" "$out2" "$d" 411 412"$exe" "$@" --: > /dev/null 2> "$out2" 413err="$?" 414 415checkerrtest "$d" "$err" "colon long option" "$out2" "$d" 416 417printf 'pass\n' 418 419printf 'Running %s directory test...' "$d" 420 421"$exe" "$@" "$testdir" > /dev/null 2> "$out2" 422err="$?" 423 424checkerrtest "$d" "$err" "directory" "$out2" "$d" 425 426printf 'pass\n' 427 428printf 'Running %s binary file test...' "$d" 429 430bin="/bin/sh" 431 432"$exe" "$@" "$bin" > /dev/null 2> "$out2" 433err="$?" 434 435checkerrtest "$d" "$err" "binary file" "$out2" "$d" 436 437printf 'pass\n' 438 439printf 'Running %s binary stdin test...' "$d" 440 441cat "$bin" | "$exe" "$@" > /dev/null 2> "$out2" 442err="$?" 443 444checkerrtest "$d" "$err" "binary stdin" "$out2" "$d" 445 446printf 'pass\n' 447 448if [ "$d" = "bc" ]; then 449 450 printf 'Running %s limits tests...' "$d" 451 printf 'limits\n' | "$exe" "$@" > "$out2" /dev/null 2>&1 452 453 checktest_retcode "$d" "$?" "limits" 454 455 if [ ! -s "$out2" ]; then 456 err_exit "$d did not produce output on the limits test" 1 457 fi 458 459 exec printf 'pass\n' 460 461fi 462