aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-07-02 16:59:45 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-07-02 16:59:45 -0700
commitda98d5314731206cd03038d589d10c5c32a0ce8c (patch)
tree4b7dd002a5edda8f2e6561c29bf6aee80a3e9303 /bin
parent94ed05fe4df6a657884596bdabd03c7666a63de7 (diff)
downloadcppawk-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-xbin/cppawk224
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