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 156 checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out" 157 158 "$exe" "$@" -r "abs" -r "else" -e 'abs = 5;else = 0' -e 'abs;else' > "$redefine_out" 159 160 checktest "$d" "$err" "keyword redefinition" "$redefine_res" "$redefine_out" 161 162 if [ "$extra_math" -ne 0 ]; then 163 164 "$exe" "$@" -lr abs -e "perm(5, 1)" -e "0" > "$redefine_out" 165 166 checktest "$d" "$err" "keyword not redefined in builtin library" "$redefine_res" "$redefine_out" 167 168 fi 169 170 "$exe" "$@" -r "break" -e 'define break(x) { x }' 2> "$redefine_out" 171 err="$?" 172 173 checkerrtest "$d" "$err" "keyword redefinition error" "$redefine_out" "$d" 174 175 "$exe" "$@" -e 'define read(x) { x }' 2> "$redefine_out" 176 err="$?" 177 178 checkerrtest "$d" "$err" "Keyword redefinition error without BC_REDEFINE_KEYWORDS" "$redefine_out" "$d" 179 180 printf 'pass\n' 181 182else 183 184 export DC_ENV_ARGS="'-x'" 185 export DC_EXPR_EXIT="1" 186 187 printf '4s stuff\n' | "$exe" "$@" > /dev/null 188 189 checktest_retcode "$d" "$?" "environment var" 190 191 "$exe" "$@" -e 4pR > /dev/null 192 193 checktest_retcode "$d" "$?" "environment var" 194 195 printf 'pass\n' 196 197 set +e 198 199 # dc has an extra test for a case that someone found running this easter.dc 200 # script. It went into an infinite loop, so we want to check that we did not 201 # regress. 202 printf 'three\n' | cut -c1-3 > /dev/null 203 err=$? 204 205 if [ "$err" -eq 0 ]; then 206 207 printf 'Running dc Easter script...' 208 209 easter_res="$outputdir/dc_outputs/easter.txt" 210 easter_out="$outputdir/dc_outputs/easter_results.txt" 211 212 outdir=$(dirname "$easter_out") 213 214 if [ ! -d "$outdir" ]; then 215 mkdir -p "$outdir" 216 fi 217 218 printf '4 April 2021\n' > "$easter_res" 219 220 "$testdir/dc/scripts/easter.sh" "$exe" 2021 "$@" | cut -c1-12 > "$easter_out" 221 err="$?" 222 223 checktest "$d" "$err" "Easter script" "$easter_res" "$easter_out" 224 225 printf 'pass\n' 226 fi 227 228fi 229 230out1="$outputdir/${d}_outputs/${d}_other.txt" 231out2="$outputdir/${d}_outputs/${d}_other_test.txt" 232 233printf 'Running %s line length tests...' "$d" 234 235printf '%s\n' "$numres" > "$out1" 236 237export "$line_var"=80 238printf '%s\n' "$num" | "$exe" "$@" > "$out2" 239 240checktest "$d" "$?" "line length" "$out1" "$out2" 241 242printf '%s\n' "$num70" > "$out1" 243 244export "$line_var"=2147483647 245printf '%s\n' "$num" | "$exe" "$@" > "$out2" 246 247checktest "$d" "$?" "line length 2" "$out1" "$out2" 248 249printf '%s\n' "$num2" > "$out1" 250 251export "$line_var"=62 252printf '%s\n' "$num" | "$exe" "$@" -L > "$out2" 253 254checktest "$d" "$?" "line length 3" "$out1" "$out2" 255 256printf '0\n' > "$out1" 257printf '%s\n' "$lltest" | "$exe" "$@" -L > "$out2" 258 259checktest "$d" "$?" "line length 3" "$out1" "$out2" 260 261printf 'pass\n' 262 263printf '%s\n' "$numres" > "$out1" 264export "$line_var"=2147483647 265 266printf 'Running %s arg tests...' "$d" 267 268f="$testdir/$d/add.txt" 269exprs=$(cat "$f") 270results=$(cat "$testdir/$d/add_results.txt") 271 272printf '%s\n%s\n%s\n%s\n' "$results" "$results" "$results" "$results" > "$out1" 273 274"$exe" "$@" -e "$exprs" -f "$f" --expression "$exprs" --file "$f" -e "$halt" > "$out2" 275 276checktest "$d" "$?" "arg" "$out1" "$out2" 277 278printf '%s\n' "$halt" | "$exe" "$@" -- "$f" "$f" "$f" "$f" > "$out2" 279 280checktest "$d" "$?" "arg" "$out1" "$out2" 281 282if [ "$d" = "bc" ]; then 283 printf '%s\n' "$halt" | "$exe" "$@" -i > /dev/null 2>&1 284fi 285 286printf '%s\n' "$halt" | "$exe" "$@" -h > /dev/null 287checktest_retcode "$d" "$?" "arg" 288printf '%s\n' "$halt" | "$exe" "$@" -P > /dev/null 289checktest_retcode "$d" "$?" "arg" 290printf '%s\n' "$halt" | "$exe" "$@" -R > /dev/null 291checktest_retcode "$d" "$?" "arg" 292printf '%s\n' "$halt" | "$exe" "$@" -v > /dev/null 293checktest_retcode "$d" "$?" "arg" 294printf '%s\n' "$halt" | "$exe" "$@" -V > /dev/null 295checktest_retcode "$d" "$?" "arg" 296 297out=$(printf '0.1\n-0.1\n1.1\n-1.1\n0.1\n-0.1\n') 298printf '%s\n' "$out" > "$out1" 299 300if [ "$d" = "bc" ]; then 301 data=$(printf '0.1\n-0.1\n1.1\n-1.1\n.1\n-.1\n') 302else 303 data=$(printf '0.1pR\n_0.1pR\n1.1pR\n_1.1pR\n.1pR\n_.1pR\n') 304fi 305 306printf '%s\n' "$data" | "$exe" "$@" -z > "$out2" 307checktest "$d" "$?" "leading zero" "$out1" "$out2" 308 309if [ "$d" = "bc" ] && [ "$extra_math" -ne 0 ]; then 310 311 printf '%s\n' "$halt" | "$exe" "$@" -lz "$testdir/bc/leadingzero.txt" > "$out2" 312 313 checktest "$d" "$?" "leading zero script" "$testdir/bc/leadingzero_results.txt" "$out2" 314 315fi 316 317"$exe" "$@" -f "saotehasotnehasthistohntnsahxstnhalcrgxgrlpyasxtsaosysxsatnhoy.txt" > /dev/null 2> "$out2" 318err="$?" 319 320checkerrtest "$d" "$err" "invalid file argument" "$out2" "$d" 321 322"$exe" "$@" "-$opt" -e "$exprs" > /dev/null 2> "$out2" 323err="$?" 324 325checkerrtest "$d" "$err" "invalid option argument" "$out2" "$d" 326 327"$exe" "$@" "--$lopt" -e "$exprs" > /dev/null 2> "$out2" 328err="$?" 329 330checkerrtest "$d" "$err" "invalid long option argument" "$out2" "$d" 331 332"$exe" "$@" "-u" -e "$exprs" > /dev/null 2> "$out2" 333err="$?" 334 335checkerrtest "$d" "$err" "unrecognized option argument" "$out2" "$d" 336 337"$exe" "$@" "--uniform" -e "$exprs" > /dev/null 2> "$out2" 338err="$?" 339 340checkerrtest "$d" "$err" "unrecognized long option argument" "$out2" "$d" 341 342"$exe" "$@" -f > /dev/null 2> "$out2" 343err="$?" 344 345checkerrtest "$d" "$err" "missing required argument to short option" "$out2" "$d" 346 347"$exe" "$@" --file > /dev/null 2> "$out2" 348err="$?" 349 350checkerrtest "$d" "$err" "missing required argument to long option" "$out2" "$d" 351 352"$exe" "$@" --version=5 > /dev/null 2> "$out2" 353err="$?" 354 355checkerrtest "$d" "$err" "given argument to long option with no argument" "$out2" "$d" 356 357"$exe" "$@" -: > /dev/null 2> "$out2" 358err="$?" 359 360checkerrtest "$d" "$err" "colon short option" "$out2" "$d" 361 362"$exe" "$@" --: > /dev/null 2> "$out2" 363err="$?" 364 365checkerrtest "$d" "$err" "colon long option" "$out2" "$d" 366 367printf 'pass\n' 368 369printf 'Running %s directory test...' "$d" 370 371"$exe" "$@" "$testdir" > /dev/null 2> "$out2" 372err="$?" 373 374checkerrtest "$d" "$err" "directory" "$out2" "$d" 375 376printf 'pass\n' 377 378printf 'Running %s binary file test...' "$d" 379 380bin="/bin/sh" 381 382"$exe" "$@" "$bin" > /dev/null 2> "$out2" 383err="$?" 384 385checkerrtest "$d" "$err" "binary file" "$out2" "$d" 386 387printf 'pass\n' 388 389printf 'Running %s binary stdin test...' "$d" 390 391cat "$bin" | "$exe" "$@" > /dev/null 2> "$out2" 392err="$?" 393 394checkerrtest "$d" "$err" "binary stdin" "$out2" "$d" 395 396printf 'pass\n' 397 398if [ "$d" = "bc" ]; then 399 400 printf 'Running %s limits tests...' "$d" 401 printf 'limits\n' | "$exe" "$@" > "$out2" /dev/null 2>&1 402 403 checktest_retcode "$d" "$?" "limits" 404 405 if [ ! -s "$out2" ]; then 406 err_exit "$d did not produce output on the limits test" 1 407 fi 408 409 exec printf 'pass\n' 410 411fi 412