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