/* * Expand the macro whose name is np, at token trp->tp, in the tokenrow. * Return trp->tp at the first token next to be expanded * (ordinarily the beginning of the expansion) */ void expand(Tokenrow *trp, Nlist *np) { Tokenrow ntr; int ntokc, narg, i; Token *tp; int hs; #ifdef __ORCAC__ Tokenrow **atr; atr = domalloc(sizeof(Tokenrow *) * (NARG+1)); #define RETURN free(atr);return #else Tokenrow *atr[NARG+1]; #define RETURN return; #endif copytokenrow(&ntr, np->vp); /* copy macro value */ if (np->ap==NULL) /* parameterless */ ntokc = 1; else { ntokc = gatherargs(trp, atr, &narg); if (narg<0) { /* not actually a call (no '(') */ trp->tp++; RETURN; } if (narg != rowlen(np->ap)) { error(ERROR, "Disagreement in number of macro arguments"); trp->tp->hideset = newhideset(trp->tp->hideset, np); trp->tp += ntokc; RETURN; } substargs(np, &ntr, atr); /* put args into replacement */ for (i=0; i<narg; i++) { dofree(atr[i]->bp); dofree(atr[i]); } } doconcat(&ntr); /* execute ## operators */ hs = newhideset(trp->tp->hideset, np); for (tp=ntr.bp; tp<ntr.lp; tp++) { /* distribute hidesets */ if (tp->type==NAME) { if (tp->hideset==0) tp->hideset = hs; else tp->hideset = unionhideset(tp->hideset, hs); } } ntr.tp = ntr.bp; insertrow(trp, ntokc, &ntr); trp->tp -= rowlen(&ntr); dofree(ntr.bp); RETURN; }
/* * Expand the macro whose name is np, at token trp->tp, in the tokenrow. * Return trp->tp at the first token next to be expanded * (ordinarily the beginning of the expansion) */ void expand(Tokenrow *trp, Nlist *np) { 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 */ ntokc = 1; else { ntokc = gatherargs(trp, atr, &narg); if (narg<0) { /* not actually a call (no '(') */ /* gatherargs has already pushed trp->tr to the next token */ return; } if (narg != rowlen(np->ap)) { error(ERROR, "Disagreement in number of macro arguments"); trp->tp->hideset = newhideset(trp->tp->hideset, np); trp->tp += ntokc; return; } substargs(np, &ntr, atr); /* put args into replacement */ for (i=0; i<narg; i++) { dofree(atr[i]->bp); dofree(atr[i]); } } doconcat(&ntr); /* execute ## operators */ hs = newhideset(trp->tp->hideset, np); for (tp=ntr.bp; tp<ntr.lp; tp++) { /* distribute hidesets */ if (tp->type==NAME) { if (tp->hideset==0) tp->hideset = hs; else tp->hideset = unionhideset(tp->hideset, hs); } } ntr.tp = ntr.bp; insertrow(trp, ntokc, &ntr); trp->tp -= rowlen(&ntr); dofree(ntr.bp); return; }
/* * Evaluate the ## operators in a tokenrow */ void doconcat(Tokenrow * trp) { Token *ltp, *ntp; Tokenrow ntr; size_t len; for (trp->tp = trp->bp; trp->tp < trp->lp; trp->tp++) { if (trp->tp->type == DSHARP1) trp->tp->type = DSHARP; else if (trp->tp->type == DSHARP) { int i; char tt[NCONCAT]; ltp = trp->tp - 1; ntp = trp->tp + 1; if (ltp < trp->bp || ntp >= trp->lp) { error(ERROR, "## occurs at border of replacement"); continue; } ntp = ltp; i = 1; len = 0; do { if (len + ntp->len + ntp->wslen > sizeof(tt)) { error(ERROR, "## string concatination buffer overrun"); break; } if (ntp != trp->tp + 1) { strncpy((char *) tt + len, (char *) ntp->t - ntp->wslen, ntp->len + ntp->wslen); len += ntp->len + ntp->wslen; } else // Leerzeichen um ## herum entfernen: { strncpy((char *) tt + len, (char *) ntp->t, ntp->len); len += ntp->len; } ntp = trp->tp + i; i++; } while (ntp < trp->lp); tt[len] = '\0'; setsource("<##>", -1, -1, tt, 0); maketokenrow(3, &ntr); gettokens(&ntr, 1); unsetsource(); if (ntr.bp->type == UNCLASS) error(WARNING, "Bad token %r produced by ##", &ntr); while ((ntr.lp-1)->len == 0 && ntr.lp != ntr.bp) ntr.lp--; doconcat(&ntr); trp->tp = ltp; makespace(&ntr, ltp); insertrow(trp, (int)(ntp - ltp), &ntr); dofree(ntr.bp); trp->tp--; } } }
/* * Expand the macro whose name is np, at token trp->tp, in the tokenrow. * Return trp->tp at the first token next to be expanded * (ordinarily the beginning of the expansion) * I.e.: the same position as before! * Only one expansion is performed, then we return to the expandrow() * loop and start at same position. */ void expand(Tokenrow * trp, Nlist * np, MacroValidatorList * pValidators) { Tokenrow ntr; int ntokc, narg; Tokenrow *atr[NARG + 1]; if (Mflag == 2) { if (np->ap) error(INFO, "Macro expansion of %t with %s(%r)", trp->tp, np->name, np->ap); else error(INFO, "Macro expansion of %t with %s", trp->tp, np->name); } copytokenrow(&ntr, np->vp); /* copy macro value */ if (np->ap == NULL) /* parameterless */ ntokc = 1; else { int i; ntokc = gatherargs(trp, atr, &narg); if (narg < 0) { /* not actually a call (no '(') */ trp->tp++; return; } if (narg != rowlen(np->ap)) { error(ERROR, "Disagreement in number of macro arguments"); trp->tp += ntokc; return; } /** If gatherargs passed a macro validating token, this token must become valid here. trp->tp+0 was checked in expandrow(), so we don't need to do it again here: */ for (i = 1; i < ntokc; i++) { mvl_check(pValidators,trp->tp+i); } substargs(np, &ntr, atr); /* put args into replacement */ for (i = 0; i < narg; i++) { dofree(atr[i]->bp); dofree(atr[i]); } } doconcat(&ntr); /* execute ## operators */ ntr.tp = ntr.bp; makespace(&ntr, trp->tp); tokenrow_zeroTokenIdentifiers(&ntr); insertrow(trp, ntokc, &ntr); /* add validator for just invalidated macro: */ np->flag |= ISACTIVE; if (trp->tp != trp->lp) { /* tp is a valid pointer: */ mvl_add(pValidators,np,trp->tp); } else { /* tp is == lp, therefore does not point to valid memory: */ mvl_add(pValidators,np,0); } /* reset trp->tp to original position: */ trp->tp -= ntr.lp - ntr.bp; /* so the result will be tested for macros from the same position again */ dofree(ntr.bp); return; }