diff --git a/sys/src/cmd/cpp/macro.c b/sys/src/cmd/cpp/macro.c index 4757f66aa..0d7640341 100644 --- a/sys/src/cmd/cpp/macro.c +++ b/sys/src/cmd/cpp/macro.c @@ -185,7 +185,7 @@ expandrow(Tokenrow *trp, char *flag) 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 @@ expand(Tokenrow *trp, Nlist *np) /* 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; diff --git a/sys/src/cmd/cpp/test/edges.expected b/sys/src/cmd/cpp/test/edges.expected index f168a8f00..96b34020d 100644 --- 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 @@ y foo x 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 @@ WUT +-- 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","" }; diff --git a/sys/src/cmd/cpp/test/edges.in b/sys/src/cmd/cpp/test/edges.in index 02623fa4b..b6f5c8d97 100644 --- 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 @@ y CAT(foo,) x 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 @@ Y #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() }; -*/