ref: 66abd6e50a59b288eac0868a2bb352f84351927f
parent: 60ea3e6d25c6ec6e1ed659b2e9ba49b91c911424
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Dec 21 19:48:14 EST 2024
cpp: implement empty arg handling for function-like macros (thanks rod)
--- a/sys/src/cmd/cpp/macro.c
+++ b/sys/src/cmd/cpp/macro.c
@@ -185,7 +185,7 @@
void
expand(Tokenrow *trp, Nlist *np)
{
- int ntokc, narg, i, hs;
+ int ntokc, narg, nparam, i, hs;
Tokenrow *atr[NARG+1];
Tokenrow ntr;
Token *tp;
@@ -202,7 +202,18 @@
/* gatherargs has already pushed trp->tr to the next token */
return;
}
- if (narg != rowlen(np->ap)) {
+ nparam = rowlen(np->ap);
+
+ if(narg == nparam - 1
+ && (narg == 0 || (np->flag&ISVARMAC))) {
+ if(narg == NARG)
+ error(ERROR, "Too many arguments");
+ atr[narg] = new(Tokenrow);
+ maketokenrow(0, atr[narg]);
+ narg++;
+ }
+
+ if (narg != nparam) {
error(ERROR, "Disagreement in number of macro arguments");
trp->tp->hideset = newhideset(trp->tp->hideset, np);
trp->tp += ntokc;
--- a/sys/src/cmd/cpp/test/edges.expected
+++ b/sys/src/cmd/cpp/test/edges.expected
@@ -1,7 +1,10 @@
+#line 1 "/sys/src/cmd/cpp/test/edges.out"
#line 1 "/sys/src/cmd/cpp/test/edges.in"
+
+-- test nop --
x fooEOF y
x EOFfoo y
x(-1) y
@@ -9,26 +12,34 @@
x foo y
X y
+-- test ncat --
foobar
+-- test xcat (no left arg) --
foo ## bar
+-- test cat3 --
ablahb
+-- test expand and cat --
33
+-- test expand and cat 2 --
a bc d
WUT
+-- test varargs --
-#line 36 "/sys/src/cmd/cpp/test/edges.in"
+ print("hi","there")
+ print("hi",)
+-- test expanding commas --
@@ -48,8 +59,15 @@
+-- test complex expressions --
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2 +(3,4)- 0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^ m(0,1);
-#line 59 "/sys/src/cmd/cpp/test/edges.in"
+#line 64 "/sys/src/cmd/cpp/test/edges.in"
-#line 66 "/sys/src/cmd/cpp/test/edges.in"
+-- test empty args --
+
+ b
+
+-- test complex expressions with empty args --
+ int i[] = {1,23,4,5, };
+char c[2][6] = {"hello","" };
--- a/sys/src/cmd/cpp/test/edges.in
+++ b/sys/src/cmd/cpp/test/edges.in
@@ -1,6 +1,8 @@
#define NOP(x) x
#define CAT(a, b) a ## b
#define EOF (-1)
+
+-- test nop --
x NOP(CAT(foo, EOF)) y
x NOP(CAT(EOF, foo)) y
x CAT(, EOF) y
@@ -8,32 +10,34 @@
x CAT(,foo) y
X NOP(CAT(,)) y
+-- test ncat --
#define NCAT(a) foo ## a
NCAT(bar)
+-- test xcat (no left arg) --
#define XCAT(a) ## a
foo XCAT(bar)
+-- test cat3 --
#define CAT3(foo) a##foo##b
CAT3(blah)
+-- test expand and cat --
#define BAR 3
#define FOO CAT(BAR, 3)
FOO
+-- test expand and cat 2 --
/* Expected: a bc d */
CAT(a b, c d)
WUT
-/*
- * CURRENTLY BROKEN:
- * __VA_ARGS__ requires at least one item.
- * It should accept an empty list.
+-- test varargs --
#define xprint(a, ...) print(a, __VA_ARGS__)
xprint("hi", "there")
xprint("hi")
-*/
+-- test expanding commas --
#define C a,b
#define X(a) a
#define Y X(C)
@@ -53,13 +57,15 @@
#define q(x) x
#define r(x,y) x ## y
#define str(x) # x
+-- test complex expressions --
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
(f)^m(m);
-/*
- * CURRENTLY BROKEN:
- * mac() needs at least one argument.
- * It should treat no args as a single empty arg list.
+
+-- test empty args --
+#define ZARGS(a) a b a
+ZARGS()
+
+-- test complex expressions with empty args --
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };
-*/
--
⑨