/* * do a macro definition. tp points to the name being defined in the line */ void dodefine(Tokenrow *trp) { Token *tp; Nlist *np; Tokenrow *def, *args; tp = trp->tp+1; if (tp>=trp->lp || tp->type!=NAME) { error(ERROR, "#defined token is not a name"); return; } np = lookup(tp, 1); if (np->flag&ISUNCHANGE) { error(ERROR, "#defined token %t can't be redefined", tp); return; } /* collect arguments */ tp += 1; args = NULL; if (tp<trp->lp && tp->type==LP && tp->wslen==0) { /* macro with args */ int narg = 0; tp += 1; args = new(Tokenrow); maketokenrow(2, args); if (tp->type!=RP) { int err = 0; for (;;) { Token *atp; if (tp->type!=NAME) { err++; break; } if (narg>=args->max) growtokenrow(args); for (atp=args->bp; atp<args->lp; atp++) if (atp->len==tp->len && strncmp((char*)atp->t, (char*)tp->t, tp->len)==0) error(ERROR, "Duplicate macro argument"); *args->lp++ = *tp; narg++; tp += 1; if (tp->type==RP) break; if (tp->type!=COMMA) { err++; break; } tp += 1; } if (err) { error(ERROR, "Syntax error in macro parameters"); return; } } tp += 1; } trp->tp = tp; if (((trp->lp)-1)->type==NL) trp->lp -= 1; def = normtokenrow(trp); if (np->flag&ISDEFINED) { if (comparetokens(def, np->vp) || (np->ap==NULL) != (args==NULL) || np->ap && comparetokens(args, np->ap)) error(ERROR, "Macro redefinition of %t", trp->bp+2); } if (args) { Tokenrow *tap; tap = normtokenrow(args); dofree(args->bp); args = tap; } np->ap = args; np->vp = def; np->flag |= ISDEFINED; }
/* * do a macro definition. tp points to the name being defined in the line */ void dodefine(Tokenrow * trp) { Token *tp; Nlist *np; Source *s; Tokenrow *def, *args; static uchar location[(PATH_MAX + 8) * NINC], *cp; tp = trp->tp + 1; if (tp >= trp->lp || tp->type != NAME) { error(ERROR, "#defined token is not a name"); return; } np = lookup(tp, 1); if (np->flag & ISUNCHANGE) { error(ERROR, "#defined token %t can't be redefined", tp); return; } /* collect arguments */ tp += 1; args = NULL; if (tp < trp->lp && tp->type == LP && tp->wslen == 0) { tp += 1; args = new(Tokenrow); maketokenrow(2, args); if (tp->type != RP) { /* macro with args */ size_t narg = 0; int err = 0; for (;;) { Token *atp; if (tp->type != NAME) { err++; break; } if (narg >= args->max) growtokenrow(args); for (atp = args->bp; atp < args->lp; atp++) if (atp->len == tp->len && strncmp((char *) atp->t, (char *) tp->t, tp->len) == 0) error(ERROR, "Duplicate macro argument"); *args->lp++ = *tp; narg++; tp += 1; if (tp->type == RP) break; if (tp->type != COMMA) { err++; break; } tp += 1; } if (err) { error(ERROR, "Syntax error in macro parameters"); return; } } tp += 1; } trp->tp = tp; if (((trp->lp) - 1)->type == NL) trp->lp -= 1; def = normtokenrow(trp); if (np->flag & ISDEFINED) { if (comparetokens(def, np->vp) || (np->ap == NULL) != (args == NULL) || (np->ap && comparetokens(args, np->ap))) { if ( np->loc ) error(ERROR, "Macro redefinition of %t (already defined at %s)", trp->bp + 2, np->loc); else error(ERROR, "Macro redefinition of %t (already defined at %s)", trp->bp + 2, "commandline" ); } } if (args) { Tokenrow *tap; tap = normtokenrow(args); dofree(args->bp); dofree(args); args = tap; } np->ap = args; np->vp = def; np->flag |= ISDEFINED; /* build location string of macro definition */ for (cp = location, s = cursource; s; s = s->next) if (*s->filename) { if (cp != location) *cp++ = ' '; sprintf((char *)cp, "%s:%d", s->filename, s->line); cp += strlen((char *)cp); } np->loc = newstring(location, strlen((char *)location), 0); if (Mflag) { if (np->ap) error(INFO, "Macro definition of %s(%r) [%r]", np->name, np->ap, np->vp); else error(INFO, "Macro definition of %s [%r]", np->name, np->vp); } }