scoped_command revision 1.1
11.1Schristos#!/bin/sh
21.1Schristos#
31.1Schristos# $NetBSD: scoped_command,v 1.1 2014/05/31 14:29:06 christos 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.1Schristosset -e
341.1Schristos
351.1Schristos# USAGE:
361.1Schristos#   scoped_command scope cmd msg var_suffix
371.1Schristos#
381.1Schristos# Write to stdout a piece of Bourne Shell script with _cmd_ in specific
391.1Schristos# _scope_.  The execution of _cmd_ is bracketed by prints of "before _msg_"
401.1Schristos# and "after _msg_, return value ${?}".  If the generated script uses
411.1Schristos# variables, __var_suffix_ is appended to their names to allow nesting of
421.1Schristos# scripts generated this way.
431.1Schristos#
441.1Schristos# _scope_ should be one of: case, compound, file, for, func, subshell,
451.1Schristos# until, while.
461.1Schristos# _cmd_ is the command line to execute.  Remember proper quoting!
471.1Schristos# _msg_ is text that will be used inside single quotes.
481.1Schristos# _var_suffix_ is a syntactically valid identifier name.
491.1Schristos
501.1Schristos# don't rely on command lists (';')
511.1Schristoscmd="echo 'before ${3}'
521.1Schristos${2}
531.1Schristosecho 'after ${3}, return value:' ${?}"
541.1Schristos
551.1Schristosecho "#!/bin/sh"
561.1Schristos
571.1Schristos[ 'func' = "${1}" ] && cat <<EOF
581.1Schristosfunc()
591.1Schristos{
601.1Schristos    echo 'before ${3}'
611.1Schristos    \${1}
621.1Schristos    echo 'after ${3}'
631.1Schristos}
641.1Schristos
651.1Schristosecho 'before function'
661.1Schristosfunc "${2}" "${3}"  # don't rely on 'shift'
671.1Schristosecho 'after function'
681.1SchristosEOF
691.1Schristos
701.1Schristos[ 'case' = "${1}" ] && cat <<EOF
711.1Schristosecho 'before case'
721.1Schristoscase 'a' in
731.1Schristos    a)  ${cmd};;
741.1Schristosesac
751.1Schristosecho 'after case'
761.1SchristosEOF
771.1Schristos
781.1Schristos[ 'file' = "${1}" ] && cat <<EOF
791.1Schristos${cmd}
801.1SchristosEOF
811.1Schristos
821.1Schristos[ 'while' = "${1}" ] && cat <<EOF
831.1Schristosecho 'before while'
841.1Schristoscond_${4}='true true false'
851.1Schristoswhile \${cond_${4}}
861.1Schristosdo
871.1Schristos    cond_${4}="\${cond_${4}#* }"
881.1Schristos    ${cmd}
891.1Schristosdone
901.1Schristosecho 'after while'
911.1SchristosEOF
921.1Schristos
931.1Schristos[ 'until' = "${1}" ] && cat <<EOF
941.1Schristosecho 'before until'
951.1Schristoscond_${4}='false false true'
961.1Schristosuntil \${cond_${4}}
971.1Schristosdo
981.1Schristos    cond_${4}="\${cond_${4}#* }"
991.1Schristos    ${cmd}
1001.1Schristosdone
1011.1Schristosecho 'after until'
1021.1SchristosEOF
1031.1Schristos
1041.1Schristos[ 'for' = "${1}" ] && cat <<EOF
1051.1Schristosecho 'before for'
1061.1Schristosfor i_${4} in 1 2
1071.1Schristosdo
1081.1Schristos    ${cmd}
1091.1Schristosdone
1101.1Schristosecho 'after for'
1111.1SchristosEOF
1121.1Schristos
1131.1Schristos[ 'subshell' = "${1}" ] && cat <<EOF
1141.1Schristos(
1151.1Schristos    echo 'subshell start'
1161.1Schristos    ${cmd}
1171.1Schristos    echo 'subshell end'
1181.1Schristos)
1191.1SchristosEOF
1201.1Schristos
1211.1Schristos[ 'compound' = "${1}" ] && cat <<EOF
1221.1Schristos{
1231.1Schristos    echo 'compound start'
1241.1Schristos    ${cmd};
1251.1Schristos    echo 'compound end'
1261.1Schristos}
1271.1SchristosEOF
1281.1Schristos
1291.1Schristosexit 0
130