| #!/bin/sh |
| # |
| # Copyright (C) 2018, 2021 Free Software Foundation, Inc. |
| # |
| # This file is part of DejaGnu. |
| # |
| # DejaGnu is free software; you can redistribute it and/or modify it |
| # under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # DejaGnu is distributed in the hope that it will be useful, but |
| # WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| # General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with DejaGnu; if not, write to the Free Software Foundation, |
| # Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
| |
| # Portions from runtest Copyright (C) 1992-2016 Free Software Foundation, Inc. |
| |
| # This script was written by Jacob Bachmeyer. Portions of this script are |
| # adapted from the existing runtest script originally written by Rob Savoye. |
| |
| # This script finds an implementation for the command given, finds the |
| # proper interpreter, and then dispatches the command. This script can |
| # either be run with a command name as the first (few) argument(s), via a |
| # link from the command name, or some combination of those. |
| |
| # shellcheck disable=SC2003 |
| # The shellcheck tool complains about use of expr and recommends using |
| # newer shell features instead. Solaris 10 /bin/sh does not support the |
| # newer features, so we must use expr in this script. |
| |
| # shellcheck disable=SC2006 |
| # The shellcheck tool complains about the old style backtick command |
| # substitution. Solaris 10 /bin/sh does not support the new style $() |
| # command substitution and the usage of command substitution in this script |
| # is simple enough to work. Most notably, nesting backtick command |
| # substitution is tricky, but we do not do that. |
| |
| # shellcheck disable=SC2209 |
| # The shellcheck tool complains about assigning certain constant strings to |
| # variables. In this script, the intended meaning is obvious in context. |
| |
| # ##help |
| # #Usage: dejagnu COMMAND [ --help | OPTIONS... ] |
| # #Usage: dejagnu --help |
| # #Usage: dejagnu --version |
| # # --help Print help text |
| # # --version Print DejaGnu version |
| # ##end |
| |
| # list of extensions supported for commands in priority order |
| Variants='gawk awk tcl exp bash sh' |
| readonly Variants |
| |
| ## Recognize options |
| |
| # For testing and development |
| override_ext= |
| if test x"$1" = x--DGTimpl ; then |
| override_ext=$2 |
| shift 2 |
| fi |
| |
| want_help=false |
| want_version=false |
| verbose=0 |
| for a in "$@"; do |
| case $a in |
| --help) want_help=true ;; |
| -v|--v|-verbose|--verbose) verbose=`expr $verbose + 1` ;; |
| -V|--V|-version|--version) want_version=true ;; |
| esac |
| done |
| |
| if expr "$verbose" \> 0 > /dev/null ; then |
| echo Verbose level is "$verbose" |
| fi |
| |
| ## Get the file name of this script and deduce @bindir@. |
| |
| bindir=`echo "$0" | sed -e 's@/[^/]*$@@'` |
| if expr "$verbose" \> 0 > /dev/null ; then |
| echo Running launcher from "$bindir" |
| fi |
| |
| ## Find the commands. |
| |
| # If running from source tree, they are in ./commands/ relative to this script. |
| # If installed, they are in @datadir@/dejagnu/commands/ on the system. |
| |
| # This makes the same assumption as in runtest that one of these holds: |
| # |
| # @datadir@ == @bindir@/../share |
| # @datadir@ == @bindir@/../../share |
| # @datadir@ == /usr/share |
| # @datadir@ == /usr/local/share |
| |
| if test -n "$DEJAGNULIBS" ; then |
| commdir="${DEJAGNULIBS}/commands" |
| datadir="${DEJAGNULIBS}" |
| elif test -d "${bindir}/commands" && test -f "${bindir}/runtest.exp" ; then |
| if expr "$verbose" \> 1 > /dev/null ; then |
| echo Running from source directory |
| fi |
| commdir="${bindir}/commands" |
| datadir="${bindir}" |
| else |
| commdir= |
| bindir1up_check=`echo "$bindir" | sed -e 's@/[^/]*$@/share/dejagnu@'` |
| bindir2up_check=`echo "$bindir" | sed -e 's@/[^/]*/[^/]*$@/share/dejagnu@'` |
| for i in \ |
| "${bindir1up_check}" "${bindir2up_check}" \ |
| /usr/share/dejagnu /usr/local/share/dejagnu |
| do |
| if expr "$verbose" \> 1 > /dev/null ; then |
| echo Probing directory "$i"/commands |
| fi |
| if test -d "$i"/commands ; then |
| commdir="$i"/commands |
| datadir="$i" |
| break |
| fi |
| done |
| fi |
| |
| if test -z "${commdir}" ; then |
| echo ERROR: could not find command directory. |
| exit 2 |
| fi |
| |
| if expr "$verbose" \> 0 > /dev/null ; then |
| echo Looking for commands in "$commdir" |
| fi |
| |
| ## Get the name of the requested command. |
| |
| # Are we just looking for version information? |
| if $want_version ; then |
| frame_version=`grep '^set frame_version' "${datadir}/runtest.exp" \ |
| | sed 's/^[^0-9]*//'` |
| echo 'dejagnu auxiliary launcher (DejaGnu)' "$frame_version" |
| exit 0 |
| fi |
| |
| # Remove any leading autoconf platform prefix and the "dejagnu" prefix. |
| # command=`basename "$0" | sed -e 's/^.*-\?dejagnu-\?//'` |
| |
| # The above simple solution is not portable, so we use Awk and two steps: |
| command=`echo "$0" | awk 'BEGIN { FS = "/" } { print $NF }'` |
| # First, we use a simple Awk program to perform the role of basename. |
| command=`echo "$command" | awk 'BEGIN { OFS = FS = "-" } |
| { for (i = 1; i <= NF; i++) if ($i ~ /dejagnu/) break; |
| i++; for (out = ""; i <= NF; i++) out = out OFS $i; |
| print substr(out,2) }'` |
| # Second, we split on "-" and search for a field matching /dejagnu/ to |
| # identify the other prefixes, then skip that field and the second loop |
| # collects any following fields. The spurious leading "-" is then removed |
| # using substr() and the result is returned to the shell. |
| |
| # This roundabout approach maintains compatibility with Solaris 10, where |
| # awk allows only limited manipulation of the record structure. |
| |
| while expr $# \> 0 > /dev/null |
| do |
| if test -z "${command}" ; then |
| case $1 in -*) break;; esac |
| command="$1" |
| shift |
| fi |
| if expr "$verbose" \> 2 > /dev/null ; then |
| echo Looking for "${commdir}/${command}.*" |
| fi |
| for ext in ${Variants} |
| do |
| if test -f "${commdir}/${command}.$ext" ; then |
| break 2 |
| fi |
| done |
| case $1 in -*) break;; esac |
| if test -n "$1" ; then |
| command="${command}-$1" |
| shift |
| else |
| break |
| fi |
| done |
| |
| commext= |
| for ext in ${Variants} |
| do |
| if test -f "${commdir}/${command}.$ext" ; then |
| commext="$commext $ext" |
| fi |
| done |
| |
| if test -z "$commext" && test -n "$command" ; then |
| echo ERROR: could not resolve command "$command" |
| exit 2 |
| fi |
| |
| if expr "$verbose" \> 0 > /dev/null ; then |
| if test -n "$command"; then |
| if expr "$verbose" \> 1 > /dev/null ; then |
| echo Found subcommand "$command" with variants: "$commext" |
| else |
| echo Found subcommand "$command" |
| fi |
| else |
| echo Running nothing. |
| fi |
| fi |
| |
| ## Find interpreters. |
| |
| # Awk and GNU awk |
| if test -n "$AWK" ; then |
| awkbin="$AWK" |
| elif test -x "${bindir}/awk" ; then |
| awkbin="${bindir}/awk" |
| else |
| # find what might be a usable awk |
| # on Solaris 10, POSIX awk is in /usr/xpg4/bin |
| for awktest in mawk /usr/xpg4/bin/awk nawk awk ; do |
| if command -v "$awktest" > /dev/null 2>&1 ; then |
| awkbin=$awktest |
| break; |
| fi |
| done |
| fi |
| if test -n "$GAWK" ; then |
| gawkbin="$GAWK" |
| elif test -x "${bindir}/gawk" ; then |
| gawkbin="${bindir}/gawk" |
| else |
| gawkbin=gawk |
| fi |
| # The non-POSIX awk in /usr/bin on Solaris 10 fails this test |
| if echo | "$awkbin" '1 && 1 {exit 0}' > /dev/null 2>&1 ; then |
| have_awk=true |
| else |
| have_awk=false |
| fi |
| if command -v "$gawkbin" > /dev/null 2>&1 ; then |
| have_gawk=true |
| else |
| have_gawk=false |
| fi |
| # substitute GNU awk for awk if needed |
| if $have_gawk ; then |
| if $have_awk ; then : ; else |
| have_awk=$have_gawk |
| awkbin=$gawkbin |
| fi |
| fi |
| # is "awk" actually GNU Awk? |
| if $have_awk ; then |
| case `"$awkbin" --version </dev/null 2>&1 | sed 1q` in |
| *'GNU Awk'*) have_gawk_as_awk=true ;; |
| *) have_gawk_as_awk=false ;; |
| esac |
| fi |
| if expr "$verbose" \> 2 > /dev/null ; then |
| if $have_awk ; then |
| echo Awk interpreter is "$awkbin" |
| else |
| echo Awk interpreter was not found |
| fi |
| if $have_gawk ; then |
| echo GNU Awk interpreter is "$gawkbin" |
| else |
| echo GNU Awk interpreter was not found |
| fi |
| fi |
| # export chosen Awk and GNU Awk |
| if $have_awk ; then |
| AWK=$awkbin |
| export AWK |
| fi |
| if $have_gawk ; then |
| GAWK=$gawkbin |
| export GAWK |
| fi |
| |
| |
| # Bash |
| if test -n "$BASH" ; then |
| bashbin="$BASH" |
| elif test -x "${bindir}/bash" ; then |
| bashbin="${bindir}/bash" |
| elif test -x /bin/bash ; then |
| bashbin=/bin/bash |
| else |
| bashbin=bash |
| fi |
| if command -v "$bashbin" > /dev/null 2>&1 ; then |
| have_bash=true |
| else |
| have_bash=false |
| fi |
| if expr "$verbose" \> 2 > /dev/null ; then |
| if $have_bash ; then |
| echo Bash interpreter is "$bashbin" |
| else |
| echo Bash interpreter was not found |
| fi |
| fi |
| |
| # Bourne shell |
| # This script is running, therefore we have a Bourne shell. |
| have_sh=true |
| |
| # Expect |
| # DejaGnu configure bails out if Expect is not available, but this script |
| # can be run from the source directory without first running configure. |
| if test -n "$EXPECT" ; then |
| expectbin="$EXPECT" |
| elif test -x "${bindir}/expect" ; then |
| expectbin="${bindir}/expect" |
| else |
| expectbin=expect |
| fi |
| if command -v "$expectbin" > /dev/null 2>&1 ; then |
| have_expect=true |
| else |
| have_expect=false |
| fi |
| if expr "$verbose" \> 2 > /dev/null ; then |
| if $have_expect ; then |
| echo Expect interpreter is "$expectbin" |
| else |
| echo Expect interpreter was not found |
| fi |
| fi |
| |
| # Tcl |
| if test -n "$TCLSH" ; then |
| tclbin="$TCLSH" |
| elif test -x "${bindir}/tclsh" ; then |
| tclbin="${bindir}/tclsh" |
| else |
| tclbin=tclsh |
| fi |
| # substitute expect if needed |
| if command -v "$tclbin" > /dev/null 2>&1 ; then : |
| elif command -v "$expectbin" > /dev/null 2>&1 ; then tclbin="$expectbin" |
| fi |
| if command -v "$tclbin" > /dev/null 2>&1 ; then |
| have_tcl=true |
| else |
| have_tcl=false |
| fi |
| if expr "$verbose" \> 2 > /dev/null ; then |
| if $have_tcl ; then |
| echo Tcl interpreter is "$tclbin" |
| else |
| echo Tcl interpreter was not found |
| fi |
| fi |
| |
| ## Select a variant. |
| |
| if test -n "$override_ext" ; then |
| selected_ext="$override_ext" |
| else |
| selected_ext= |
| for v in $commext |
| do |
| case $v in |
| awk) |
| if $have_awk ; then |
| selected_ext=awk |
| break |
| fi |
| ;; |
| bash) |
| if $have_bash ; then |
| selected_ext=bash |
| break |
| fi |
| ;; |
| exp) |
| if $have_expect ; then |
| selected_ext=exp |
| break |
| fi |
| ;; |
| gawk) |
| if $have_gawk ; then |
| selected_ext=gawk |
| break |
| fi |
| ;; |
| tcl) |
| if $have_tcl ; then |
| selected_ext=tcl |
| break |
| fi |
| ;; |
| sh) |
| selected_ext=sh |
| break |
| ;; |
| *) |
| echo ERROR: '(select-variant)' unrecognized variant "$v" |
| ;; |
| esac |
| done |
| if test -z "$selected_ext" && test -n "$command" ; then |
| echo ERROR: no variant of "$command" was selected |
| exit 2 |
| fi |
| fi |
| |
| if test -n "$command" && expr "$verbose" \> 0 > /dev/null ; then |
| if test -n "$override_ext" ; then |
| echo Selected variant "$selected_ext" by override |
| else |
| echo Selected variant "$selected_ext" |
| fi |
| fi |
| |
| ## Dispatch to the selected command. |
| |
| # Are we just looking for a usage message? |
| if $want_help ; then |
| if $have_awk; then : ; else |
| echo ERROR: extracting help message requires POSIX Awk |
| exit 2 |
| fi |
| if test -z "$command" ; then |
| # want help on the launcher itself |
| help_file=$0 |
| else |
| help_file="${commdir}/${command}.${selected_ext}" |
| fi |
| if test ! -r "$help_file" ; then |
| echo ERROR: file "'$help_file'" is not readable |
| exit 2 |
| fi |
| if "$AWK" '/#help$/ { pfxlen = length($0) - 4 } |
| pfxlen && substr($0, pfxlen) == "#end" { exit 1 } |
| ' "$help_file" ; then |
| echo ERROR: file "'$help_file'" does not contain a help message |
| exit 2 |
| fi |
| exec "$AWK" '/#help$/ { pfxlen = length($0) - 4 } |
| pfxlen && substr($0, pfxlen) == "#end" { exit 0 } |
| pfxlen { print substr($0, pfxlen) }' "$help_file" |
| fi |
| |
| if test -z "$command" ; then |
| if test -n "$override_ext" ; then |
| case $selected_ext in |
| awk) if $have_awk; then exit 0; else exit 1; fi ;; |
| bash) if $have_bash; then exit 0; else exit 1; fi ;; |
| exp) if $have_expect; then exit 0; else exit 1; fi ;; |
| gawk) if $have_gawk; then exit 0; else exit 1; fi ;; |
| tcl) if $have_tcl; then exit 0; else exit 1; fi ;; |
| sh) if $have_sh; then exit 0; else exit 1; fi ;; |
| *) exit 2 ;; |
| esac |
| else |
| echo ERROR: no command given |
| exit 2 |
| fi |
| fi |
| |
| case $selected_ext in |
| awk) |
| if $have_gawk_as_awk ; then |
| exec "$awkbin" --posix -f "${commdir}/${command}.awk" -- ${1+"$@"} |
| else |
| exec "$awkbin" -f "${commdir}/${command}.awk" -- ${1+"$@"} |
| fi |
| ;; |
| bash) exec "$bashbin" -- "${commdir}/${command}.bash" ${1+"$@"} ;; |
| exp) exec "$expectbin" -- "${commdir}/${command}.exp" ${1+"$@"} ;; |
| gawk) exec "$gawkbin" -f "${commdir}/${command}.gawk" -- ${1+"$@"} ;; |
| tcl) exec "$tclbin" "${commdir}/${command}.tcl" ${1+"$@"} ;; |
| sh) exec /bin/sh "${commdir}/${command}.sh" ${1+"$@"} ;; |
| echo) |
| echo command: "${command}" |
| echo args: ${1+"$@"} |
| exit 0 |
| ;; |
| *) |
| echo ERROR: '(run-variant)' unrecognized variant "$selected_ext" |
| exit 2 |
| ;; |
| esac |
| |
| #EOF |