11.1Schristos#!/bin/sh
21.1Schristos#
31.3Skre# $NetBSD: scoped_command,v 1.3 2018/12/04 09:47:25 kre Exp $
41.1Schristos#
51.1Schristos# Copyright (c) 2014 The NetBSD Foundation, Inc.
61.1Schristos# All rights reserved.
71.1Schristos#
81.1Schristos# This code is derived from software contributed to The NetBSD Foundation
91.1Schristos# by Jarmo Jaakkola.
101.1Schristos#
111.1Schristos# Redistribution and use in source and binary forms, with or without
121.1Schristos# modification, are permitted provided that the following conditions
131.1Schristos# are met:
141.1Schristos# 1. Redistributions of source code must retain the above copyright
151.1Schristos#    notice, this list of conditions and the following disclaimer.
161.1Schristos# 2. Redistributions in binary form must reproduce the above copyright
171.1Schristos#    notice, this list of conditions and the following disclaimer in the
181.1Schristos#    documentation and/or other materials provided with the distribution.
191.1Schristos#
201.1Schristos# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
211.1Schristos# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
221.1Schristos# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
231.1Schristos# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
241.1Schristos# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
251.1Schristos# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
261.1Schristos# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
271.1Schristos# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
281.1Schristos# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
291.1Schristos# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
301.1Schristos# POSSIBILITY OF SUCH DAMAGE.
311.1Schristos#
321.1Schristos
331.2Schristos: ${TEST_SH:=/bin/sh}
341.2Schristos
351.2Schristossane_sh()
361.2Schristos{
371.2Schristos	set -- ${TEST_SH}
381.2Schristos	case "$#" in
391.2Schristos	(0)   set /bin/sh;;
401.2Schristos	(1|2) ;;
411.2Schristos	(*)   set "$1";;   # Just ignore options if we cannot make them work
421.2Schristos	esac
431.2Schristos
441.2Schristos	case "$1" in
451.2Schristos	/*)	TEST_SH="$1${2+ }$2";;
461.2Schristos	./*)	TEST_SH="${PWD}${1#.}${2+ }$2";;
471.2Schristos	*/*)	TEST_SH="${PWD}/$1${2+ }$2";;
481.2Schristos	*)	TEST_SH="$( command -v "$1" )${2+ }$2";;
491.2Schristos	esac
501.2Schristos}
511.2Schristos
521.2Schristossane_sh
531.2Schristos
541.1Schristosset -e
551.1Schristos
561.1Schristos# USAGE:
571.1Schristos#   scoped_command scope cmd msg var_suffix
581.1Schristos#
591.1Schristos# Write to stdout a piece of Bourne Shell script with _cmd_ in specific
601.1Schristos# _scope_.  The execution of _cmd_ is bracketed by prints of "before _msg_"
611.1Schristos# and "after _msg_, return value ${?}".  If the generated script uses
621.1Schristos# variables, __var_suffix_ is appended to their names to allow nesting of
631.1Schristos# scripts generated this way.
641.1Schristos#
651.1Schristos# _scope_ should be one of: case, compound, file, for, func, subshell,
661.1Schristos# until, while.
671.1Schristos# _cmd_ is the command line to execute.  Remember proper quoting!
681.1Schristos# _msg_ is text that will be used inside single quotes.
691.1Schristos# _var_suffix_ is a syntactically valid identifier name.
701.1Schristos
711.1Schristos# don't rely on command lists (';')
721.1Schristoscmd="echo 'before ${3}'
731.1Schristos${2}
741.3Skreecho 'after ${3}, return value:' \${?}"
751.1Schristos
761.2Schristosecho "#!${TEST_SH}"
771.1Schristos
781.1Schristos[ 'func' = "${1}" ] && cat <<EOF
791.1Schristosfunc()
801.1Schristos{
811.1Schristos    echo 'before ${3}'
821.1Schristos    \${1}
831.1Schristos    echo 'after ${3}'
841.1Schristos}
851.1Schristos
861.1Schristosecho 'before function'
871.1Schristosfunc "${2}" "${3}"  # don't rely on 'shift'
881.1Schristosecho 'after function'
891.1SchristosEOF
901.1Schristos
911.1Schristos[ 'case' = "${1}" ] && cat <<EOF
921.1Schristosecho 'before case'
931.1Schristoscase 'a' in
941.1Schristos    a)  ${cmd};;
951.1Schristosesac
961.1Schristosecho 'after case'
971.1SchristosEOF
981.1Schristos
991.1Schristos[ 'file' = "${1}" ] && cat <<EOF
1001.1Schristos${cmd}
1011.1SchristosEOF
1021.1Schristos
1031.1Schristos[ 'while' = "${1}" ] && cat <<EOF
1041.1Schristosecho 'before while'
1051.1Schristoscond_${4}='true true false'
1061.1Schristoswhile \${cond_${4}}
1071.1Schristosdo
1081.1Schristos    cond_${4}="\${cond_${4}#* }"
1091.1Schristos    ${cmd}
1101.1Schristosdone
1111.1Schristosecho 'after while'
1121.1SchristosEOF
1131.1Schristos
1141.1Schristos[ 'until' = "${1}" ] && cat <<EOF
1151.1Schristosecho 'before until'
1161.1Schristoscond_${4}='false false true'
1171.1Schristosuntil \${cond_${4}}
1181.1Schristosdo
1191.1Schristos    cond_${4}="\${cond_${4}#* }"
1201.1Schristos    ${cmd}
1211.1Schristosdone
1221.1Schristosecho 'after until'
1231.1SchristosEOF
1241.1Schristos
1251.1Schristos[ 'for' = "${1}" ] && cat <<EOF
1261.1Schristosecho 'before for'
1271.1Schristosfor i_${4} in 1 2
1281.1Schristosdo
1291.1Schristos    ${cmd}
1301.1Schristosdone
1311.1Schristosecho 'after for'
1321.1SchristosEOF
1331.1Schristos
1341.1Schristos[ 'subshell' = "${1}" ] && cat <<EOF
1351.1Schristos(
1361.1Schristos    echo 'subshell start'
1371.1Schristos    ${cmd}
1381.1Schristos    echo 'subshell end'
1391.1Schristos)
1401.1SchristosEOF
1411.1Schristos
1421.1Schristos[ 'compound' = "${1}" ] && cat <<EOF
1431.1Schristos{
1441.1Schristos    echo 'compound start'
1451.1Schristos    ${cmd};
1461.1Schristos    echo 'compound end'
1471.1Schristos}
1481.1SchristosEOF
1491.1Schristos
1501.1Schristosexit 0
151