Change #! lines in launcher scripts
[dejagnu.git] / dejagnu
blob9b4480ec05c7916e6878cdf5e97bd43e34ecf0d3
1 #! /bin/sh
3 # Copyright (C) 2018, 2021 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=SC2209
43 # The shellcheck tool complains about assigning certain constant strings to
44 # variables. In this script, the intended meaning is obvious in context.
46 # ##help
47 # #Usage: dejagnu COMMAND [ --help | OPTIONS... ]
48 # #Usage: dejagnu --help
49 # #Usage: dejagnu --version
50 # # --help Print help text
51 # # --version Print DejaGnu version
52 # ##end
54 # list of extensions supported for commands in priority order
55 Variants='gawk awk tcl exp bash sh'
56 readonly Variants
58 ## Recognize options
60 # For testing and development
61 override_ext=
62 if test x"$1" = x--DGTimpl ; then
63 override_ext=$2
64 shift 2
67 want_help=false
68 want_version=false
69 verbose=0
70 for a in "$@"; do
71 case $a in
72 --help) want_help=true ;;
73 -v|--v|-verbose|--verbose) verbose=`expr $verbose + 1` ;;
74 -V|--V|-version|--version) want_version=true ;;
75 esac
76 done
78 if expr "$verbose" \> 0 > /dev/null ; then
79 echo Verbose level is "$verbose"
82 ## Get the file name of this script and deduce @bindir@.
84 bindir=`echo "$0" | sed -e 's@/[^/]*$@@'`
85 if expr "$verbose" \> 0 > /dev/null ; then
86 echo Running launcher from "$bindir"
89 ## Find the commands.
91 # If running from source tree, they are in ./commands/ relative to this script.
92 # If installed, they are in @datadir@/dejagnu/commands/ on the system.
94 # This makes the same assumption as in runtest that one of these holds:
96 # @datadir@ == @bindir@/../share
97 # @datadir@ == @bindir@/../../share
98 # @datadir@ == /usr/share
99 # @datadir@ == /usr/local/share
101 if test -n "$DEJAGNULIBS" ; then
102 commdir="${DEJAGNULIBS}/commands"
103 datadir="${DEJAGNULIBS}"
104 elif test -d "${bindir}/commands" && test -f "${bindir}/runtest.exp" ; then
105 if expr "$verbose" \> 1 > /dev/null ; then
106 echo Running from source directory
108 commdir="${bindir}/commands"
109 datadir="${bindir}"
110 else
111 commdir=
112 bindir1up_check=`echo "$bindir" | sed -e 's@/[^/]*$@/share/dejagnu@'`
113 bindir2up_check=`echo "$bindir" | sed -e 's@/[^/]*/[^/]*$@/share/dejagnu@'`
114 for i in \
115 "${bindir1up_check}" "${bindir2up_check}" \
116 /usr/share/dejagnu /usr/local/share/dejagnu
118 if expr "$verbose" \> 1 > /dev/null ; then
119 echo Probing directory "$i"/commands
121 if test -d "$i"/commands ; then
122 commdir="$i"/commands
123 datadir="$i"
124 break
126 done
129 if test -z "${commdir}" ; then
130 echo ERROR: could not find command directory.
131 exit 2
134 if expr "$verbose" \> 0 > /dev/null ; then
135 echo Looking for commands in "$commdir"
138 ## Get the name of the requested command.
140 # Are we just looking for version information?
141 if $want_version ; then
142 frame_version=`grep '^set frame_version' "${datadir}/runtest.exp" \
143 | sed 's/^[^0-9]*//'`
144 echo 'dejagnu auxiliary launcher (DejaGnu)' "$frame_version"
145 exit 0
148 # Remove any leading autoconf platform prefix and the "dejagnu" prefix.
149 # command=`basename "$0" | sed -e 's/^.*-\?dejagnu-\?//'`
151 # The above simple solution is not portable, so we use Awk and two steps:
152 command=`echo "$0" | awk 'BEGIN { FS = "/" } { print $NF }'`
153 # First, we use a simple Awk program to perform the role of basename.
154 command=`echo "$command" | awk 'BEGIN { OFS = FS = "-" }
155 { for (i = 1; i <= NF; i++) if ($i ~ /dejagnu/) break;
156 i++; for (out = ""; i <= NF; i++) out = out OFS $i;
157 print substr(out,2) }'`
158 # Second, we split on "-" and search for a field matching /dejagnu/ to
159 # identify the other prefixes, then skip that field and the second loop
160 # collects any following fields. The spurious leading "-" is then removed
161 # using substr() and the result is returned to the shell.
163 # This roundabout approach maintains compatibility with Solaris 10, where
164 # awk allows only limited manipulation of the record structure.
166 while expr $# \> 0 > /dev/null
168 if test -z "${command}" ; then
169 case $1 in -*) break;; esac
170 command="$1"
171 shift
173 if expr "$verbose" \> 2 > /dev/null ; then
174 echo Looking for "${commdir}/${command}.*"
176 for ext in ${Variants}
178 if test -f "${commdir}/${command}.$ext" ; then
179 break 2
181 done
182 case $1 in -*) break;; esac
183 if test -n "$1" ; then
184 command="${command}-$1"
185 shift
186 else
187 break
189 done
191 commext=
192 for ext in ${Variants}
194 if test -f "${commdir}/${command}.$ext" ; then
195 commext="$commext $ext"
197 done
199 if test -z "$commext" && test -n "$command" ; then
200 echo ERROR: could not resolve command "$command"
201 exit 2
204 if expr "$verbose" \> 0 > /dev/null ; then
205 if test -n "$command"; then
206 if expr "$verbose" \> 1 > /dev/null ; then
207 echo Found subcommand "$command" with variants: "$commext"
208 else
209 echo Found subcommand "$command"
211 else
212 echo Running nothing.
216 ## Find interpreters.
218 # Awk and GNU awk
219 if test -n "$AWK" ; then
220 awkbin="$AWK"
221 elif test -x "${bindir}/awk" ; then
222 awkbin="${bindir}/awk"
223 else
224 # find what might be a usable awk
225 # on Solaris 10, POSIX awk is in /usr/xpg4/bin
226 for awktest in mawk /usr/xpg4/bin/awk nawk awk ; do
227 if command -v "$awktest" > /dev/null 2>&1 ; then
228 awkbin=$awktest
229 break;
231 done
233 if test -n "$GAWK" ; then
234 gawkbin="$GAWK"
235 elif test -x "${bindir}/gawk" ; then
236 gawkbin="${bindir}/gawk"
237 else
238 gawkbin=gawk
240 # The non-POSIX awk in /usr/bin on Solaris 10 fails this test
241 if echo | "$awkbin" '1 && 1 {exit 0}' > /dev/null 2>&1 ; then
242 have_awk=true
243 else
244 have_awk=false
246 if command -v "$gawkbin" > /dev/null 2>&1 ; then
247 have_gawk=true
248 else
249 have_gawk=false
251 # substitute GNU awk for awk if needed
252 if $have_gawk ; then
253 if $have_awk ; then : ; else
254 have_awk=$have_gawk
255 awkbin=$gawkbin
258 # is "awk" actually GNU Awk?
259 if $have_awk ; then
260 case `"$awkbin" --version </dev/null 2>&1 | sed 1q` in
261 *'GNU Awk'*) have_gawk_as_awk=true ;;
262 *) have_gawk_as_awk=false ;;
263 esac
265 if expr "$verbose" \> 2 > /dev/null ; then
266 if $have_awk ; then
267 echo Awk interpreter is "$awkbin"
268 else
269 echo Awk interpreter was not found
271 if $have_gawk ; then
272 echo GNU Awk interpreter is "$gawkbin"
273 else
274 echo GNU Awk interpreter was not found
277 # export chosen Awk and GNU Awk
278 if $have_awk ; then
279 AWK=$awkbin
280 export AWK
282 if $have_gawk ; then
283 GAWK=$gawkbin
284 export GAWK
288 # Bash
289 if test -n "$BASH" ; then
290 bashbin="$BASH"
291 elif test -x "${bindir}/bash" ; then
292 bashbin="${bindir}/bash"
293 elif test -x /bin/bash ; then
294 bashbin=/bin/bash
295 else
296 bashbin=bash
298 if command -v "$bashbin" > /dev/null 2>&1 ; then
299 have_bash=true
300 else
301 have_bash=false
303 if expr "$verbose" \> 2 > /dev/null ; then
304 if $have_bash ; then
305 echo Bash interpreter is "$bashbin"
306 else
307 echo Bash interpreter was not found
311 # Bourne shell
312 # This script is running, therefore we have a Bourne shell.
313 have_sh=true
315 # Expect
316 # DejaGnu configure bails out if Expect is not available, but this script
317 # can be run from the source directory without first running configure.
318 if test -n "$EXPECT" ; then
319 expectbin="$EXPECT"
320 elif test -x "${bindir}/expect" ; then
321 expectbin="${bindir}/expect"
322 else
323 expectbin=expect
325 if command -v "$expectbin" > /dev/null 2>&1 ; then
326 have_expect=true
327 else
328 have_expect=false
330 if expr "$verbose" \> 2 > /dev/null ; then
331 if $have_expect ; then
332 echo Expect interpreter is "$expectbin"
333 else
334 echo Expect interpreter was not found
338 # Tcl
339 if test -n "$TCLSH" ; then
340 tclbin="$TCLSH"
341 elif test -x "${bindir}/tclsh" ; then
342 tclbin="${bindir}/tclsh"
343 else
344 tclbin=tclsh
346 # substitute expect if needed
347 if command -v "$tclbin" > /dev/null 2>&1 ; then :
348 elif command -v "$expectbin" > /dev/null 2>&1 ; then tclbin="$expectbin"
350 if command -v "$tclbin" > /dev/null 2>&1 ; then
351 have_tcl=true
352 else
353 have_tcl=false
355 if expr "$verbose" \> 2 > /dev/null ; then
356 if $have_tcl ; then
357 echo Tcl interpreter is "$tclbin"
358 else
359 echo Tcl interpreter was not found
363 ## Select a variant.
365 if test -n "$override_ext" ; then
366 selected_ext="$override_ext"
367 else
368 selected_ext=
369 for v in $commext
371 case $v in
372 awk)
373 if $have_awk ; then
374 selected_ext=awk
375 break
378 bash)
379 if $have_bash ; then
380 selected_ext=bash
381 break
384 exp)
385 if $have_expect ; then
386 selected_ext=exp
387 break
390 gawk)
391 if $have_gawk ; then
392 selected_ext=gawk
393 break
396 tcl)
397 if $have_tcl ; then
398 selected_ext=tcl
399 break
403 selected_ext=sh
404 break
407 echo ERROR: '(select-variant)' unrecognized variant "$v"
409 esac
410 done
411 if test -z "$selected_ext" && test -n "$command" ; then
412 echo ERROR: no variant of "$command" was selected
413 exit 2
417 if test -n "$command" && expr "$verbose" \> 0 > /dev/null ; then
418 if test -n "$override_ext" ; then
419 echo Selected variant "$selected_ext" by override
420 else
421 echo Selected variant "$selected_ext"
425 ## Dispatch to the selected command.
427 # Are we just looking for a usage message?
428 if $want_help ; then
429 if $have_awk; then : ; else
430 echo ERROR: extracting help message requires POSIX Awk
431 exit 2
433 if test -z "$command" ; then
434 # want help on the launcher itself
435 help_file=$0
436 else
437 help_file="${commdir}/${command}.${selected_ext}"
439 if test ! -r "$help_file" ; then
440 echo ERROR: file "'$help_file'" is not readable
441 exit 2
443 if "$AWK" '/#help$/ { pfxlen = length($0) - 4 }
444 pfxlen && substr($0, pfxlen) == "#end" { exit 1 }
445 ' "$help_file" ; then
446 echo ERROR: file "'$help_file'" does not contain a help message
447 exit 2
449 exec "$AWK" '/#help$/ { pfxlen = length($0) - 4 }
450 pfxlen && substr($0, pfxlen) == "#end" { exit 0 }
451 pfxlen { print substr($0, pfxlen) }' "$help_file"
454 if test -z "$command" ; then
455 if test -n "$override_ext" ; then
456 case $selected_ext in
457 awk) if $have_awk; then exit 0; else exit 1; fi ;;
458 bash) if $have_bash; then exit 0; else exit 1; fi ;;
459 exp) if $have_expect; then exit 0; else exit 1; fi ;;
460 gawk) if $have_gawk; then exit 0; else exit 1; fi ;;
461 tcl) if $have_tcl; then exit 0; else exit 1; fi ;;
462 sh) if $have_sh; then exit 0; else exit 1; fi ;;
463 *) exit 2 ;;
464 esac
465 else
466 echo ERROR: no command given
467 exit 2
471 case $selected_ext in
472 awk)
473 if $have_gawk_as_awk ; then
474 exec "$awkbin" --posix -f "${commdir}/${command}.awk" -- ${1+"$@"}
475 else
476 exec "$awkbin" -f "${commdir}/${command}.awk" -- ${1+"$@"}
479 bash) exec "$bashbin" -- "${commdir}/${command}.bash" ${1+"$@"} ;;
480 exp) exec "$expectbin" -- "${commdir}/${command}.exp" ${1+"$@"} ;;
481 gawk) exec "$gawkbin" -f "${commdir}/${command}.gawk" -- ${1+"$@"} ;;
482 tcl) exec "$tclbin" "${commdir}/${command}.tcl" ${1+"$@"} ;;
483 sh) exec /bin/sh "${commdir}/${command}.sh" ${1+"$@"} ;;
484 echo)
485 echo command: "${command}"
486 echo args: ${1+"$@"}
487 exit 0
490 echo ERROR: '(run-variant)' unrecognized variant "$selected_ext"
491 exit 2
493 esac
495 #EOF