gencpp 2.0 (was: [...] /usr/lib/cpp for generic text)
Maarten Litmaath
maart at cs.vu.nl
Tue Sep 26 14:39:13 AEST 1989
Let's try again. Still some limitations, but it seems to work well, albeit
a bit slow.
----------8<----------8<----------8<----------8<----------8<----------
#!/bin/sh
#
# @(#)gencpp 2.0 89/09/26 Maarten Litmaath
# generic cpp
# as substitution is done even inside quoted strings, you should choose
# identifiers which won't collide easily, e.g.
#
# #define MACHINE_ VAX
#
# instead of
#
# #define machine VAX
#
# don't use `/*' and `*/' to comment out blocks of text, use
#
# #if 0
# ...
# #endif /* 0 */
#
# only `<...>' and `"..."' include directives are supported
# furthermore cpp predefines certain symbols, e.g.
#
# #define unix 1
#
# which can be overruled using cpp's option `-U'
case $1 in
-level2)
# process included file
level=2
shift
;;
*)
level=1
dirs=
export dirs
argc=0
optc=0
export optc
tab=`echo I | tr I '\11'`
for i
do
case $i in
-I*)
# include directories
dirs="$dirs "`echo "x$i" | sed 's/...//'`
;;
-*)
optc=`expr $optc + 1`
eval optv$optc='"$i"'
eval export optv$optc
;;
*)
# files
argc=`expr $argc + 1`
eval argv$argc='"$i"'
esac
done
# double single and double quotes
q=\"
SED1="s/['$q]/&&/g"
# restore quotes and backslashes
SED2="
s/''/'/g
s/$q$q/$q/g
s/\\\\\\\\/\\\\/g
"
for i in define undef ifdef ifndef if elif else endif
do
# mark the relevant cpp control lines
# due to a bug in some sed versions, the `p' mustn't
# be appended to the previous substitute command
SED1="
$SED1
/^[ $tab]*#[ $tab]*\\($i\\).*/{
h
s//\\\\#\\1/
p
g
b
}
"
# remove a marked line and the (empty) next line
SED2="
$SED2
/^\\\\#$i$/{
N
d
}
"
done
# set the file arguments
set ' '
i=0
while
i=`expr $i + 1`
test $i -le $argc
do
eval set '${1+"$@"}' '"$argv'$i'"'
done
shift
esac
# canonicalize the `#include' line
# double backslashes
# protect leading whitespace against stripping by the shell (`read line')
SED3="
s/^[ $tab]*#[ $tab]*include/#include/
s/\\\\/&&/g
s/^[ $tab]/\\\\&/
"
# get include file name
SED4='
/[^<"]*.\([^>"]*\).*/{
s//\1/
s/\\\\/\\/g
p
}
'
sed "$SED3" ${1+"$@"} | (
while read line
do
case $line in
\#include*\<*)
# don't search dot default
dot=
;;
\#include*\"*)
dot=.
;;
*)
echo "$line"
continue
esac
name=`echo "$line" | sed -n "$SED4"`
file=
case $name in
/*)
file=$name
;;
*)
for dir in $dot $dirs
do
if test -f "$dir/$name"
then
file=$dir/$name
break
fi
done
esac
case $file in
'')
echo "$0: include file '$name' not found" >&2
continue
esac
# process included file
$0 -level2 "$file"
done
) | (
case $level in
2)
cat
;;
*)
# set cpp options
set ' '
i=0
while
i=`expr $i + 1`
test $i -le $optc
do
eval set '${1+"$@"}' '"$optv'$i'"'
done
shift
sed "$SED1" | /lib/cpp -P ${1+"$@"} | sed "$SED2"
esac
)
----------8<----------8<----------8<----------8<----------8<----------
--
`I AM NEW HEAR AMD I WANT TO INKRIMENT A |Maarten Litmaath @ VU Amsterdam:
VURIABLE BY 1 (OONE) IN "c"' (Tom Neff) |maart at cs.vu.nl, mcvax!botter!maart
More information about the Comp.unix.wizards
mailing list