Fix shellcheck warnings
[dejagnu.git] / dejagnu
blob33ccf6f7f1a7ac76884f7e5e279e3ae1c1eb0498
1 #! /bin/sh
3 # Copyright (C) 2018, 2021, 2024 Free Software Foundation, Inc.
5 # This file is part of DejaGnu.
7 # DejaGnu is free software: you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # DejaGnu is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with DejaGnu. If not, see <http://www.gnu.org/licenses/>.
20 # Portions from runtest Copyright (C) 1992-2016 Free Software Foundation, Inc.
22 # This script was written by Jacob Bachmeyer. Portions of this script are
23 # adapted from the existing runtest script originally written by Rob Savoye.
25 # This script finds an implementation for the command given, finds the
26 # proper interpreter, and then dispatches the command. This script can
27 # either be run with a command name as the first (few) argument(s), via a
28 # link from the command name, or some combination of those.
30 # shellcheck disable=SC2003
31 # The shellcheck tool complains about use of expr and recommends using
32 # newer shell features instead. Solaris 10 /bin/sh does not support the
33 # newer features, so we must use expr in this script.
35 # shellcheck disable=SC2006
36 # The shellcheck tool complains about the old style backtick command
37 # substitution. Solaris 10 /bin/sh does not support the new style $()
38 # command substitution and the usage of command substitution in this script
39 # is simple enough to work. Most notably, nesting backtick command
40 # substitution is tricky, but we do not do that.
42 # shellcheck disable=SC2016
43 # The shellcheck tool complains about single-quoted strings containing "$",
44 # such as Awk programs that access fields as aid to programmers unfamiliar
45 # with how the shell quoting rules differ from Python and JavaScript.
47 # shellcheck disable=SC2209
48 # The shellcheck tool complains about assigning certain constant strings to
49 # variables. In this script, the intended meaning is obvious in context.
51 # shellcheck disable=SC2268
52 # The shellcheck tool complains about using 'x' as a common prefix on both
53 # sides of a comparison. While this is no longer required, it does no harm.
55 # ##help
56 # #Usage: dejagnu COMMAND [ --help | OPTIONS... ]
57 # #Usage: dejagnu --help
58 # #Usage: dejagnu --version
59 # # --help Print help text
60 # # --version Print DejaGnu version
61 # ##end
63 # list of extensions supported for commands in priority order
64 Variants='gawk awk tcl exp bash sh'
65 readonly Variants
67 ## Recognize options
69 # For testing and development
70 override_ext=
71 if test x"$1" = x--DGTimpl ; then
72 override_ext=$2
73 shift 2
76 want_help=false
77 want_version=false
78 verbose=0
79 for a in "$@"; do
80 case $a in
81 --help) want_help=true ;;
82 -v|--v|-verbose|--verbose) verbose=`expr "$verbose" + 1` ;;
83 -V|--V|-version|--version) want_version=true ;;
84 esac
85 done
87 if expr "$verbose" \> 0 > /dev/null ; then
88 echo Verbose level is "$verbose"
91 ## Get the file name of this script and deduce @bindir@.
93 bindir=`echo "$0" | sed -e 's@/[^/]*$@@'`
94 if expr "$verbose" \> 0 > /dev/null ; then
95 echo Running launcher from "$bindir"
98 ## Find the commands.
100 # If running from source tree, they are in ./commands/ relative to this script.
101 # If installed, they are in @datadir@/dejagnu/commands/ on the system.
103 # This makes the same assumption as in runtest that one of these holds:
105 # @datadir@ == @bindir@/../share
106 # @datadir@ == @bindir@/../../share
107 # @datadir@ == /usr/share
108 # @datadir@ == /usr/local/share
110 if test -n "$DEJAGNULIBS" ; then
111 commdir="${DEJAGNULIBS}/commands"
112 datadir="${DEJAGNULIBS}"
113 elif test -d "${bindir}/commands" && test -f "${bindir}/runtest.exp" ; then
114 if expr "$verbose" \> 1 > /dev/null ; then
115 echo Running from source directory
117 commdir="${bindir}/commands"
118 datadir="${bindir}"
119 else
120 commdir=
121 bindir1up_check=`echo "$bindir" | sed -e 's@/[^/]*$@/share/dejagnu@'`
122 bindir2up_check=`echo "$bindir" | sed -e 's@/[^/]*/[^/]*$@/share/dejagnu@'`
123 for i in \
124 "${bindir1up_check}" "${bindir2up_check}" \
125 /usr/share/dejagnu /usr/local/share/dejagnu
127 if expr "$verbose" \> 1 > /dev/null ; then
128 echo Probing directory "$i"/commands
130 if test -d "$i"/commands ; then
131 commdir="$i"/commands
132 datadir="$i"
133 break
135 done
138 if test -z "${commdir}" ; then
139 echo ERROR: could not find command directory.
140 exit 2
143 if expr "$verbose" \> 0 > /dev/null ; then
144 echo Looking for commands in "$commdir"
147 ## Get the name of the requested command.
149 # Are we just looking for version information?
150 if $want_version ; then
151 frame_version=`grep '^set frame_version' "${datadir}/runtest.exp" \
152 | sed 's/^[^0-9]*//'`
153 echo 'dejagnu auxiliary launcher (DejaGnu)' "$frame_version"
154 exit 0
157 # Remove any leading autoconf platform prefix and the "dejagnu" prefix.
158 # command=`basename "$0" | sed -e 's/^.*-\?dejagnu-\?//'`
160 # The above simple solution is not portable, so we use Awk and two steps:
161 command=`echo "$0" | awk 'BEGIN { FS = "/" } { print $NF }'`
162 # First, we use a simple Awk program to perform the role of basename.
163 command=`echo "$command" | awk 'BEGIN { OFS = FS = "-" }
164 { for (i = 1; i <= NF; i++) if ($i ~ /dejagnu/) break;
165 i++; for (out = ""; i <= NF; i++) out = out OFS $i;
166 print substr(out,2) }'`
167 # Second, we split on "-" and search for a field matching /dejagnu/ to
168 # identify the other prefixes, then skip that field and the second loop
169 # collects any following fields. The spurious leading "-" is then removed
170 # using substr() and the result is returned to the shell.
172 # This roundabout approach maintains compatibility with Solaris 10, where
173 # awk allows only limited manipulation of the record structure.
175 while expr $# \> 0 > /dev/null
177 if test -z "${command}" ; then
178 case $1 in -*) break;; esac
179 command="$1"
180 shift
182 if expr "$verbose" \> 2 > /dev/null ; then
183 echo Looking for "${commdir}/${command}.*"
185 for ext in ${Variants}
187 if test -f "${commdir}/${command}.$ext" ; then
188 break 2
190 done
191 case $1 in -*) break;; esac
192 if test -n "$1" ; then
193 command="${command}-$1"
194 shift
195 else
196 break
198 done
200 commext=
201 for ext in ${Variants}
203 if test -f "${commdir}/${command}.$ext" ; then
204 commext="$commext $ext"
206 done
208 if test -z "$commext" && test -n "$command" ; then
209 echo ERROR: could not resolve command "$command"
210 exit 2
213 if expr "$verbose" \> 0 > /dev/null ; then
214 if test -n "$command"; then
215 if expr "$verbose" \> 1 > /dev/null ; then
216 echo Found subcommand "$command" with variants: "$commext"
217 else
218 echo Found subcommand "$command"
220 else
221 echo Running nothing.
225 ## Find interpreters.
227 # Awk and GNU awk
228 if test -n "$AWK" ; then
229 awkbin="$AWK"
230 elif test -x "${bindir}/awk" ; then
231 awkbin="${bindir}/awk"
232 else
233 # find what might be a usable awk
234 # on Solaris 10, POSIX awk is in /usr/xpg4/bin
235 for awktest in mawk /usr/xpg4/bin/awk nawk awk ; do
236 if command -v "$awktest" > /dev/null 2>&1 ; then
237 awkbin=$awktest
238 break;
240 done
242 if test -n "$GAWK" ; then
243 gawkbin="$GAWK"
244 elif test -x "${bindir}/gawk" ; then
245 gawkbin="${bindir}/gawk"
246 else
247 gawkbin=gawk
249 # The non-POSIX awk in /usr/bin on Solaris 10 fails this test
250 if echo | "$awkbin" '1 && 1 {exit 0}' > /dev/null 2>&1 ; then
251 have_awk=true
252 else
253 have_awk=false
255 if command -v "$gawkbin" > /dev/null 2>&1 ; then
256 have_gawk=true
257 else
258 have_gawk=false
260 # substitute GNU awk for awk if needed
261 if $have_gawk ; then
262 if $have_awk ; then : ; else
263 have_awk=$have_gawk
264 awkbin=$gawkbin
267 # is "awk" actually GNU Awk?
268 if $have_awk ; then
269 case `"$awkbin" --version </dev/null 2>&1 | sed 1q` in
270 *'GNU Awk'*) have_gawk_as_awk=true ;;
271 *) have_gawk_as_awk=false ;;
272 esac
274 if expr "$verbose" \> 2 > /dev/null ; then
275 if $have_awk ; then
276 echo Awk interpreter is "$awkbin"
277 else
278 echo Awk interpreter was not found
280 if $have_gawk ; then
281 echo GNU Awk interpreter is "$gawkbin"
282 else
283 echo GNU Awk interpreter was not found
286 # export chosen Awk and GNU Awk
287 if $have_awk ; then
288 AWK=$awkbin
289 export AWK
291 if $have_gawk ; then
292 GAWK=$gawkbin
293 export GAWK
297 # Bash
298 if test -n "$BASH" ; then
299 bashbin="$BASH"
300 elif test -x "${bindir}/bash" ; then
301 bashbin="${bindir}/bash"
302 elif test -x /bin/bash ; then
303 bashbin=/bin/bash
304 else
305 bashbin=bash
307 if command -v "$bashbin" > /dev/null 2>&1 ; then
308 have_bash=true
309 else
310 have_bash=false
312 if expr "$verbose" \> 2 > /dev/null ; then
313 if $have_bash ; then
314 echo Bash interpreter is "$bashbin"
315 else
316 echo Bash interpreter was not found
320 # Bourne shell
321 # This script is running, therefore we have a Bourne shell.
322 have_sh=true
324 # Expect
325 # DejaGnu configure bails out if Expect is not available, but this script
326 # can be run from the source directory without first running configure.
327 if test -n "$EXPECT" ; then
328 expectbin="$EXPECT"
329 elif test -x "${bindir}/expect" ; then
330 expectbin="${bindir}/expect"
331 else
332 expectbin=expect
334 if command -v "$expectbin" > /dev/null 2>&1 ; then
335 have_expect=true
336 else
337 have_expect=false
339 if expr "$verbose" \> 2 > /dev/null ; then
340 if $have_expect ; then
341 echo Expect interpreter is "$expectbin"
342 else
343 echo Expect interpreter was not found
347 # Tcl
348 if test -n "$TCLSH" ; then
349 tclbin="$TCLSH"
350 elif test -x "${bindir}/tclsh" ; then
351 tclbin="${bindir}/tclsh"
352 else
353 tclbin=tclsh
355 # substitute expect if needed
356 if command -v "$tclbin" > /dev/null 2>&1 ; then :
357 elif command -v "$expectbin" > /dev/null 2>&1 ; then tclbin="$expectbin"
359 if command -v "$tclbin" > /dev/null 2>&1 ; then
360 have_tcl=true
361 else
362 have_tcl=false
364 if expr "$verbose" \> 2 > /dev/null ; then
365 if $have_tcl ; then
366 echo Tcl interpreter is "$tclbin"
367 else
368 echo Tcl interpreter was not found
372 ## Select a variant.
374 if test -n "$override_ext" ; then
375 selected_ext="$override_ext"
376 else
377 selected_ext=
378 for v in $commext
380 case $v in
381 awk)
382 if $have_awk ; then
383 selected_ext=awk
384 break
387 bash)
388 if $have_bash ; then
389 selected_ext=bash
390 break
393 exp)
394 if $have_expect ; then
395 selected_ext=exp
396 break
399 gawk)
400 if $have_gawk ; then
401 selected_ext=gawk
402 break
405 tcl)
406 if $have_tcl ; then
407 selected_ext=tcl
408 break
412 selected_ext=sh
413 break
416 echo ERROR: '(select-variant)' unrecognized variant "$v"
418 esac
419 done
420 if test -z "$selected_ext" && test -n "$command" ; then
421 echo ERROR: no variant of "$command" was selected
422 exit 2
426 if test -n "$command" && expr "$verbose" \> 0 > /dev/null ; then
427 if test -n "$override_ext" ; then
428 echo Selected variant "$selected_ext" by override
429 else
430 echo Selected variant "$selected_ext"
434 ## Dispatch to the selected command.
436 # Are we just looking for a usage message?
437 if $want_help ; then
438 if $have_awk; then : ; else
439 echo ERROR: extracting help message requires POSIX Awk
440 exit 2
442 if test -z "$command" ; then
443 # want help on the launcher itself
444 help_file=$0
445 else
446 help_file="${commdir}/${command}.${selected_ext}"
448 if test ! -r "$help_file" ; then
449 echo ERROR: file "'$help_file'" is not readable
450 exit 2
452 if "$AWK" '/#help$/ { pfxlen = length($0) - 4 }
453 pfxlen && substr($0, pfxlen) == "#end" { exit 1 }
454 ' "$help_file" ; then
455 echo ERROR: file "'$help_file'" does not contain a help message
456 exit 2
458 exec "$AWK" '/#help$/ { pfxlen = length($0) - 4; next }
459 pfxlen && substr($0, pfxlen) == "#end" { exit 0 }
460 pfxlen { print substr($0, pfxlen) }' "$help_file"
463 if test -z "$command" ; then
464 if test -n "$override_ext" ; then
465 case $selected_ext in
466 awk) if $have_awk; then exit 0; else exit 1; fi ;;
467 bash) if $have_bash; then exit 0; else exit 1; fi ;;
468 exp) if $have_expect; then exit 0; else exit 1; fi ;;
469 gawk) if $have_gawk; then exit 0; else exit 1; fi ;;
470 tcl) if $have_tcl; then exit 0; else exit 1; fi ;;
471 sh) if $have_sh; then exit 0; else exit 1; fi ;;
472 *) exit 2 ;;
473 esac
474 else
475 echo ERROR: no command given
476 exit 2
480 case $selected_ext in
481 awk)
482 if $have_gawk_as_awk ; then
483 exec "$awkbin" --posix -f "${commdir}/${command}.awk" -- ${1+"$@"}
484 else
485 exec "$awkbin" -f "${commdir}/${command}.awk" -- ${1+"$@"}
488 bash) exec "$bashbin" -- "${commdir}/${command}.bash" ${1+"$@"} ;;
489 exp) exec "$expectbin" -- "${commdir}/${command}.exp" ${1+"$@"} ;;
490 gawk) exec "$gawkbin" -f "${commdir}/${command}.gawk" -- ${1+"$@"} ;;
491 tcl) exec "$tclbin" "${commdir}/${command}.tcl" ${1+"$@"} ;;
492 sh) exec /bin/sh "${commdir}/${command}.sh" ${1+"$@"} ;;
493 echo)
494 echo command: "${command}"
495 echo args: ${1+"$@"}
496 exit 0
499 echo ERROR: '(run-variant)' unrecognized variant "$selected_ext"
500 exit 2
502 esac
504 #EOF