shithub: riscv

Download patch

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)