aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-07-17 18:55:55 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-07-17 18:55:55 -0700
commit5293e86e5185b959a442633c93445ecfde107d1e (patch)
tree4a4dfd4b07a85d5243baf5336768a0b53a5ff15c
parentdcdb116a4ec5106483aeef7f0b4454e7f03b790d (diff)
downloadcppawk-5293e86e5185b959a442633c93445ecfde107d1e.tar.gz
cppawk-5293e86e5185b959a442633c93445ecfde107d1e.tar.bz2
cppawk-5293e86e5185b959a442633c93445ecfde107d1e.zip
Implement -E option and <safearg.h> header.
The -E option is not passed through to the Awk implementation any more, which is not particularly useful, because the option resembles -f, and its argument requires likewise handling. We achieve the semantics that -E <name> is equivalent to -f <name> --. From the GNU Awk user's perspective, this is a regression in the semantics of -E which also has the effect of suppressing the processing of arguments which look like variable assignments. To make up for that, we provide the <safearg.h> header which suppresses all implicit treatment of the remaining arguments.
-rwxr-xr-xbin/cppawk11
-rw-r--r--cppawk.165
-rw-r--r--share/cppawk/include/safearg.h48
-rw-r--r--testcases33
-rw-r--r--testdir/arg.cwk8
-rw-r--r--testdir/safearg.cwk14
6 files changed, 175 insertions, 4 deletions
diff --git a/bin/cppawk b/bin/cppawk
index bb58c78..c35b4fd 100755
--- a/bin/cppawk
+++ b/bin/cppawk
@@ -150,10 +150,15 @@ while [ $# -gt 0 ] ; do
-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"
+ -f | -E )
+ [ $# -gt 1 ] || die "%s requires argument" $1
+ [ -z "$awk_file" ] || die "%s can be only given once" $1
awk_file=$2
+ if [ $1 = -E ] ; then
+ shift
+ shift
+ break
+ fi
shift
;;
-F | -v | -E | -i | -l | -L )
diff --git a/cppawk.1 b/cppawk.1
index 3416fc4..33627e6 100644
--- a/cppawk.1
+++ b/cppawk.1
@@ -110,6 +110,69 @@ is then invoked on this file. The file is deleted when
.I awk
terminates.
+.IP "\fB\-E\fR \fIfilename\fR"
+The
+.B -E
+option is inspired by that of GNU Awk;
+.B cppawk
+implements a form of this option itself, for all Awk back-ends,
+and does not pass it through to GNU Awk.
+This option combines the semantics of the
+.B -f
+and
+.B --
+options. Arrangements are made for the awk program to be read from
+a file exactly as described above for the
+.B -f
+option. Then, no more options are processed. Any remaining option-like
+arguments are ordinary arguments.
+
+Note that unlike GNU Awk's
+.B -E
+options,
+.BR cppawk 's
+.B -E
+option doesn't suppress the processing of arguments which look like
+variable assignments.
+
+Instead, the program may specify the following preprocessing directive, outside
+of any Awk block or function:
+
+.ft B
+ #include <safearg.h>
+.ft R
+
+this directive produces a
+.B BEGIN
+clause which prepares an associate array named
+.B argv
+that contains the same key/value pairs as the standard
+.BR ARGV .
+The
+.B ARGV
+array is then deleted. Consequently, Awk will not process
+and perform the command line variable assignments, which normally
+occurs after the
+.B BEGIN
+clauses are processed.
+The effects of
+.B "<safearg.h>" are not visible to
+.B BEGIN
+clauses which are placed earlier than the inclusion of
+.BR "<safearg.h>" .
+Those earlier clauses have access to the original
+.B ARGV
+array.
+
+However, the combination of
+.B -E
+option and
+.B "<safearg.h>"
+is still not equivalent to GNU Awk's
+.B -E
+option, because no filename arguments are available for implicit
+use in the Awk pattern processing loop.
+
.IP "\fB--nobash\fR"
Pretend that the shell which executes
.I cppawk
@@ -148,7 +211,7 @@ message and failed termination. The intent is that the
family of options that are supported by GNU cpp are not supported by
.IR cppawk .
-.IP "\fB-F\fR, \fB-v\fR, \fB-E\fR, \fB-i\fR, \fB-l\fR, \fB-L\fR"
+.IP "\fB-F\fR, \fB-v\fR, \fB-i\fR, \fB-l\fR, \fB-L\fR"
These standard and GNU Awk options are recognized by
.I cppawk
as requiring an argument. They are validated for the presence of the
diff --git a/share/cppawk/include/safearg.h b/share/cppawk/include/safearg.h
new file mode 100644
index 0000000..5016155
--- /dev/null
+++ b/share/cppawk/include/safearg.h
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef __CPPAWK_SAFEARG_H
+#define __CPPAWK_SAFEARG_H
+
+#ifndef __CPPAWK_BASE_H
+#include "base.h"
+#endif
+
+BEGIN {
+ for (__key in ARGV) {
+ argv[__key] = ARGV[__key]
+#if !__gawk__
+ delete ARGV[__key]
+#endif
+ }
+
+#if __gawk__
+ delete ARGV
+#endif
+}
+
+#endif
diff --git a/testcases b/testcases
index d95e25f..1af3714 100644
--- a/testcases
+++ b/testcases
@@ -251,3 +251,36 @@ $cppawk --dump-macros '#define foo_bar 42' | grep foo_bar
$cppawk --dump-macros x | (grep -q '#define [A-Za-z]' || echo "clean")
:
clean
+--
+44:
+$cppawk -f x -E x
+:
+ERR
+--
+45:
+$cppawk -E testdir/program.cwk
+:
+73
+--
+46:
+$cppawk -E testdir/program.cwk -f testdir/program.cwk
+:
+73
+--
+47:
+$cppawk -E testdir/arg.cwk a=3 b=4 testdir/data
+:
+ARGV[1]=a=3
+ARGV[2]=b=4
+ARGV[3]=testdir/data
+a=3
+b=4
+--
+48:
+echo | $cppawk -E testdir/safearg.cwk a=3 b=4 testdir/data
+:
+argv[1]=a=3
+argv[2]=b=4
+argv[3]=testdir/data
+a=
+b=
diff --git a/testdir/arg.cwk b/testdir/arg.cwk
new file mode 100644
index 0000000..a5c98a9
--- /dev/null
+++ b/testdir/arg.cwk
@@ -0,0 +1,8 @@
+END {
+ for (x in ARGV) {
+ if (x != 0)
+ printf("ARGV[%s]=%s\n", x, ARGV[x])
+ }
+ printf("a=%s\n", a)
+ printf("b=%s\n", b)
+}
diff --git a/testdir/safearg.cwk b/testdir/safearg.cwk
new file mode 100644
index 0000000..4f29b9f
--- /dev/null
+++ b/testdir/safearg.cwk
@@ -0,0 +1,14 @@
+#include <safearg.h>
+
+END {
+ for (x in ARGV) {
+ if (x != 0)
+ printf("ARGV[%s]=%s\n", x, ARGV[x])
+ }
+ for (x in argv) {
+ if (x != 0)
+ printf("argv[%s]=%s\n", x, argv[x])
+ }
+ printf("a=%s\n", a)
+ printf("b=%s\n", a)
+}