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; ap<mac->ap->lp; ap++) {
if (ap->len==tp->len && strncmp((char*)ap->t,(char*)tp->t,ap->len)==0)
return ap - mac->ap->bp;
|