aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-03-29 07:02:37 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-03-29 07:02:37 -0700
commit4955c31e0b97fa5d0ac866df2db08bb390845a30 (patch)
treec1677eb5a2ecc541dedbac516f8910097140ff9f
parentc2287bfb8bdf1648ec2683b1a8e96547fcb43513 (diff)
downloadcppawk-4955c31e0b97fa5d0ac866df2db08bb390845a30.tar.gz
cppawk-4955c31e0b97fa5d0ac866df2db08bb390845a30.tar.bz2
cppawk-4955c31e0b97fa5d0ac866df2db08bb390845a30.zip
case: add mixed clause.
-rw-r--r--cppawk-case.119
-rw-r--r--cppawk-include/case-priv.h9
-rw-r--r--cppawk-include/case.h1
-rw-r--r--testcases-case26
4 files changed, 52 insertions, 3 deletions
diff --git a/cppawk-case.1 b/cppawk-case.1
index c542dc7..f048ff6 100644
--- a/cppawk-case.1
+++ b/cppawk-case.1
@@ -19,6 +19,8 @@ case \- macro for portable switch statement
print "regex case"
cbreak
+ mixed (("def", "ghi"), (/regex4/, /regex5/))
+
otherwise
print "default case"
}
@@ -40,9 +42,10 @@ cases, requiring an explicit break.
The clauses of
.BI case
are labeled with the identifiers
-.BI of
-and
+.BI of,
.BI matching,
+or
+.BI mixed
which take arguments, and are followed by one or more statements. The last one
of those statements must always be a
.BI cbreak,
@@ -55,7 +58,9 @@ Regular expression keys must use the
.BI matching
label; ordinary keys compared for equality must use the
.BI of
-label.
+label. The
+.BI mixed
+label allows for both keys to be included in one case.
The
.BI of
@@ -69,6 +74,14 @@ construct:
of (3, 4) print "3 or 4"; cbreak // correct
+The
+.BI mixed
+macro takes exactly two arguments, which are parenthesized lists of
+keys. The left list must be a list of ordinary value keys, and the
+second of regular expression literals:
+
+ mixed ((1, 2, "a"), (/xyz$/, /^\et/))
+
Each clause must specify how it terminates: whether it breaks out of the
.BI case
statement, "falls through" to the next case, or returns from the surrounding
diff --git a/cppawk-include/case-priv.h b/cppawk-include/case-priv.h
index 2d99533..6421877 100644
--- a/cppawk-include/case-priv.h
+++ b/cppawk-include/case-priv.h
@@ -41,10 +41,15 @@
#define __ca_first(x) case x:
#define __ca_next(p, x) p case x:
+#define __mx_first(x) __of(x)
+#define __mx_next(p, x) p case x:
+
#define __case_temps __ign
#define __case(expr) switch (expr)
#define __of(...) __varexpand(__ca_first, __ca_next, __VA_ARGS__) {{{
#define __matching(...) __varexpand(__ca_first, __ca_next, __VA_ARGS__) {{{
+#define __mixed(x, y) __varexpand(__ca_first, __ca_next, __splice(x)) \
+ __varexpand(__ca_first, __ca_next, __splice(y)) {{{
#define __cbreak break; }}}
#define __cfall }}}
#define __cret(val) return val; }}}
@@ -67,6 +72,10 @@
__VA_ARGS__)) {{{
#define __matching(...) __clause(__varexpand(__mtch_first, mtch_next, \
__VA_ARGS__)) {{{
+#define __mixed(x, y) __clause(__varexpand(__of_first, __of_next, \
+ __splice(x)) || \
+ __varexpand(__mtch_first, __mtch_next, \
+ __splice(y))) {{{
#define __cbreak break; }}}
#define __creturn(val) return val; }}}
#define __cfall }}}
diff --git a/cppawk-include/case.h b/cppawk-include/case.h
index 79a04b8..42eb7ae 100644
--- a/cppawk-include/case.h
+++ b/cppawk-include/case.h
@@ -36,6 +36,7 @@
#define case(expr) __case(expr)
#define of(...) __of(__VA_ARGS__)
#define matching(...) __matching(__VA_ARGS__)
+#define mixed(...) __mixed(__VA_ARGS__)
#define cbreak __cbreak
#define cfall __cfall
#define cret(val) __cret(val)
diff --git a/testcases-case b/testcases-case
index 6e62412..4b9fc5e 100644
--- a/testcases-case
+++ b/testcases-case
@@ -52,3 +52,29 @@ function f(arg, case_temps)
BEGIN { print f(1), f(2), f(3), f(4) }'
:
10 20 30 -4
+--
+4:
+$cppawk '
+#include <case.h>
+function f(arg, case_temps, retval)
+{
+ retval = 0
+
+ case (arg) {
+ of ("alt")
+ ++retval
+ cfall
+ mixed (("foo", "bar"), (/^abc/, /xyz$/))
+ ++retval
+ cbreak
+ otherwise
+ --retval
+ cbreak
+ }
+
+ return retval
+}
+
+BEGIN { print f("alt"), f("foo"), f("bar"), f("abcde"), f("wxyz"), f("1abc2") }'
+:
+2 1 1 1 1 -1