scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit a2305b12133a41577a844ad42ae22c5b1ac9663c
parent b28fbe8ac9f8a23b909f200723f8947e6f94155e
Author: Quentin Rameau <quinq@fifth.space>
Date:   Tue, 28 Jun 2016 22:49:44 +0200

[cpp] unify definition of internal, cmdline, file macros

In the end, make no difference about how a macro has been defined,
they'll all be processed as if defined with a #define clause infile.
This fixes too command-line definitions of function-like macros.

Diffstat:
Mcc1/cc1.h | 4+++-
Mcc1/cpp.c | 52++++++++++++++++++++++------------------------------
Mcc1/lex.c | 41+++++++++++++++++++++++------------------
Mcc1/main.c | 13+++++++++++++
4 files changed, 61 insertions(+), 49 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -382,6 +382,8 @@ extern int moreinput(void); extern void expect(unsigned tok); extern void discard(void); extern int addinput(char *fname); +extern void allocinput(char *fname, FILE *fp, char *s); +extern void delinput(void); extern void setsafe(int type); extern void ilex(void); #define accept(t) ((yytoken == (t)) ? next() : 0) @@ -418,7 +420,7 @@ extern int cpp(void); extern int expand(char *begin, Symbol *sym); extern void incdir(char *dir); extern void outcpp(void); -extern Symbol *defmacro(char *s); +extern void defdefine(char *macro, char *val); extern void undefmacro(char *s); /* diff --git a/cc1/cpp.c b/cc1/cpp.c @@ -21,30 +21,19 @@ static char **dirinclude; unsigned cppctx; int disexpand; -Symbol * -defmacro(char *s) +void +defdefine(char *macro, char *val) { - char *p, *q; - Symbol *sym; - char def[] = "=1"; + char *def, *fmt = "#define %s %s"; - if ((p = strchr(s, '=')) == NULL) - p = def; - *p++='\0'; - q = xmalloc(strlen(p) + 4); - sprintf(q, "-1#%s", p); + if (!val) + val = ""; + def = xmalloc(strlen(fmt) + strlen(macro) + strlen(val)); - sym = lookup(NS_CPP, s); - if (sym->flags & SDECLARED) { - warn("'%s' redefined"); - free(sym->u.s); - } else { - install(NS_CPP, sym); - sym->flags |= SDECLARED|SSTRING; - } - - sym->u.s = q; - return sym; + sprintf(def, fmt, macro, val); + allocinput("command-line", NULL, def); + cpp(); + delinput(); } void @@ -56,7 +45,7 @@ undefmacro(char *s) void icpp(void) { - static char sdate[17], stime[14]; + static char sdate[14], stime[11]; struct tm *tm; time_t t; static char **bp, *list[] = { @@ -85,16 +74,19 @@ icpp(void) t = time(NULL); tm = localtime(&t); - strftime(sdate, sizeof(sdate), "-1#\"%b %d %Y\"", tm); - strftime(stime, sizeof(stime), "-1#\"%H:%M:%S\"", tm); - defmacro("__DATE__")->u.s = sdate; - defmacro("__TIME__")->u.s = stime; - defmacro("__STDC_VERSION__")->u.s = "-1#199409L"; - symline = defmacro("__LINE__"); - symfile = defmacro("__FILE__"); + strftime(sdate, sizeof(sdate), "\"%b %d %Y\"", tm); + strftime(stime, sizeof(stime), "\"%H:%M:%S\"", tm); + defdefine("__DATE__", sdate); + defdefine("__TIME__", stime); + defdefine("__STDC_VERSION__", "199409L"); + defdefine("__LINE__", NULL); + defdefine("__FILE__", NULL); + + symline = lookup(NS_CPP, "__LINE__"); + symfile = lookup(NS_CPP, "__FILE__"); for (bp = list; *bp; ++bp) - defmacro(*bp)->u.s = "-1#1"; + defdefine(*bp, NULL); } static void diff --git a/cc1/lex.c b/cc1/lex.c @@ -22,16 +22,20 @@ int namespace = NS_IDEN; static int safe, eof; Input *input; -static void -allocinput(char *fname, FILE *fp) +void +allocinput(char *fname, FILE *fp, char *s) { - Input *ip; + Input *ip = xmalloc(sizeof(Input)); - ip = xmalloc(sizeof(Input)); + if (s) { + ip->p = ip->begin = ip->line = s; + ip->nline = 1; + } else { + ip->p = ip->begin = ip->line = xmalloc(INPUTSIZ); + ip->p[0] = '\0'; + ip->nline = 0; + } ip->fname = xstrdup(fname); - ip->p = ip->begin = ip->line = xmalloc(INPUTSIZ); - ip->p[0] = '\0'; - ip->nline = 0; ip->next = input; ip->fp = fp; input = ip; @@ -93,19 +97,22 @@ addinput(char *fname) fp = stdin; fname = "<stdin>"; } - allocinput(fname, fp); + allocinput(fname, fp, NULL); return 1; } -static void +void delinput(void) { Input *ip = input; - if (!ip->next) - eof = 1; - if (fclose(ip->fp)) - die("error: failed to read from input file '%s'", ip->fname); + if (ip->fp) { + if (fclose(ip->fp)) + die("error: failed to read from input file '%s'", + ip->fname); + if (!ip->next) + eof = 1; + } if (eof) return; input = ip->next; @@ -123,14 +130,12 @@ newline(void) static int readchar(void) { + FILE *fp = input->fp; int c; - FILE *fp; -repeat: - if (eof) + if (eof || !fp) return 0; - fp = input->fp; - +repeat: switch (c = getc(fp)) { case EOF: c = '\0'; diff --git a/cc1/main.c b/cc1/main.c @@ -29,6 +29,19 @@ clean(void) } static void +defmacro(char *macro) +{ + char *p = strchr(macro, '='); + + if (p) + *p++ = '\0'; + else + p = "1"; + + defdefine(macro, p); +} + +static void usage(void) { die(!strcmp(name, "cpp") ?