Home | History | Annotate | Line # | Download | only in dotcmd
      1  1.1  christos #!/bin/sh
      2  1.1  christos #
      3  1.3       kre # $NetBSD: scoped_command,v 1.3 2018/12/04 09:47:25 kre Exp $
      4  1.1  christos #
      5  1.1  christos # Copyright (c) 2014 The NetBSD Foundation, Inc.
      6  1.1  christos # All rights reserved.
      7  1.1  christos #
      8  1.1  christos # This code is derived from software contributed to The NetBSD Foundation
      9  1.1  christos # by Jarmo Jaakkola.
     10  1.1  christos #
     11  1.1  christos # Redistribution and use in source and binary forms, with or without
     12  1.1  christos # modification, are permitted provided that the following conditions
     13  1.1  christos # are met:
     14  1.1  christos # 1. Redistributions of source code must retain the above copyright
     15  1.1  christos #    notice, this list of conditions and the following disclaimer.
     16  1.1  christos # 2. Redistributions in binary form must reproduce the above copyright
     17  1.1  christos #    notice, this list of conditions and the following disclaimer in the
     18  1.1  christos #    documentation and/or other materials provided with the distribution.
     19  1.1  christos #
     20  1.1  christos # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  1.1  christos # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  1.1  christos # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  1.1  christos # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  1.1  christos # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  1.1  christos # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  1.1  christos # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  1.1  christos # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  1.1  christos # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  1.1  christos # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  1.1  christos # POSSIBILITY OF SUCH DAMAGE.
     31  1.1  christos #
     32  1.1  christos 
     33  1.2  christos : ${TEST_SH:=/bin/sh}
     34  1.2  christos 
     35  1.2  christos sane_sh()
     36  1.2  christos {
     37  1.2  christos 	set -- ${TEST_SH}
     38  1.2  christos 	case "$#" in
     39  1.2  christos 	(0)   set /bin/sh;;
     40  1.2  christos 	(1|2) ;;
     41  1.2  christos 	(*)   set "$1";;   # Just ignore options if we cannot make them work
     42  1.2  christos 	esac
     43  1.2  christos 
     44  1.2  christos 	case "$1" in
     45  1.2  christos 	/*)	TEST_SH="$1${2+ }$2";;
     46  1.2  christos 	./*)	TEST_SH="${PWD}${1#.}${2+ }$2";;
     47  1.2  christos 	*/*)	TEST_SH="${PWD}/$1${2+ }$2";;
     48  1.2  christos 	*)	TEST_SH="$( command -v "$1" )${2+ }$2";;
     49  1.2  christos 	esac
     50  1.2  christos }
     51  1.2  christos 
     52  1.2  christos sane_sh
     53  1.2  christos 
     54  1.1  christos set -e
     55  1.1  christos 
     56  1.1  christos # USAGE:
     57  1.1  christos #   scoped_command scope cmd msg var_suffix
     58  1.1  christos #
     59  1.1  christos # Write to stdout a piece of Bourne Shell script with _cmd_ in specific
     60  1.1  christos # _scope_.  The execution of _cmd_ is bracketed by prints of "before _msg_"
     61  1.1  christos # and "after _msg_, return value ${?}".  If the generated script uses
     62  1.1  christos # variables, __var_suffix_ is appended to their names to allow nesting of
     63  1.1  christos # scripts generated this way.
     64  1.1  christos #
     65  1.1  christos # _scope_ should be one of: case, compound, file, for, func, subshell,
     66  1.1  christos # until, while.
     67  1.1  christos # _cmd_ is the command line to execute.  Remember proper quoting!
     68  1.1  christos # _msg_ is text that will be used inside single quotes.
     69  1.1  christos # _var_suffix_ is a syntactically valid identifier name.
     70  1.1  christos 
     71  1.1  christos # don't rely on command lists (';')
     72  1.1  christos cmd="echo 'before ${3}'
     73  1.1  christos ${2}
     74  1.3       kre echo 'after ${3}, return value:' \${?}"
     75  1.1  christos 
     76  1.2  christos echo "#!${TEST_SH}"
     77  1.1  christos 
     78  1.1  christos [ 'func' = "${1}" ] && cat <<EOF
     79  1.1  christos func()
     80  1.1  christos {
     81  1.1  christos     echo 'before ${3}'
     82  1.1  christos     \${1}
     83  1.1  christos     echo 'after ${3}'
     84  1.1  christos }
     85  1.1  christos 
     86  1.1  christos echo 'before function'
     87  1.1  christos func "${2}" "${3}"  # don't rely on 'shift'
     88  1.1  christos echo 'after function'
     89  1.1  christos EOF
     90  1.1  christos 
     91  1.1  christos [ 'case' = "${1}" ] && cat <<EOF
     92  1.1  christos echo 'before case'
     93  1.1  christos case 'a' in
     94  1.1  christos     a)  ${cmd};;
     95  1.1  christos esac
     96  1.1  christos echo 'after case'
     97  1.1  christos EOF
     98  1.1  christos 
     99  1.1  christos [ 'file' = "${1}" ] && cat <<EOF
    100  1.1  christos ${cmd}
    101  1.1  christos EOF
    102  1.1  christos 
    103  1.1  christos [ 'while' = "${1}" ] && cat <<EOF
    104  1.1  christos echo 'before while'
    105  1.1  christos cond_${4}='true true false'
    106  1.1  christos while \${cond_${4}}
    107  1.1  christos do
    108  1.1  christos     cond_${4}="\${cond_${4}#* }"
    109  1.1  christos     ${cmd}
    110  1.1  christos done
    111  1.1  christos echo 'after while'
    112  1.1  christos EOF
    113  1.1  christos 
    114  1.1  christos [ 'until' = "${1}" ] && cat <<EOF
    115  1.1  christos echo 'before until'
    116  1.1  christos cond_${4}='false false true'
    117  1.1  christos until \${cond_${4}}
    118  1.1  christos do
    119  1.1  christos     cond_${4}="\${cond_${4}#* }"
    120  1.1  christos     ${cmd}
    121  1.1  christos done
    122  1.1  christos echo 'after until'
    123  1.1  christos EOF
    124  1.1  christos 
    125  1.1  christos [ 'for' = "${1}" ] && cat <<EOF
    126  1.1  christos echo 'before for'
    127  1.1  christos for i_${4} in 1 2
    128  1.1  christos do
    129  1.1  christos     ${cmd}
    130  1.1  christos done
    131  1.1  christos echo 'after for'
    132  1.1  christos EOF
    133  1.1  christos 
    134  1.1  christos [ 'subshell' = "${1}" ] && cat <<EOF
    135  1.1  christos (
    136  1.1  christos     echo 'subshell start'
    137  1.1  christos     ${cmd}
    138  1.1  christos     echo 'subshell end'
    139  1.1  christos )
    140  1.1  christos EOF
    141  1.1  christos 
    142  1.1  christos [ 'compound' = "${1}" ] && cat <<EOF
    143  1.1  christos {
    144  1.1  christos     echo 'compound start'
    145  1.1  christos     ${cmd};
    146  1.1  christos     echo 'compound end'
    147  1.1  christos }
    148  1.1  christos EOF
    149  1.1  christos 
    150  1.1  christos exit 0
    151