cpp: add C99 variadic macros [rsc] --rw-rw-r-- M 628694 glenda sys 4707 Apr 10 13:53 sys/src/cmd/cpp/cpp.h /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/cpp.h:27,32 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/cpp.h:27,33 #define ISKW 02 /* is PP keyword */ #define ISUNCHANGE 04 /* can't be #defined in PP */ #define ISMAC 010 /* builtin macro, e.g. __LINE__ */ + #define ISVARMAC 020 /* variadic macro */ #define EOB 0xFE /* sentinel for end of input buffer */ #define EOFC 0xFD /* sentinel for end of input file */ /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/cpp.h:110,116 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/cpp.h:111,117 void doif(Tokenrow *, enum kwtype); void expand(Tokenrow *, Nlist *); void builtin(Tokenrow *, int); - int gatherargs(Tokenrow *, Tokenrow **, int *); + int gatherargs(Tokenrow *, Tokenrow **, int, int *); void substargs(Nlist *, Tokenrow *, Tokenrow **); void expandrow(Tokenrow *, char *); void maketokenrow(int, Tokenrow *); [rsc] --rw-rw-r-- M 628694 glenda sys 11287 Apr 10 13:53 sys/src/cmd/cpp/macro.c /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:12,18 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:12,20 Token *tp; Nlist *np; Tokenrow *def, *args; + int dots; + dots = 0; tp = trp->tp+1; if (tp>=trp->lp || tp->type!=NAME) { error(ERROR, "#defined token is not a name"); /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:36,42 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:38,46 int err = 0; for (;;) { Token *atp; - if (tp->type!=NAME) { + if (tp->type == ELLIPS) + dots++; + else if (tp->type!=NAME) { err++; break; } /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:51,56 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:55,62 tp += 1; if (tp->type==RP) break; + if (dots) + error(ERROR, "arguments after '...' in macro"); if (tp->type!=COMMA) { err++; break; /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:83,88 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:89,96 np->ap = args; np->vp = def; np->flag |= ISDEFINED; + if(dots) + np->flag |= ISVARMAC; } /* /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:188,194 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:196,202 if (np->ap==NULL) /* parameterless */ ntokc = 1; else { - ntokc = gatherargs(trp, atr, &narg); + ntokc = gatherargs(trp, atr, (np->flag&ISVARMAC) ? rowlen(np->ap) : 0, &narg); if (narg<0) { /* not actually a call (no '(') */ /* error(WARNING, "%d %r\n", narg, trp); */ /* gatherargs has already pushed trp->tr to the next token */ /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:229,235 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:237,243 * trp->tp is not changed relative to the tokenrow. */ int - gatherargs(Tokenrow *trp, Tokenrow **atr, int *narg) + gatherargs(Tokenrow *trp, Tokenrow **atr, int dots, int *narg) { int parens = 1; int ntok = 0; /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:304,310 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:312,320 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 ((lp->type==COMMA && parens==0) || (parens<0 && (lp-1)->type!=LP)) { + if (lp->type == COMMA && dots && *narg == dots-1) + continue; if (*narg>=NARG-1) error(FATAL, "Sorry, too many macro arguments"); ttr.bp = ttr.tp = bp; /n/sourcesdump/2006/0410/plan9/sys/src/cmd/cpp/macro.c:412,417 - /n/sourcesdump/2006/0411/plan9/sys/src/cmd/cpp/macro.c:422,429 if (tp->type!=NAME || mac->ap==NULL) return -1; + if((mac->flag & ISVARMAC) && strcmp((char*)tp->t, "__VA_ARGS__") == 0) + return rowlen(mac->ap) - 1; for (ap=mac->ap->bp; apap->lp; ap++) { if (ap->len==tp->len && strncmp((char*)ap->t,(char*)tp->t,ap->len)==0) return ap - mac->ap->bp;