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 65mkdir -p "$outputdir" 66 67# For tests later. 68num=100000000000000000000000000000000000000000000000000000000000000000000000000000 69num2="$num" 70numres="$num" 71num70="10000000000000000000000000000000000000000000000000000000000000000000\\ 720000000000" 73 74# Set stuff for the correct calculator. 75if [ "$d" = "bc" ]; then 76 halt="halt" 77 opt="x" 78 lopt="extended-register" 79 line_var="BC_LINE_LENGTH" 80 lltest="line_length()" 81else 82 halt="q" 83 opt="l" 84 lopt="mathlib" 85 line_var="DC_LINE_LENGTH" 86 num="$num pR" 87 lltest="glpR" 88fi 89 90# I use these, so unset them to make the tests work. 91unset BC_ENV_ARGS 92unset BC_LINE_LENGTH 93unset DC_ENV_ARGS 94unset DC_LINE_LENGTH 95 96set +e 97 98printf '\nRunning %s quit test...' "$d" 99 100printf '%s\n' "$halt" | "$exe" "$@" > /dev/null 2>&1 101 102checktest_retcode "$d" "$?" "quit" 103 104# bc has two halt or quit commands, so test the second as well. 105if [ "$d" = bc ]; then 106 107 printf '%s\n' "quit" | "$exe" "$@" > /dev/null 2>&1 108 109 checktest_retcode "$d" "$?" quit 110 111 two=$("$exe" "$@" -e 1+1 -e quit) 112 113 checktest_retcode "$d" "$?" quit 114 115 if [ "$two" != "2" ]; then 116 err_exit "$d failed test quit" 1 117 fi 118fi 119 120printf 'pass\n' 121 122base=$(basename "$exe") 123 124printf 'Running %s environment var tests...' "$d" 125 126if [ "$d" = "bc" ]; then 127 128 export BC_ENV_ARGS=" '-l' '' -q" 129 130 printf 's(.02893)\n' | "$exe" "$@" > /dev/null 131 132 checktest_retcode "$d" "$?" "environment var" 133 134 "$exe" "$@" -e 4 > /dev/null 135 136 err="$?" 137 checktest_retcode "$d" "$?" "environment var" 138 139 printf 'pass\n' 140 141 printf 'Running keyword redefinition test...' 142 143 unset BC_ENV_ARGS 144 145 redefine_res="$outputdir/bc_outputs/redefine.txt" 146 redefine_out="$outputdir/bc_outputs/redefine_results.txt" 147 148 outdir=$(dirname "$redefine_out") 149 150 if [ ! -d "$outdir" ]; then 151 mkdir -p "$outdir" 152 fi 153 154 printf '5\n0\n' > "$redefine_res" 155 156 "$exe" "$@" --redefine=print -e 'define print(x) { x }' -e 'print(5)' > "$redefine_out" 157 err="$?" 158 159 checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out" 160 161 "$exe" "$@" -r "abs" -r "else" -e 'abs = 5;else = 0' -e 'abs;else' > "$redefine_out" 162 err="$?" 163 164 checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out" 165 166 if [ "$extra_math" -ne 0 ]; then 167 168 "$exe" "$@" -lr abs -e "perm(5, 1)" -e "0" > "$redefine_out" 169 err="$?" 170 171 checktest "$d" "$err" "keyword not redefined in builtin library" "$redefine_res" "$redefine_out" 172 173 fi 174 175 "$exe" "$@" -r "break" -e 'define break(x) { x }' 2> "$redefine_out" 176 err="$?" 177 178 checkerrtest "$d" "$err" "keyword redefinition error" "$redefine_out" "$d" 179 180 "$exe" "$@" -e 'define read(x) { x }' 2> "$redefine_out" 181 err="$?" 182 183 checkerrtest "$d" "$err" "Keyword redefinition error without BC_REDEFINE_KEYWORDS" "$redefine_out" "$d" 184 185 printf 'pass\n' 186 printf 'Running multiline comment expression file test...' 187 188 multiline_expr_res="" 189 multiline_expr_out="$outputdir/bc_outputs/multiline_expr_results.txt" 190 191 # tests/bc/misc1.txt happens to have a multiline comment in it. 192 "$exe" "$@" -f "$testdir/bc/misc1.txt" > "$multiline_expr_out" 193 err="$?" 194 195 checktest "$d" "$err" "multiline comment in expression file" "$testdir/bc/misc1_results.txt" \ 196 "$multiline_expr_out" 197 198 printf 'pass\n' 199 printf 'Running multiline comment expression file error test...' 200 201 "$exe" "$@" -f "$testdir/bc/errors/05.txt" 2> "$multiline_expr_out" 202 err="$?" 203 204 checkerrtest "$d" "$err" "multiline comment in expression file error" \ 205 "$multiline_expr_out" "$d" 206 207 printf 'pass\n' 208 printf 'Running multiline string expression file test...' 209 210 # tests/bc/strings.txt happens to have a multiline string in it. 211 "$exe" "$@" -f "$testdir/bc/strings.txt" > "$multiline_expr_out" 212 err="$?" 213 214 checktest "$d" "$err" "multiline string in expression file" "$testdir/bc/strings_results.txt" \ 215 "$multiline_expr_out" 216 217 printf 'pass\n' 218 printf 'Running multiline string expression file error test...' 219 220 "$exe" "$@" -f "$testdir/bc/errors/16.txt" 2> "$multiline_expr_out" 221 err="$?" 222 223 checkerrtest "$d" "$err" "multiline string in expression file with backslash error" \ 224 "$multiline_expr_out" "$d" 225 226 "$exe" "$@" -f "$testdir/bc/errors/04.txt" 2> "$multiline_expr_out" 227 err="$?" 228 229 checkerrtest "$d" "$err" "multiline string in expression file error" \ 230 "$multiline_expr_out" "$d" 231 232 printf 'pass\n' 233 234else 235 236 export DC_ENV_ARGS="'-x'" 237 export DC_EXPR_EXIT="1" 238 239 printf '4s stuff\n' | "$exe" "$@" > /dev/null 240 241 checktest_retcode "$d" "$?" "environment var" 242 243 "$exe" "$@" -e 4pR > /dev/null 244 245 checktest_retcode "$d" "$?" "environment var" 246 247 printf 'pass\n' 248 249 set +e 250 251 # dc has an extra test for a case that someone found running this easter.dc 252 # script. It went into an infinite loop, so we want to check that we did not 253 # regress. 254 printf 'three\n' | cut -c1-3 > /dev/null 255 err=$? 256 257 if [ "$err" -eq 0 ]; then 258 259 printf 'Running dc Easter script...' 260 261 easter_res="$outputdir/dc_outputs/easter.txt" 262 easter_out="$outputdir/dc_outputs/easter_results.txt" 263 264 outdir=$(dirname "$easter_out") 265 266 if [ ! -d "$outdir" ]; then 267 mkdir -p "$outdir" 268 fi 269 270 printf '4 April 2021\n' > "$easter_res" 271 272 "$testdir/dc/scripts/easter.sh" "$exe" 2021 "$@" | cut -c1-12 > "$easter_out" 273 err="$?" 274 275 checktest "$d" "$err" "Easter script" "$easter_res" "$easter_out" 276 277 printf 'pass\n' 278 fi 279 280fi 281 282out1="$outputdir/${d}_outputs/${d}_other.txt" 283out2="$outputdir/${d}_outputs/${d}_other_test.txt" 284 285printf 'Running %s line length tests...' "$d" 286 287printf '%s\n' "$numres" > "$out1" 288 289export "$line_var"=80 290printf '%s\n' "$num" | "$exe" "$@" > "$out2" 291 292checktest "$d" "$?" "line length" "$out1" "$out2" 293 294printf '%s\n' "$num70" > "$out1" 295 296export "$line_var"=2147483647 297printf '%s\n' "$num" | "$exe" "$@" > "$out2" 298 299checktest "$d" "$?" "line length 2" "$out1" "$out2" 300 301printf '%s\n' "$num2" > "$out1" 302 303export "$line_var"=62 304printf '%s\n' "$num" | "$exe" "$@" -L > "$out2" 305 306checktest "$d" "$?" "line length 3" "$out1" "$out2" 307 308printf '0\n' > "$out1" 309printf '%s\n' "$lltest" | "$exe" "$@" -L > "$out2" 310 311checktest "$d" "$?" "line length 3" "$out1" "$out2" 312 313printf 'pass\n' 314 315printf '%s\n' "$numres" > "$out1" 316export "$line_var"=2147483647 317 318printf 'Running %s arg tests...' "$d" 319 320f="$testdir/$d/add.txt" 321exprs=$(cat "$f") 322results=$(cat "$testdir/$d/add_results.txt") 323 324printf '%s\n%s\n%s\n%s\n' "$results" "$results" "$results" "$results" > "$out1" 325 326"$exe" "$@" -e "$exprs" -f "$f" --expression "$exprs" --file "$f" -e "$halt" > "$out2" 327 328checktest "$d" "$?" "arg" "$out1" "$out2" 329 330printf '%s\n' "$halt" | "$exe" "$@" -- "$f" "$f" "$f" "$f" > "$out2" 331 332checktest "$d" "$?" "arg" "$out1" "$out2" 333 334if [ "$d" = "bc" ]; then 335 printf '%s\n' "$halt" | "$exe" "$@" -i > /dev/null 2>&1 336fi 337 338printf '%s\n' "$halt" | "$exe" "$@" -h > /dev/null 339checktest_retcode "$d" "$?" "arg" 340printf '%s\n' "$halt" | "$exe" "$@" -P > /dev/null 341checktest_retcode "$d" "$?" "arg" 342printf '%s\n' "$halt" | "$exe" "$@" -R > /dev/null 343checktest_retcode "$d" "$?" "arg" 344printf '%s\n' "$halt" | "$exe" "$@" -v > /dev/null 345checktest_retcode "$d" "$?" "arg" 346printf '%s\n' "$halt" | "$exe" "$@" -V > /dev/null 347checktest_retcode "$d" "$?" "arg" 348 349out=$(printf '0.1\n-0.1\n1.1\n-1.1\n0.1\n-0.1\n') 350printf '%s\n' "$out" > "$out1" 351 352if [ "$d" = "bc" ]; then 353 data=$(printf '0.1\n-0.1\n1.1\n-1.1\n.1\n-.1\n') 354else 355 data=$(printf '0.1pR\n_0.1pR\n1.1pR\n_1.1pR\n.1pR\n_.1pR\n') 356fi 357 358printf '%s\n' "$data" | "$exe" "$@" -z > "$out2" 359checktest "$d" "$?" "leading zero" "$out1" "$out2" 360 361if [ "$d" = "bc" ] && [ "$extra_math" -ne 0 ]; then 362 363 printf '%s\n' "$halt" | "$exe" "$@" -lz "$testdir/bc/leadingzero.txt" > "$out2" 364 365 checktest "$d" "$?" "leading zero script" "$testdir/bc/leadingzero_results.txt" "$out2" 366 367fi 368 369"$exe" "$@" -f "saotehasotnehasthistohntnsahxstnhalcrgxgrlpyasxtsaosysxsatnhoy.txt" > /dev/null 2> "$out2" 370err="$?" 371 372checkerrtest "$d" "$err" "invalid file argument" "$out2" "$d" 373 374"$exe" "$@" "-$opt" -e "$exprs" > /dev/null 2> "$out2" 375err="$?" 376 377checkerrtest "$d" "$err" "invalid option argument" "$out2" "$d" 378 379"$exe" "$@" "--$lopt" -e "$exprs" > /dev/null 2> "$out2" 380err="$?" 381 382checkerrtest "$d" "$err" "invalid long option argument" "$out2" "$d" 383 384"$exe" "$@" "-u" -e "$exprs" > /dev/null 2> "$out2" 385err="$?" 386 387checkerrtest "$d" "$err" "unrecognized option argument" "$out2" "$d" 388 389"$exe" "$@" "--uniform" -e "$exprs" > /dev/null 2> "$out2" 390err="$?" 391 392checkerrtest "$d" "$err" "unrecognized long option argument" "$out2" "$d" 393 394"$exe" "$@" -f > /dev/null 2> "$out2" 395err="$?" 396 397checkerrtest "$d" "$err" "missing required argument to short option" "$out2" "$d" 398 399"$exe" "$@" --file > /dev/null 2> "$out2" 400err="$?" 401 402checkerrtest "$d" "$err" "missing required argument to long option" "$out2" "$d" 403 404"$exe" "$@" --version=5 > /dev/null 2> "$out2" 405err="$?" 406 407checkerrtest "$d" "$err" "given argument to long option with no argument" "$out2" "$d" 408 409"$exe" "$@" -: > /dev/null 2> "$out2" 410err="$?" 411 412checkerrtest "$d" "$err" "colon short option" "$out2" "$d" 413 414"$exe" "$@" --: > /dev/null 2> "$out2" 415err="$?" 416 417checkerrtest "$d" "$err" "colon long option" "$out2" "$d" 418 419printf 'pass\n' 420 421printf 'Running %s builtin variable arg tests...' "$d" 422 423if [ "$extra_math" -ne 0 ]; then 424 425 out=$(printf '14\n15\n16\n17.25\n') 426 printf '%s\n' "$out" > "$out1" 427 428 if [ "$d" = "bc" ]; then 429 data=$(printf 's=scale;i=ibase;o=obase;t=seed@2;ibase=A;obase=A;s;i;o;t;') 430 else 431 data=$(printf 'J2@OIKAiAopRpRpRpR') 432 fi 433 434 printf '%s\n' "$data" | "$exe" "$@" -S14 -I15 -O16 -E17.25 > "$out2" 435 checktest "$d" "$?" "builtin variable args" "$out1" "$out2" 436 437 printf '%s\n' "$data" | "$exe" "$@" --scale=14 --ibase=15 --obase=16 --seed=17.25 > "$out2" 438 checktest "$d" "$?" "builtin variable long args" "$out1" "$out2" 439 440else 441 442 out=$(printf '14\n15\n16\n') 443 printf '%s\n' "$out" > "$out1" 444 445 if [ "$d" = "bc" ]; then 446 data=$(printf 's=scale;i=ibase;o=obase;ibase=A;obase=A;s;i;o;') 447 else 448 data=$(printf 'OIKAiAopRpRpR') 449 fi 450 451 printf '%s\n' "$data" | "$exe" "$@" -S14 -I15 -O16 > "$out2" 452 checktest "$d" "$?" "builtin variable args" "$out1" "$out2" 453 454 printf '%s\n' "$data" | "$exe" "$@" --scale=14 --ibase=15 --obase=16 > "$out2" 455 checktest "$d" "$?" "builtin variable long args" "$out1" "$out2" 456 457fi 458 459printf 'scale\n' | "$exe" "$@" --scale=18923c.rlg > /dev/null 2> "$out2" 460err="$?" 461 462checkerrtest "$d" "$err" "invalid command-line arg for builtin variable" "$out2" "$d" 463 464if [ "$extra_math" -ne 0 ]; then 465 466 printf 'seed\n' | "$exe" "$@" --seed=18923c.rlg > /dev/null 2> "$out2" 467 err="$?" 468 469 checkerrtest "$d" "$err" "invalid command-line arg for seed" "$out2" "$d" 470 471fi 472 473printf 'pass\n' 474 475printf 'Running %s directory test...' "$d" 476 477"$exe" "$@" "$testdir" > /dev/null 2> "$out2" 478err="$?" 479 480checkerrtest "$d" "$err" "directory" "$out2" "$d" 481 482printf 'pass\n' 483 484printf 'Running %s binary file test...' "$d" 485 486bin="/bin/sh" 487 488"$exe" "$@" "$bin" > /dev/null 2> "$out2" 489err="$?" 490 491checkerrtest "$d" "$err" "binary file" "$out2" "$d" 492 493printf 'pass\n' 494 495printf 'Running %s binary stdin test...' "$d" 496 497cat "$bin" | "$exe" "$@" > /dev/null 2> "$out2" 498err="$?" 499 500checkerrtest "$d" "$err" "binary stdin" "$out2" "$d" 501 502printf 'pass\n' 503 504if [ "$d" = "bc" ]; then 505 506 printf 'Running %s limits tests...' "$d" 507 printf 'limits\n' | "$exe" "$@" > "$out2" /dev/null 2>&1 508 509 checktest_retcode "$d" "$?" "limits" 510 511 if [ ! -s "$out2" ]; then 512 err_exit "$d did not produce output on the limits test" 1 513 fi 514 515 exec printf 'pass\n' 516 517fi 518