2
+ − 1
#! /bin/sh
+ − 2
+ − 3
#
+ − 4
# Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
+ − 5
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ − 6
#
+ − 7
# This code is free software; you can redistribute it and/or modify it
+ − 8
# under the terms of the GNU General Public License version 2 only, as
+ − 9
# published by the Free Software Foundation. Sun designates this
+ − 10
# particular file as subject to the "Classpath" exception as provided
+ − 11
# by Sun in the LICENSE file that accompanied this code.
+ − 12
#
+ − 13
# This code is distributed in the hope that it will be useful, but WITHOUT
+ − 14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 15
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 16
# version 2 for more details (a copy is included in the LICENSE file that
+ − 17
# accompanied this code).
+ − 18
#
+ − 19
# You should have received a copy of the GNU General Public License version
+ − 20
# 2 along with this work; if not, write to the Free Software Foundation,
+ − 21
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ − 22
#
+ − 23
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ − 24
# CA 95054 USA or visit www.sun.com if you need additional information or
+ − 25
# have any questions.
+ − 26
#
+ − 27
+ − 28
# SPP: A simple/sed-based/stream preprocessor
+ − 29
# Mark Reinhold / mr@sun.com
+ − 30
#
+ − 31
# Usage: spp [-be] [-Kkey] -Dvar=value ... <in >out
+ − 32
#
+ − 33
# Source-file constructs
+ − 34
#
+ − 35
# Meaningful only at beginning of line, works with any number of keys:
+ − 36
#
+ − 37
# #if[key] Includes text between #if/#end if -Kkey specified,
+ − 38
# #else[key] otherwise changes text to blank lines; key test
+ − 39
# #end[key] may be negated by prefixing !, e.g., #if[!key]
+ − 40
#
+ − 41
# #begin If -be is specified then lines up to and including
+ − 42
# #end #begin, and from #end to EOF, are deleted
+ − 43
#
+ − 44
# #warn Changed into warning that file is generated
+ − 45
#
+ − 46
# // ## Changed into blank line
+ − 47
#
+ − 48
# Meaningful anywhere in line, works only for first two keys:
+ − 49
#
+ − 50
# {#if[key]?yes} Expands to yes if -Kkey specified
+ − 51
# {#if[key]?yes:no} Expands to yes if -Kkey, otherwise no
+ − 52
# {#if[!key]?yes} Expands to yes if -Kother
+ − 53
# {#if[!key]?yes:no} Expands to yes if -Kother, otherwise no
+ − 54
# $var$ Expands to value if -Dvar=value given
+ − 55
#
+ − 56
# yes, no must not contain whitespace
+ − 57
#
+ − 58
# If the environment variable SED is defined, uses that instead of sed
+ − 59
# If the environment variable NAWK is defined, uses that instead of awk
+ − 60
#
+ − 61
+ − 62
SED=${SED:-sed}
+ − 63
NAWK=${NAWK:-awk}
+ − 64
+ − 65
# Map a string of the form -Dvar=value into an appropriate sed command
+ − 66
#
+ − 67
subst() {
+ − 68
# The first two lines are to avoid the direct use of echo,
+ − 69
# which does not treat backslashes consistently across platforms
+ − 70
echo '' \
+ − 71
| $SED -e "s.*$*" \
+ − 72
| $SED -e 's-D\([a-zA-Z_][-a-zA-Z_]*\)=\(.*\)'"s\\\\\$\\1\\\\\$\2gg" \
+ − 73
-e 's-D\([a-zA-Z_][-a-zA-Z_]*\)'"s\\\\\$\\1\\\\\$1gg" \
+ − 74
-e 's/ //g'
+ − 75
}
+ − 76
+ − 77
es=
+ − 78
be=
+ − 79
keys=
+ − 80
key1=_1_
+ − 81
key2=_2_
+ − 82
while [ $# -gt 0 ]; do
+ − 83
case "$1" in
+ − 84
-be)
+ − 85
be='-e 1,/^#begin$/d -e /^#end$/,$d'
+ − 86
;;
+ − 87
-D*)
+ − 88
es="$es -e `subst $1`"
+ − 89
;;
+ − 90
-K*)
+ − 91
nk=`echo $1 | $SED -e 's/-K//'`
+ − 92
if [ "x$keys" = x ]; then keys="$nk"; else keys="$keys $nk"; fi
+ − 93
if [ "x$key1" = x_1_ ]; then key1="$nk";
+ − 94
elif [ "x$key2" = x_2_ ]; then key2="$nk"; fi
+ − 95
;;
+ − 96
*)
+ − 97
echo "Usage: $0 [-be] [-Kkey] -Dvar=value ... <in >out"
+ − 98
exit 1
+ − 99
;;
+ − 100
esac
+ − 101
shift
+ − 102
done
+ − 103
+ − 104
text='[-a-zA-Z0-9&;,.<>/#() ]'
+ − 105
+ − 106
$SED $es \
+ − 107
-e 's// /g' \
+ − 108
-e "s@^#warn .*@// -- This file was mechanically generated: Do not edit! -- //@" \
+ − 109
-e 's-// ##.*$--' $be \
+ − 110
-e "s/{#if\[$key1\]?\($text*\):\($text*\)}/\1/g" \
+ − 111
-e "s/{#if\[!$key1\]?\($text*\):\($text*\)}/\2/g" \
+ − 112
-e "s/{#if\[$key1\]?\($text*\)}/\1/g" \
+ − 113
-e "s/{#if\[!$key1\]?\($text*\)}//g" \
+ − 114
-e "s/{#if\[$key2\]?\($text*\):\($text*\)}/\1/g" \
+ − 115
-e "s/{#if\[!$key2\]?\($text*\):\($text*\)}/\2/g" \
+ − 116
-e "s/{#if\[$key2\]?\($text*\)}/\1/g" \
+ − 117
-e "s/{#if\[!$key2\]?\($text*\)}//g" \
+ − 118
-e "s/{#if\[[a-z]*\]?\($text*\):\($text*\)}/\2/g" \
+ − 119
-e "s/{#if\[![a-z]*\]?\($text*\):\($text*\)}/\1/g" \
+ − 120
-e "s/{#if\[[a-z]*\]?\($text*\)}//g" \
+ − 121
-e "s/{#if\[![a-z]*\]?\($text*\)}/\1/g" \
+ − 122
| $NAWK \
+ − 123
'function key(s) {
+ − 124
i = match(s, "[a-zA-Z][a-zA-Z]*\\]");
+ − 125
if (i > 0) return substr(s, i, RLENGTH - 1);
+ − 126
return "XYZZY"; }
+ − 127
function neg(s) { return match(s, "!") > 0; }
+ − 128
BEGIN {
+ − 129
KEYS = "'"$keys"'"
+ − 130
n = split(KEYS, ks, " *");
+ − 131
for (i = 1; i <= n; i++) keys[ks[i]] = 1;
+ − 132
top = 1; copy[top] = 1 }
+ − 133
/^#if\[!?[a-zA-Z][a-zA-Z]*\]/ \
+ − 134
{ k = key($0);
+ − 135
n = neg($0);
+ − 136
stack[++top] = k;
+ − 137
if ((k in keys) == !n) {
+ − 138
copy[top] = copy[top - 1];
+ − 139
} else {
+ − 140
copy[top] = 0;
+ − 141
}
+ − 142
print ""; next }
+ − 143
/^#else\[!?[a-zA-Z][a-zA-Z]*\]/ \
+ − 144
{ k = key($0);
+ − 145
if (stack[top] == k) {
+ − 146
copy[top] = copy[top - 1] && !copy[top];
+ − 147
} else {
+ − 148
printf "%d: Mismatched #else key\n", NR | "cat 1>&2";
+ − 149
exit 11
+ − 150
}
+ − 151
print ""; next }
+ − 152
/^#end\[!?[a-zA-Z][a-zA-Z]*\]/ \
+ − 153
{ k = key($0);
+ − 154
if (stack[top] == k) {
+ − 155
top--;
+ − 156
} else {
+ − 157
printf "%d: Mismatched #end key\n", NR | "cat 1>&2"
+ − 158
exit 11
+ − 159
}
+ − 160
print ""; next }
+ − 161
/^#/ {
+ − 162
printf "%d: Malformed #directive\n", NR | "cat 1>&2"
+ − 163
exit 11
+ − 164
}
+ − 165
{ if (copy[top]) print; else print "" }'