diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-07-02 16:59:45 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-07-02 16:59:45 -0700 |
commit | da98d5314731206cd03038d589d10c5c32a0ce8c (patch) | |
tree | 4b7dd002a5edda8f2e6561c29bf6aee80a3e9303 /bin | |
parent | 94ed05fe4df6a657884596bdabd03c7666a63de7 (diff) | |
download | cppawk-da98d5314731206cd03038d589d10c5c32a0ce8c.tar.gz cppawk-da98d5314731206cd03038d589d10c5c32a0ce8c.tar.bz2 cppawk-da98d5314731206cd03038d589d10c5c32a0ce8c.zip |
Restructure cppawk installation.
cppawk now expects to be installed in some directory (typically "bin"),
such that the include files are in a "share/cppawk/include" directory
where "share" is a sibling of "bin".
The git repository is restructured to match this shape; cppawk is
moved into "bin", and the include files into "share/cppawk/include".
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/cppawk | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/bin/cppawk b/bin/cppawk new file mode 100755 index 0000000..e5c95dc --- /dev/null +++ b/bin/cppawk @@ -0,0 +1,224 @@ +#!/bin/sh + +# cppawk: C preprocessor wrapper around awk +# Copyright 2022 Kaz Kylheku <kaz@kylheku.com> +# +# BSD-2 License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# site configuration +prepro=cpp +incopt=-iquote # GNU extension: must be changed to -I for traditional cpp +dumpopt=-dM # GNU cpp option to dump macros +stdopt=-std=c99 # GNU cpp option for standard conformance +awk=gawk +prepro_opts="-D__gawk__=1 -D__cppawk_ver=20220419 $stdopt" + +# globals +bash=${BASH_VERSION+y} +# if this isn't bash, and there is a /bin/bash, let's re-execute ourselves +# with Bash, so we can use process substitution instead of temp files. +if ! [ $bash ] && [ -x /bin/bash ] ; then + exec /bin/bash "$0" "$@" +fi +awk_file= +awk_opts= +tmp_file= +prepro_only= + +selfdir="$(dirname "$0")" + +# functions + +# convert argument into quoted shell syntax +quote() +{ + case $1 in + *"'"* ) + case $1 in + *[\"\$\\]* ) + printf "'%s'" "$(printf "%s" "$1" | sed -e "s/'/'\\\\''/g")" + ;; + * ) + printf '"%s"' "$1" + ;; + esac + ;; + * ) + printf "'%s'" "$1" + ;; + esac +} + +die() +{ + fmt="$0: $1\n" ; shift + printf "$fmt" "$@" + exit 1 +} + +delhashbang_setline() +{ + sed -e "1s/^#!.*/#/" -e "1i#line 1 \"$1\"" "$1" +} + +delhashbang() +{ + sed -e "1s/^#!.*/#/" +} + +# Eliminate tracer lines in cpp output which continue a previous line, and +# merge the continued lines into one. Awk needs this because spurious newlines +# break its syntax. +collapse() +{ + awk ' + $1 == "#" { if ($2 != curline || $3 != curfile) + { print + if (have_line) + { printf("%s\n", line); + line = "" + have_line = 0 } } + startline = $2 + curline = startline - 1 + curfile = $3; + next } + 1 { if (++curline > startline) + { if (have_line) + { printf("%s\n", line) + line = "" } } + else + { sub(/^[ \t]+/, "") } + line = line $0 + have_line = 1 } + END { if (have_line) + printf("%s\n", line); }' +} + +prepro_opts="$prepro_opts -I$selfdir/../share/cppawk/include" + +while [ $# -gt 0 ] ; do + case $1 in + -M?* ) + die "-M family of cpp options not supported" + ;; + --prepro-only ) + prepro_only=y + ;; + --prepro=* ) + prepro=${1#*=} + ;; + --awk=* ) + awk=${1#*=} + case $awk in + gawk | mawk | */gawk | */mawk ) + prepro_opts="$prepro_opts -U__gawk__ -D__$(basename "$awk")__=1" + ;; + egawk | */egawk ) + prepro_opts="$prepro_opts -D__egawk__=1" + ;; + esac + ;; + --nobash ) + bash= + ;; + --dump-macros ) + prepro_opts="$prepro_opts $dumpopt" + prepro_only=y + ;; + -U* | -D* | -I* | -iquote* ) + prepro_opts="$prepro_opts $(quote "$1")" + ;; + -f ) + [ $# -gt 1 ] || die "-f requires argument" + [ -z "$awk_file" ] || die "-f can be only given once" + awk_file=$2 + shift + ;; + -F | -v | -E | -i | -l | -L ) + [ $# -gt 1 ] || die "%s requires argument" $1 + awk_opts="$awk_opts $1 $(quote "$2")" + shift + ;; + -- ) + break + ;; + -M | --bignum ) + awk_opts="$awk_opts $1" + prepro_opts="$prepro_opts -D__bignum__=1" + ;; + -P | --posix ) + awk_opts="$awk_opts $1" + prepro_opts="$prepro_opts -D__posix__=1" + ;; + -* ) + awk_opts="$awk_opts $(quote "$1")" + ;; + * ) + break + ;; + esac + shift +done + +awk="command $(quote "$awk")" +prepro="command $(quote "$prepro")" + +if [ -n "$awk_file" ] ; then + awk_file_dir=$(dirname "$awk_file") + if [ $prepro_only ] ; then + delhashbang_setline "$awk_file" \ + | eval "$prepro $incopt\"$awk_file_dir\" $prepro_opts - | collapse" + elif [ $bash ] ; then + prep='delhashbang_setline "$awk_file" \ + | eval "$prepro $incopt\"$awk_file_dir\" $prepro_opts - | collapse"' + eval "$awk $awk_opts -f <($prep) -- \"\$@\"" + else + trap 'rm -f $tmp_file' EXIT INT TERM + tmp_file=$(mktemp) + delhashbang_setline "$awk_file" \ + | eval "$prepro $incopt\"$awk_file_dir\" $prepro_opts - | collapse" \ + > $tmp_file + eval "$awk $awk_opts -f $tmp_file -- \"\$@\"" + fi +elif [ $# -gt 0 ] ; then + if [ $prepro_only ] ; then + printf "%s" "$1" | delhashbang \ + | eval "$prepro $incopt"$(pwd)" $prepro_opts - | collapse" + elif [ $bash ] ; then + code=$1; shift + prep='printf "%s" "$code" | delhashbang \ + | eval "$prepro $incopt"$(pwd)" $prepro_opts - | collapse"' + eval "$awk $awk_opts -f <($prep) -- \"\$@\"" + else + trap 'rm -f $tmp_file' EXIT INT TERM + tmp_file=$(mktemp) + printf "%s" "$1" | delhashbang \ + | eval "$prepro $incopt"$(pwd)" $prepro_opts - | collapse" > $tmp_file + shift + eval "$awk $awk_opts -f $tmp_file -- \"\$@\"" + fi +else + die "awk code must be specified" +fi |