scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 02f0aed96a08450b8f69e89fb784483e9e6af864
parent d868791e6cb87f6e2511517d4f22b3d04a843dab
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  5 Apr 2022 14:35:05 +0200

cc1: Add Macro type

Macro expansion is a complex topic, and it is better
if we add a type that can encapsulate this complexity.

Diffstat:
Msrc/cmd/cc/cc1/cc1.h | 13+++++++++++++
Msrc/cmd/cc/cc1/cpp.c | 104+++++++++++++++++++++++++++++++++++++++++++------------------------------------
2 files changed, 70 insertions(+), 47 deletions(-)

diff --git a/src/cmd/cc/cc1/cc1.h b/src/cmd/cc/cc1/cc1.h @@ -282,6 +282,7 @@ typedef struct type Type; typedef struct symbol Symbol; typedef struct swtch Switch; typedef struct node Node; +typedef struct macro Macro; typedef struct input Input; typedef struct arch Arch; @@ -394,6 +395,15 @@ struct yystype { unsigned char token; }; +struct macro { + Symbol *sym; + char **arglist; + char *buffer; + char *def; + int bufsiz; + int npars; +}; + #ifdef stdin struct input { char flags; @@ -491,6 +501,9 @@ extern void outcpp(void); extern void defdefine(char *macro, char *val, char *source); extern void undefmacro(char *s); extern void ppragmaln(void); +extern void delmacro(Macro *); +extern Macro *newmacro(Symbol *); + /* builtin.c */ extern void ibuilts(void); diff --git a/src/cmd/cc/cc1/cpp.c b/src/cmd/cc/cc1/cpp.c @@ -9,18 +9,6 @@ #include <scc/scc.h> #include "cc1.h" -struct macroctx { - Symbol *sym; - char *argp; - char **arglist; - char **listp; - char *buffer; - char *def; - size_t bufsiz; - int arglen; - int npars; -}; - static unsigned ncmdlines; static Symbol *symline, *symfile; static unsigned char ifstatus[NR_COND]; @@ -87,7 +75,7 @@ icpp(void) } static void -nextcpp(struct macroctx *mp) +nextcpp(Macro *mp) { next(); if (yytoken == EOFTOK) @@ -98,7 +86,7 @@ nextcpp(struct macroctx *mp) } static void -paren(struct macroctx *mp) +paren(Macro *mp) { for (;;) { nextcpp(mp); @@ -112,11 +100,11 @@ paren(struct macroctx *mp) } } -static void -parameter(struct macroctx *mp) +static char * +parameter(Macro *mp) { int siz; - char *begin, *end; + char *s, *begin, *end; begin = input->begin; for (;;) { @@ -130,15 +118,9 @@ parameter(struct macroctx *mp) --end; siz = end - begin; - if (siz+1 > mp->arglen) { - error("argument overflow invoking macro \"%s\"", - mp->sym->name); - } - memcpy(mp->argp, begin, siz); - mp->argp += siz; - *mp->argp++ = '\0'; - mp->arglen -= siz + 1; - return; + s = memcpy(xmalloc(siz+1), begin, siz); + s[siz] = '\0'; + return s; case '(': paren(mp); break; @@ -147,7 +129,7 @@ parameter(struct macroctx *mp) } static int -parsepars(struct macroctx *mp) +parsepars(Macro *mp) { int n; @@ -163,8 +145,8 @@ parsepars(struct macroctx *mp) next(); } else { do { - *mp->listp++ = mp->argp; - parameter(mp); + mp->arglist = xrealloc(mp->arglist, n*sizeof(char *)); + mp->arglist[n] = parameter(mp); } while (++n < NR_MACROARG && yytoken == ','); } if (yytoken != ')') @@ -209,7 +191,7 @@ expandarg(char *arg, char *buf, int bufsiz) } static int -copymacro(struct macroctx *mp) +copymacro(Macro *mp) { int delim, c, esc; char *s, *p, *arg, *bp; @@ -300,14 +282,43 @@ expansion_too_long: error("macro expansion of \"%s\" too long", mp->sym->name); } +void +delmacro(Macro *mp) +{ + int i; + + if (!mp) + return; + + if (mp->arglist) { + for (i = 0; i < mp->npars; i++) + free(mp->arglist[i]); + } + free(mp->arglist); + free(mp); +} + +Macro * +newmacro(Symbol *sym) +{ + Macro *mp; + + mp = xmalloc(sizeof(*mp)); + mp->sym = sym; + mp->arglist = NULL; + mp->def = sym->u.s + 3; + mp->npars = 0; + mp->npars = atoi(sym->u.s); + + return mp; +} + int expand(Symbol *sym) { int elen; - int i; - struct macroctx macro; - char *arglist[NR_MACROARG]; - char arguments[INPUTSIZ], buffer[INPUTSIZ]; + Macro *mp; + char buffer[INPUTSIZ]; DBG("MACRO '%s' detected disexpand=%d hide=%d", sym->name, disexpand, sym->hide); @@ -315,15 +326,9 @@ expand(Symbol *sym) if (disexpand || sym->hide) return 0; - macro.sym = sym; - macro.argp = arguments; - macro.listp = arglist; - macro.arglist = arglist; - macro.arglen = INPUTSIZ; - macro.buffer = buffer; - macro.npars = atoi(sym->u.s); - macro.def = sym->u.s + 3; - macro.bufsiz = INPUTSIZ-1; + mp = newmacro(sym); + mp->buffer = buffer; + mp->bufsiz = INPUTSIZ-1; if (sym == symfile) { elen = sprintf(buffer, "\"%s\" ", filenam); @@ -334,14 +339,19 @@ expand(Symbol *sym) goto substitute; } - if (!parsepars(&macro)) + if (!parsepars(mp)) { + delmacro(mp); return 0; - elen = copymacro(&macro); + } + elen = copymacro(mp); substitute: + mp->buffer = NULL; + mp->bufsiz = 0; buffer[elen] = '\0'; - DBG("MACRO '%s' expanded to :'%s'", macro.sym->name, buffer); - addinput(filenam, sym, xstrdup(buffer), FAIL); + DBG("MACRO '%s' expanded to :'%s'", mp->sym->name, buffer); + addinput(filenam, mp->sym, xstrdup(buffer), FAIL); + delmacro(mp); return 1; }