shithub: front

Download patch

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() };
-*/
--