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