diff options
| author | forsyth <forsyth@vitanuova.com> | 2010-07-15 17:13:02 +0100 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2010-07-15 17:13:02 +0100 |
| commit | 4d1cf5269ce9db7a55c9be8fb51fda675c5d8223 (patch) | |
| tree | 7f3d5e5c801b38cd38116259247dba984a01553d /utils/cc | |
| parent | 287839a46d8cf9bfe7ae06f655a4a74f8ba54793 (diff) | |
20100715-1712
Diffstat (limited to 'utils/cc')
| -rw-r--r-- | utils/cc/macbody | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/utils/cc/macbody b/utils/cc/macbody index 91181875..e26dc427 100644 --- a/utils/cc/macbody +++ b/utils/cc/macbody @@ -1,3 +1,4 @@ +#define VARMAC 0x80 long getnsn(void) @@ -43,6 +44,27 @@ getsym(void) return lookup(); } +Sym* +getsymdots(int *dots) +{ + int c; + Sym *s; + + s = getsym(); + if(s != S) + return s; + + c = getnsc(); + if(c != '.'){ + unget(c); + return S; + } + if(getc() != '.' || getc() != '.') + yyerror("bad dots in macro"); + *dots = 1; + return slookup("__VA_ARGS__"); +} + int getcom(void) { @@ -172,7 +194,7 @@ macdef(void) { Sym *s, *a; char *args[NARG], *np, *base; - int n, i, c, len; + int n, i, c, len, dots; int ischr; s = getsym(); @@ -182,13 +204,14 @@ macdef(void) yyerror("macro redefined: %s", s->name); c = getc(); n = -1; + dots = 0; if(c == '(') { n++; c = getnsc(); if(c != ')') { unget(c); for(;;) { - a = getsym(); + a = getsymdots(&dots); if(a == S) goto bad; if(n >= NARG) { @@ -199,7 +222,7 @@ macdef(void) c = getnsc(); if(c == ')') break; - if(c != ',') + if(c != ',' || dots) goto bad; } } @@ -325,6 +348,8 @@ macdef(void) } while(len & 3); *base = n+1; + if(dots) + *base |= VARMAC; s->macro = base; if(debug['m']) print("#define %s %s\n", s->name, s->macro+1); @@ -343,16 +368,19 @@ macexpand(Sym *s, char *b) { char buf[2000]; int n, l, c, nargs; - char *arg[NARG], *cp, *ob, *ecp; + char *arg[NARG], *cp, *ob, *ecp, dots; ob = b; - nargs = *s->macro - 1; - if(nargs < 0) { + if(*s->macro == 0) { strcpy(b, s->macro+1); if(debug['m']) print("#expand %s %s\n", s->name, ob); return; } + + nargs = (char)(*s->macro & ~VARMAC) - 1; + dots = *s->macro & VARMAC; + c = getnsc(); if(c != '(') goto bad; @@ -425,6 +453,10 @@ macexpand(Sym *s, char *b) } if(l == 0) { if(c == ',') { + if(n == nargs && dots) { + *cp++ = ','; + continue; + } *cp++ = 0; arg[n++] = cp; if(n > nargs) @@ -452,6 +484,8 @@ macexpand(Sym *s, char *b) cp = s->macro+1; for(;;) { c = *cp++; + if(c == '\n') + c = ' '; if(c != '#') { *b++ = c; if(c == 0) |
