1#!/bin/sh 2# 3# $NetBSD: scoped_command,v 1.2 2016/03/27 14:57:50 christos 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 35sane_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 52sane_sh 53 54set -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 (';') 72cmd="echo 'before ${3}' 73${2} 74echo 'after ${3}, return value:' ${?}" 75 76echo "#!${TEST_SH}" 77 78[ 'func' = "${1}" ] && cat <<EOF 79func() 80{ 81 echo 'before ${3}' 82 \${1} 83 echo 'after ${3}' 84} 85 86echo 'before function' 87func "${2}" "${3}" # don't rely on 'shift' 88echo 'after function' 89EOF 90 91[ 'case' = "${1}" ] && cat <<EOF 92echo 'before case' 93case 'a' in 94 a) ${cmd};; 95esac 96echo 'after case' 97EOF 98 99[ 'file' = "${1}" ] && cat <<EOF 100${cmd} 101EOF 102 103[ 'while' = "${1}" ] && cat <<EOF 104echo 'before while' 105cond_${4}='true true false' 106while \${cond_${4}} 107do 108 cond_${4}="\${cond_${4}#* }" 109 ${cmd} 110done 111echo 'after while' 112EOF 113 114[ 'until' = "${1}" ] && cat <<EOF 115echo 'before until' 116cond_${4}='false false true' 117until \${cond_${4}} 118do 119 cond_${4}="\${cond_${4}#* }" 120 ${cmd} 121done 122echo 'after until' 123EOF 124 125[ 'for' = "${1}" ] && cat <<EOF 126echo 'before for' 127for i_${4} in 1 2 128do 129 ${cmd} 130done 131echo 'after for' 132EOF 133 134[ 'subshell' = "${1}" ] && cat <<EOF 135( 136 echo 'subshell start' 137 ${cmd} 138 echo 'subshell end' 139) 140EOF 141 142[ 'compound' = "${1}" ] && cat <<EOF 143{ 144 echo 'compound start' 145 ${cmd}; 146 echo 'compound end' 147} 148EOF 149 150exit 0 151