scc

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

commit 51ed388be94bcfb8daa15325ba307f0aee3ec248
parent eb5eb795e4d7e8ab22bebc225d385b5405764274
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  5 Apr 2022 20:44:58 +0200

cc1: Add type parameter to addinput()

Addinput() had a complex logic based in the received parameters to
decide what action should be taken. This logic was hard from the
external caller and it created confusing situations, that joined
to the fact that was not clear who was the owner of the memory
made everything a bit complex. This patch solves the problem adding
a type parameter and moving ownership of memory inside addinput()
which is responsible to allocate memory now.

Diffstat:
Msrc/cmd/cc/cc1/cc1.h | 4++--
Msrc/cmd/cc/cc1/cpp.c | 23++++++++++++++---------
Msrc/cmd/cc/cc1/lex.c | 65++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/cmd/cc/cc1/main.c | 8+++++---
4 files changed, 67 insertions(+), 33 deletions(-)

diff --git a/src/cmd/cc/cc1/cc1.h b/src/cmd/cc/cc1/cc1.h @@ -397,6 +397,7 @@ struct yystype { struct macro { Symbol *sym; + char *fname; char **arglist; char *buffer; char *def; @@ -459,7 +460,7 @@ extern int ahead(void); extern int next(void); extern void expect(int tok); extern void discard(void); -extern int addinput(char *, Macro *, char *, int); +extern int addinput(int, void *, int); extern void delinput(void); extern void setsafe(int type); extern void setloc(char *fname, unsigned line); @@ -532,7 +533,6 @@ extern int lexmode, namespace; extern int onlycpp, onlyheader; extern unsigned curctx; extern Symbol *curfun, *zero, *one; -extern char *infile; extern unsigned lineno; extern char filenam[]; extern char *architecture; diff --git a/src/cmd/cc/cc1/cpp.c b/src/cmd/cc/cc1/cpp.c @@ -22,6 +22,7 @@ int disescape; void defdefine(char *name, char *val, char *source) { + char buffer[INPUTSIZ+1]; char *def, *fmt = "#define %s %s\n"; Symbol *sym = &(Symbol) { .name = name, @@ -31,12 +32,18 @@ defdefine(char *name, char *val, char *source) if (!val) val = ""; - def = xmalloc(strlen(fmt) + strlen(name) + strlen(val)); - sprintf(def, fmt, name, val); + if (strlen(fmt) + strlen(name) + strlen(val) > INPUTSIZ) { + errorp("macro definition '%s' too big", name); + return; + } + + sprintf(buffer, fmt, name, val); mp = newmacro(sym); + mp->buffer = buffer; + mp->fname = source; lineno = ++ncmdlines; - addinput(source, mp, def, FAIL); + addinput(IMACRO, mp, FAIL); cpp(); delinput(); } @@ -177,8 +184,7 @@ expandarg(char *arg, char *buf, int bufsiz) int siz, n; char *s = buf; - addinput(filenam, NULL, xstrdup(arg), FAIL); - + addinput(IPARAM, arg, FAIL); for (siz = 0; next() != EOFTOK; siz += yylen+1) { if (yylen > bufsiz-2) { siz = -1; @@ -336,6 +342,7 @@ expand(Symbol *sym) return 0; mp = newmacro(sym); + mp->fname = filenam; mp->buffer = buffer; mp->bufsiz = INPUTSIZ-1; @@ -355,11 +362,9 @@ expand(Symbol *sym) elen = copymacro(mp); substitute: - mp->buffer = NULL; - mp->bufsiz = 0; buffer[elen] = '\0'; DBG("MACRO '%s' expanded to :'%s'", mp->sym->name, buffer); - addinput(filenam, mp, xstrdup(buffer), FAIL); + addinput(IMACRO, mp, FAIL); return 1; } @@ -533,7 +538,7 @@ includefile(char *dir, char *file, size_t filelen) memcpy(path+dirlen, file, filelen); path[dirlen + filelen] = '\0'; - return addinput(path, NULL, NULL, NOFAIL); + return addinput(IFILE, path, NOFAIL); } static char * diff --git a/src/cmd/cc/cc1/lex.c b/src/cmd/cc/cc1/lex.c @@ -65,67 +65,84 @@ unhide(Symbol *sym) } int -addinput(char *fname, Macro *mp, char *buffer, int fail) +addinput(int type, void *arg, int fail) { FILE *fp; - char *extp; - unsigned flags; + char *extp, *fname, *buffer, *infile;; int infileln; + Macro *mp; Symbol *sym; Input *newip, *curip = input; if (curip) curip->lineno = lineno; - if (mp) { - /* this is a macro expansion */ + switch (type) { + case IMACRO: fp = NULL; + mp = arg; sym = mp->sym; - DBG("MACRO: %s expanded to '%s'", sym->name, buffer); + fname = mp->fname; + buffer = mp->buffer; hide(sym); - flags = IMACRO; - } else if (buffer) { - /* this is a macro parameter */ + DBG("INPUT: macro %s expanded to '%s'", sym->name, buffer); + break; + case IPARAM: fp = NULL; - DBG("MACRO parameter '%s'", buffer); - flags = IPARAM; - } else if (fname) { - /* a new file */ + mp = NULL; + buffer = arg; + fname = filenam; + DBG("INPUT: macro parameter '%s'", buffer); + break; + case IFILE: + fname = arg; + mp = NULL; + buffer = NULL; + if ((fp = fopen(fname, "r")) == NULL) { if (!fail) return 0; die("cc1: %s: %s", fname, strerror(errno)); } - flags = IFILE; if (curip && onlyheader) { + infile = curip->filenam; infileln = strlen(infile); if (extp = strrchr(infile, '.')) infileln -= strlen(extp); + /* TODO: is this C99? */ printf("%.*s.o: %s %s\n", infileln, infile, infile, fname); } lineno = 0; - } else { - /* reading from stdin */ + DBG("INPUT: file input '%s'", fname); + break; + case ISTDIN: fp = stdin; + mp = NULL; fname = "<stdin>"; - flags = ISTDIN; + buffer = NULL; lineno = 0; + DBG("INPUT: file input 'stdin'"); + break; + default: + abort(); } if (!buffer) { buffer = xmalloc(INPUTSIZ); buffer[0] = '\0'; + } else { + buffer = xstrdup(buffer); } newip = xmalloc(sizeof(*newip)); newip->next = curip; newip->macro = mp; - newip->lineno = lineno; newip->p = newip->begin = newip->line = buffer; newip->filenam = NULL; + newip->lineno = 0; newip->fp = fp; - newip->flags = flags; + newip->flags = type; input = newip; setloc(fname, lineno); @@ -139,12 +156,22 @@ delinput(void) switch (ip->flags & ITYPE) { case IFILE: + DBG("INPUT: file finished '%s'", ip->filenam); if (fclose(ip->fp)) die("cc1: %s: %s", ip->filenam, strerror(errno)); break; case IMACRO: + DBG("INPUT: macro %s finished", ip->macro->sym->name); unhide(ip->macro->sym); break; + case IPARAM: + DBG("INPUT: macro param finished"); + break; + case ISTDIN: + DBG("INPUT: stdin finished"); + break; + default: + abort(); } input = ip->next; diff --git a/src/cmd/cc/cc1/main.c b/src/cmd/cc/cc1/main.c @@ -8,7 +8,7 @@ #include <scc/scc.h> #include "cc1.h" -char *argv0, *infile; +char *argv0; int warnings; jmp_buf recover; @@ -91,8 +91,10 @@ main(int argc, char *argv[]) for (i = 0; i < uflags.n; ++i) undefmacro(uflags.s[i]); - infile = (*argv) ? *argv : "<stdin>"; - addinput(*argv, NULL, NULL, FAIL); + if (*argv) + addinput(IFILE, *argv, FAIL); + else + addinput(ISTDIN, NULL, FAIL); if (onlycpp || onlyheader) { outcpp();