ref: 0366f11300521165ff22423514a5d829a1f34912
parent: 77ddc8c654824962149160af822f849b78cc6cc0
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jul 13 14:50:14 EDT 2020
cpp: fix mutually recursive macros Handle cases where parameterless macros expand to each other: #define FOO BAR #define BAR FOO FOO There were cases where the macros didn't make it into the hidesets, and we would recurse infinitely. This fixes that.
--- a/sys/src/cmd/cpp/cpp.h
+++ b/sys/src/cmd/cpp/cpp.h
@@ -110,7 +110,7 @@
void expand(Tokenrow *, Nlist *);
void builtin(Tokenrow *, int);
int gatherargs(Tokenrow *, Tokenrow **, int, int *);
-void substargs(Nlist *, Tokenrow *, Tokenrow **);
+void substargs(Nlist *, Tokenrow *, Tokenrow **, int);
void expandrow(Tokenrow *, char *);
void maketokenrow(int, Tokenrow *);
Tokenrow *copytokenrow(Tokenrow *, Tokenrow *);
--- a/sys/src/cmd/cpp/macro.c
+++ b/sys/src/cmd/cpp/macro.c
@@ -169,9 +169,8 @@
}
if (np->flag&ISMAC)
builtin(trp, np->val);
- else {
+ else
expand(trp, np);
- }
tp = trp->tp;
}
if (flag)
@@ -186,11 +185,10 @@
void
expand(Tokenrow *trp, Nlist *np)
{
+ int ntokc, narg, i, hs;
+ Tokenrow *atr[NARG+1];
Tokenrow ntr;
- int ntokc, narg, i;
Token *tp;
- Tokenrow *atr[NARG+1];
- int hs;
copytokenrow(&ntr, np->vp); /* copy macro value */
if (np->ap==NULL) { /* parameterless */
@@ -197,7 +195,7 @@
ntokc = 1;
/* substargs for handling # and ## */
atr[0] = nil;
- substargs(np, &ntr, atr);
+ substargs(np, &ntr, atr, trp->tp->hideset);
} else {
ntokc = gatherargs(trp, atr, (np->flag&ISVARMAC) ? rowlen(np->ap) : 0, &narg);
if (narg<0) { /* not actually a call (no '(') */
@@ -210,12 +208,13 @@
trp->tp += ntokc;
return;
}
- substargs(np, &ntr, atr); /* put args into replacement */
+ substargs(np, &ntr, atr, trp->tp->hideset); /* put args into replacement */
for (i=0; i<narg; i++) {
dofree(atr[i]->bp);
dofree(atr[i]);
}
}
+
hs = newhideset(trp->tp->hideset, np);
for (tp=ntr.bp; tp<ntr.lp; tp++) { /* distribute hidesets */
if (tp->type==NAME) {
@@ -343,12 +342,13 @@
}
return 0;
}
+
/*
* substitute the argument list into the replacement string
* This would be simple except for ## and #
*/
void
-substargs(Nlist *np, Tokenrow *rtr, Tokenrow **atr)
+substargs(Nlist *np, Tokenrow *rtr, Tokenrow **atr, int hideset)
{
Tokenrow ttr, rp, rn;
Token *tp, *ap, *an, *pp, *pn;
@@ -355,7 +355,7 @@
int ntok, argno, hs;
for (rtr->tp=rtr->bp; rtr->tp<rtr->lp; ) {
- if(rtr->tp->hideset && checkhideset(rtr->tp->hideset, np)) {
+ if(rtr->tp->hideset && checkhideset(hideset, np)) {
rtr->tp++;
} else if (rtr->tp->type==SHARP) { /* string operator */
tp = rtr->tp;
@@ -405,10 +405,10 @@
*ttr.tp = *rtr->tp;
hs = newhideset(rtr->tp->hideset, np);
- if(ttr.tp->hideset == 0)
+ if(hideset == 0)
ttr.tp->hideset = hs;
else
- ttr.tp->hideset = unionhideset(ttr.tp->hideset, hs);
+ ttr.tp->hideset = unionhideset(hideset, hs);
expandrow(&ttr, (char*)np->name);
for(tp = ttr.bp; tp != ttr.lp; tp++)
if(tp->type == COMMA)