MacroValidatorList validators;
mvl_init(&validators); /* Sets all token-identifiers to 0 because tokens may not be initialised (never use C!) */
tokenrow_zeroTokenIdentifiers(trp);
if (flag)
setsource(flag, -1, -1, "", 0); for (tp = trp->tp; tp < trp->lp;)
{
mvl_check(&validators, tp);
if (np->flag & ISMAC)
builtin(trp, np->val); else
{ // coverity[overrun-buffer-arg: FALSE] - a multiple of trp->max is allocated, not trp->max itself
expand(trp, np, &validators);
}
tp = trp->tp;
} // end for if (flag)
unsetsource();
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 mustbecomevalidhere. trp->tp+0wascheckedinexpandrow(),sowedon'tneedtodoit againhere:
*/ 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]);
}
}
/* 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,NULL);
} /* 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;
}
/* *Gatheranarglist,startingintrpwithtppointingatthemacroname. *Returntotalnumberoftokenspassed,stashnumberofargsfound. *trp->tpisnotchangedrelativetothetokenrow.
*/ int
gatherargs(Tokenrow * trp, Tokenrow ** atr, int *narg)
{ int parens = 1; int ntok = 0;
Token *bp, *lp;
Tokenrow ttr; int ntokp; int needspace;
*narg = -1; /* means that there is no macro
* call */ /* look for the ( */ for (;;)
{
trp->tp++;
ntok++; if (trp->tp >= trp->lp)
{ // coverity[overrun-buffer-arg: FALSE] - a multiple of trp->max is allocated, not trp->max itself
gettokens(trp, 0); if ((trp->lp - 1)->type == END)
{
trp->lp -= 1;
trp->tp -= ntok; return ntok;
}
} if (trp->tp->type == LP) break; if (trp->tp->type != NL) return ntok;
}
*narg = 0;
ntok++;
ntokp = ntok;
trp->tp++; /* search for the terminating ), possibly extending the row */
needspace = 0; while (parens > 0)
{ if (trp->tp >= trp->lp)
{ // coverity[overrun-buffer-arg: FALSE] - a multiple of trp->max is allocated, not trp->max itself
gettokens(trp, 0);
} if (needspace)
{
needspace = 0; /* makespace(trp); [rh] */
} if (trp->tp->type == END)
{
trp->lp -= 1;
trp->tp -= ntok;
error(ERROR, "EOF in macro arglist"); return ntok;
} if (trp->tp->type == NL)
{
trp->tp += 1;
adjustrow(trp, -1);
trp->tp -= 1; /* makespace(trp); [rh] */
needspace = 1; continue;
} if (trp->tp->type == LP)
parens++; else if (trp->tp->type == RP)
parens--;
trp->tp++;
ntok++;
}
trp->tp -= ntok; /* Now trp->tp won't move underneath us */
lp = bp = trp->tp + ntokp; for (; parens >= 0; lp++)
{ if (lp->type == LP)
{
parens++; continue;
} if (lp->type == RP)
parens--; if (lp->type == DSHARP)
lp->type = DSHARP1; /* ## not special in arg */ if ((lp->type == COMMA && parens == 0) ||
( parens < 0 && ((lp - 1)->type != LP)))
{ if (*narg >= NARG - 1)
error(FATAL, "Sorry, too many macro arguments");
ttr.bp = ttr.tp = bp;
ttr.lp = lp;
atr[(*narg)++] = normtokenrow(&ttr);
bp = lp + 1;
}
} return ntok;
}
tp = trp->tp;
trp->tp++; /* need to find the real source */
s = cursource; while (s && s->fd == -1)
s = s->next; if (s == NULL)
s = cursource; /* most are strings */
tp->type = STRING; if (tp->wslen)
{
*outptr++ = ' ';
tp->wslen = 1;
}
op = outptr;
*op++ = '"'; switch (biname)
{
case KLINENO:
tp->type = NUMBER;
op = outnum(op - 1, s->line); break;
case KFILE:
{ char *src = s->filename;
while ((*op++ = *src++) != 0) if (src[-1] == '\\')
*op++ = '\\';
op--; break;
}
case KDATE:
strncpy(op, curtime + 4, 7);
strncpy(op + 7, curtime + 20, 4);
op += 11; break;
case KTIME:
strncpy(op, curtime + 11, 8);
op += 8; break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.