[hackers] [scc] [cc1] Add support for macro expansion in input buffers || Roberto E. Vargas Caballero
commit e075a0228c63e8bed0a848713569a3b8fe52012c
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Jan 11 11:17:11 2017 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Jan 11 12:12:02 2017 +0100
[cc1] Add support for macro expansion in input buffers
We are going to implement the macro expansion using a push up/pop down of buffers.
It is important to keep a track of the symbol which generates the push up,
because this symbol becomes part of the hide set (see Prosser algorithm)
of the current expansion.
diff --git a/cc1/cc1.h b/cc1/cc1.h
index ac9f9d3..7485a34 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -307,6 +307,7 @@ struct symbol {
Type *type;
unsigned short id;
unsigned char ctx;
+ unsigned char hide;
char ns;
unsigned char token;
short flags;
_AT_@ -344,6 +345,7 @@ struct yystype {
struct input {
char *fname;
FILE *fp;
+ Symbol *hide;
char *line, *begin, *p;
struct input *next;
unsigned short nline;
_AT_@ -392,7 +394,7 @@ extern unsigned next(void);
extern int moreinput(void);
extern void expect(unsigned tok);
extern void discard(void);
-extern int addinput(char *fname);
+extern int addinput(char *fname, Symbol *hide);
extern void allocinput(char *fname, FILE *fp, char *line);
extern void delinput(void);
extern void setsafe(int type);
diff --git a/cc1/cpp.c b/cc1/cpp.c
index c40e436..2d77b16 100644
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
_AT_@ -238,14 +238,13 @@ expansion_too_long:
error("macro expansion of \"%s\" too long", macroname);
}
-#define BUFSIZE ((INPUTSIZ > FILENAME_MAX+2) ? INPUTSIZ : FILENAME_MAX+2)
int
expand(char *begin, Symbol *sym)
{
- size_t total, elen, rlen, llen, ilen;
+ size_t elen;
int n;
char *s = sym->u.s;
- char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE];
+ char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[INPUTSIZ];
macroname = sym->name;
if (sym == symfile) {
_AT_@ -268,30 +267,12 @@ expand(char *begin, Symbol *sym)
substitute:
DBG("MACRO '%s' expanded to :'%s'", macroname, buffer);
- rlen = strlen(input->p); /* rigth length */
- llen = begin - input->line; /* left length */
- ilen = input->p - begin; /* invocation length */
- total = llen + elen + rlen;
-
- if (total >= LINESIZ)
- error("macro expansion of \"%s\" too long", macroname);
-
- /* cut macro invocation */
- memmove(begin, begin + ilen, rlen);
-
- /* paste macro expansion */
- memmove(begin + elen, begin, rlen);
- memcpy(begin, buffer, elen);
- input->line[total] = '\0';
-
- input->p = input->begin = begin;
-
- if (!(sym->flags & SDECLARED))
- killsym(sym);
+ addinput(NULL, sym);
+ memcpy(input->line, buffer, elen);
+ input->line[elen] = '\0';
return 1;
}
-#undef BUFSIZE
static int
getpars(Symbol *args[NR_MACROARG])
_AT_@ -449,7 +430,7 @@ includefile(char *dir, char *file, size_t filelen)
memcpy(path+dirlen, file, filelen);
path[dirlen + filelen] = '\0';
- return addinput(path);
+ return addinput(path, NULL);
}
static void
diff --git a/cc1/lex.c b/cc1/lex.c
index 98a9713..130c586 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
_AT_@ -2,6 +2,7 @@
static char sccsid[] = "_AT_(#) ./cc1/lex.c";
#include <ctype.h>
#include <errno.h>
+#include <limits.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
_AT_@ -85,18 +86,32 @@ ilex(void)
}
int
-addinput(char *fname)
+addinput(char *fname, Symbol *hide)
{
FILE *fp;
+ unsigned nline = 0;
- if (fname) {
+ if (hide) {
+ /* this is a macro expansion */
+ fp = NULL;
+ fname = xstrdup(input->fname);
+ nline = input->nline;
+ if (hide->hide == UCHAR_MAX)
+ die("Too many macro expansions");
+ ++hide->hide;
+ } else if (fname) {
+ /* a new file */
if ((fp = fopen(fname, "r")) == NULL)
return 0;
} else {
+ /* reading from stdin */
fp = stdin;
fname = "<stdin>";
}
allocinput(fname, fp, NULL);
+ input->hide = hide;
+ input->nline = nline;
+
return 1;
}
_AT_@ -104,6 +119,7 @@ void
delinput(void)
{
Input *ip = input;
+ Symbol *hide = ip->hide;
if (ip->fp) {
if (fclose(ip->fp))
_AT_@ -112,6 +128,17 @@ delinput(void)
if (!ip->next)
eof = 1;
}
+ if (hide) {
+ --hide->hide;
+ /*
+ * If the symbol is not declared then it was
+ * an extension due to a #if directive with
+ * a non declared symbol (expanded to 0),
+ * thus we have to kill the symbol
+ */
+ if ((hide->flags & SDECLARED) == 0)
+ killsym(hide);
+ }
if (eof)
return;
input = ip->next;
_AT_@ -179,14 +206,21 @@ readline(void)
char *bp, *lim;
char c, peekc = 0;
-repeat:
+repeat_from_file:
input->begin = input->p = input->line;
*input->line = '\0';
+
+repeat_from_expand:
if (eof)
return 0;
+
+ if (!input->fp) {
+ delinput();
+ goto repeat_from_expand;
+ }
if (feof(input->fp)) {
delinput();
- goto repeat;
+ goto repeat_from_file;
}
lim = &input->line[INPUTSIZ-1];
for (bp = input->line; bp < lim; *bp++ = c) {
_AT_@ -213,8 +247,10 @@ moreinput(void)
static char file[FILENAME_MAX];
static unsigned nline;
char *s;
+ int wasexpand;
repeat:
+ wasexpand = input->hide != NULL;
if (!readline())
return 0;
while (isspace(*input->p))
_AT_@ -225,7 +261,7 @@ repeat:
goto repeat;
}
- if (onlycpp) {
+ if (onlycpp && !wasexpand) {
putchar('\n');
if (strcmp(file, input->fname)) {
strcpy(file, input->fname);
_AT_@ -497,7 +533,7 @@ iden(void)
input->p = p;
tok2str();
if ((sym = lookup(NS_CPP, yytext, NOALLOC)) != NULL) {
- if (!disexpand && expand(begin, sym))
+ if (!disexpand && !sym->hide && expand(begin, sym))
return next();
}
sym = lookup(namespace, yytext, ALLOC);
diff --git a/cc1/main.c b/cc1/main.c
index 3525cea..83498e9 100644
--- a/cc1/main.c
+++ b/cc1/main.c
_AT_@ -102,7 +102,7 @@ main(int argc, char *argv[])
for (i = 0; i < uflags.n; ++i)
undefmacro(uflags.s[i]);
- if (!addinput(*argv)) {
+ if (!addinput(*argv, NULL)) {
die("error: failed to open input file '%s': %s",
*argv, strerror(errno));
}
diff --git a/cc1/symbol.c b/cc1/symbol.c
index 633691d..24565d7 100644
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
_AT_@ -152,6 +152,7 @@ newsym(int ns, char *name)
name = xstrdup(name);
sym->name = name;
sym->id = 0;
+ sym->hide = 0;
sym->ns = ns;
sym->ctx = (ns == NS_CPP) ? UCHAR_MAX : curctx;
sym->token = IDEN;
Received on Wed Jan 11 2017 - 12:13:14 CET
This archive was generated by hypermail 2.3.0
: Wed Jan 11 2017 - 12:24:16 CET