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