[hackers] [scc] Reduce amount of non declared symbols generated in cpp || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Tue, 11 Aug 2015 22:04:26 +0200 (CEST)

commit 454cbc4039b4f3c7efb737b04259c0e4ab73ba40
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Tue Aug 11 21:41:58 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Tue Aug 11 21:51:48 2015 +0200

    Reduce amount of non declared symbols generated in cpp
    
    There was a lot of different places where spurious symbols
    were created. This patch minimizes it setting the correct
    namespace before calling next(). It also avoids error()
    calls, because the error recovery mechanish will conflict
    with the line behaviour of the preprocessor.

diff --git a/cc1/cpp.c b/cc1/cpp.c
index ae55236..d864fe9 100644
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
_AT_@ -26,12 +26,8 @@ int disexpand;
 static Symbol *
 defmacro(char *s)
 {
- Symbol *sym;
-
         strcpy(yytext, s);
- sym = addmacro();
- sym->flags |= ISDECLARED;
- return sym;
+ return addmacro();
 }
 
 void
_AT_@ -239,7 +235,6 @@ static int
 getpars(Symbol *args[NR_MACROARG])
 {
         int n = -1;
- char *err;
 
         if (!accept('('))
                 return n;
_AT_@ -249,12 +244,12 @@ getpars(Symbol *args[NR_MACROARG])
 
         do {
                 if (n == NR_MACROARG) {
- err = "too much parameters in macro";
- goto popctx_and_error;
+ printerr("too much parameters in macro");
+ return NR_MACROARG;
                 }
                 if (yytoken != IDEN) {
- err = "macro arguments must be identifiers";
- goto popctx_and_error;
+ printerr("macro arguments must be identifiers");
+ return NR_MACROARG;
                 }
                 args[n++] = yylval.sym;
                 next();
_AT_@ -262,17 +257,12 @@ getpars(Symbol *args[NR_MACROARG])
         expect(')');
 
         return n;
-
-popctx_and_error:
- popctx();
- error(err);
 }
 
-static void
+static bool
 getdefs(Symbol *args[NR_MACROARG], int nargs, char *bp, size_t bufsiz)
 {
         Symbol **argp;
- char *err;
         size_t len;
         int prevc = 0, ispar;
 
_AT_@ -288,14 +278,16 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *bp, size_t bufsiz)
                                 ispar = 1;
                         }
                 }
- if (prevc == '#' && !ispar)
- goto bad_stringer;
+ if (prevc == '#' && !ispar) {
+ printerr("'#' is not followed by a macro parameter");
+ return 0;
+ }
                 if (yytoken == EOFTOK)
                         break;
 
                 if ((len = strlen(yytext)) >= bufsiz) {
- err = "too long macro";
- goto popctx_and_error;
+ printerr("too long macro");
+ return 0;
                 }
                 memcpy(bp, yytext, len);
                 bp += len;
_AT_@ -305,13 +297,7 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *bp, size_t bufsiz)
                 next();
         }
         *bp = '\0';
- return;
-
-bad_stringer:
- err = "'#' is not followed by a macro parameter";
-popctx_and_error:
- popctx();
- error(err);
+ return 1;
 }
 
 static void
_AT_@ -323,27 +309,31 @@ define(void)
 
         if (cppoff)
                 return;
+
+ setnamespace(NS_CPP);
+ next();
         if (yytoken != IDEN)
                 error("macro names must be identifiers");
         sym = yylval.sym;
- if ((sym->flags & ISDECLARED) && sym->ns == NS_CPP) {
+ if (sym->flags & ISDECLARED) {
                 warn("'%s' redefined", yytext);
                 free(sym->u.s);
- } else if (sym->ns != NS_CPP) {
+ } else {
                 sym = addmacro();
         }
- sym->flags |= ISDECLARED;
-
- pushctx();
 
         next();
- n = getpars(args);
+ if ((n = getpars(args)) == NR_MACROARG)
+ goto delete;
         sprintf(buff, "%02d#", n);
- getdefs(args, n, buff+3, LINESIZ-3);
+ if (!getdefs(args, n, buff+3, LINESIZ-3))
+ goto delete;
         sym->u.s = xstrdup(buff);
         fprintf(stderr, "MACRO '%s' defined as '%s'\n", sym->name, buff);
+ return;
 
- popctx();
+delete:
+ delmacro(sym);
 }
 
 static void
_AT_@ -359,6 +349,10 @@ include(void)
 
         if (cppoff)
                 return;
+
+ setnamespace(NS_IDEN);
+ next();
+
         switch (*yytext) {
         case '<':
                 if ((p = strchr(input->begin, '>')) == NULL)
_AT_@ -395,15 +389,18 @@ include(void)
                 if (addinput(path))
                         break;
         }
+
         if (*bp)
- error("included file '%s' not found", file);
+ printerr("included file '%s' not found", file);
 
         return;
 
 bad_include:
- error("#include expects \"FILENAME\" or <FILENAME>");
+ printerr("#include expects \"FILENAME\" or <FILENAME>");
+ return;
 too_long:
- error("#include FILENAME too long");
+ printerr("#include FILENAME too long");
+ return;
 }
 
 static void
_AT_@ -415,20 +412,29 @@ line(void)
         if (cppoff)
                 return;
 
+ setnamespace(NS_IDEN);
+ next();
         n = strtol(yytext, &endp, 10);
- if (n <= 0 || n > USHRT_MAX || *endp != '\0')
- error("first parameter of #line is not a positive integer");
+ if (n <= 0 || n > USHRT_MAX || *endp != '\0') {
+ printerr("first parameter of #line is not a positive integer");
+ return;
+ }
 
- input->nline = yylval.sym->u.i;
         next();
         if (yytoken == EOFTOK)
+ goto set_line;
+
+ if (*yytext != '\"' || yylen == 1) {
+ printerr("second parameter of #line is not a valid filename");
                 return;
+ }
 
- if (*yytext != '\"' || yylen == 1)
- error("second parameter of #line is not a valid filename");
         free(input->fname);
         input->fname = xstrdup(yylval.sym->u.s);
         next();
+
+set_line:
+ input->nline = yylval.sym->u.i;
 }
 
 static void
_AT_@ -464,15 +470,21 @@ ifclause(int negate, int isifdef)
 
         if (isifdef) {
                 if (yytoken != IDEN) {
- error("no macro name given in #%s directive",
- (negate) ? "ifndef" : "ifdef");
+ printerr("no macro name given in #%s directive",
+ (negate) ? "ifndef" : "ifdef");
+ return;
                 }
- sym = lookup(NS_CPP);
+ sym = yylval.sym;
                 next();
                 status = (sym->flags & ISDECLARED) != 0;
+ if (!status)
+ delmacro(sym);
         } else {
- if ((expr = iconstexpr()) == NULL)
- error("parameter of #if is not an integer constant expression");
+ /* TODO: catch recovery here */
+ if ((expr = iconstexpr()) == NULL) {
+ printerr("parameter of #if is not an integer constant expression");
+ return;
+ }
                 status = expr->sym->u.i != 0;
         }
 
_AT_@ -485,18 +497,24 @@ ifclause(int negate, int isifdef)
 static void
 cppif(void)
 {
+ setnamespace(NS_CPP);
+ next();
         ifclause(0, 0);
 }
 
 static void
 ifdef(void)
 {
+ setnamespace(NS_CPP);
+ next();
         ifclause(0, 1);
 }
 
 static void
 ifndef(void)
 {
+ setnamespace(NS_CPP);
+ next();
         ifclause(1, 1);
 }
 
_AT_@ -507,6 +525,7 @@ endif(void)
                 error("#endif without #if");
         if (!ifstatus[--cppctx])
                 --cppoff;
+ next();
 }
 
 static void
_AT_@ -519,6 +538,7 @@ elseclause(void)
 
         status = (ifstatus[cppctx-1] ^= 1);
         cppoff += (status) ? -1 : 1;
+ next();
 }
 
 static void
_AT_@ -533,12 +553,14 @@ undef(void)
 {
         if (cppoff)
                 return;
+
+ setnamespace(NS_CPP);
+ next();
         if (yytoken != IDEN) {
                 error("no macro name given in #undef directive");
                 return;
         }
- if (yylval.sym->ns == NS_CPP)
- delmacro(yylval.sym);
+ delmacro(yylval.sym);
         next();
 }
 
_AT_@ -576,11 +598,13 @@ cpp(void)
                 /* nothing */;
         if (!bp->token)
                 error("incorrect preprocessor directive");
- next();
- (*bp->fun)();
+
+ pushctx(); /* create a new context to avoid polish */
+ (*bp->fun)(); /* the current context, and to get all */
+ popctx(); /* the symbols freed at the end */
 
         if (yytoken != EOFTOK && !cppoff)
- error("trailing characters after preprocessor directive");
+ printerr("trailing characters after preprocessor directive");
         disexpand = 0;
         lexmode = CCMODE;
 
diff --git a/cc1/lex.c b/cc1/lex.c
index bc4c5d8..6b7ce44 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
_AT_@ -379,7 +379,7 @@ iden(void)
         input->p = p;
         tok2str();
         yylval.sym = sym = lookup(lex_ns);
- if (sym->ns == NS_CPP) {
+ if (sym->ns == NS_CPP && lexmode == CCMODE) {
                 if (!disexpand && expand(begin, sym))
                         return next();
                 /*
diff --git a/cc1/symbol.c b/cc1/symbol.c
index 2286a96..cc736e8 100644
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
_AT_@ -157,7 +157,7 @@ newsym(unsigned ns)
         sym->ctx = curctx;
         sym->token = IDEN;
         sym->flags = ISDECLARED;
- sym->name = NULL;
+ sym->u.s = sym->name = NULL;
         sym->type = NULL;
         sym->next = sym->hash = NULL;
 
_AT_@ -219,6 +219,7 @@ addmacro(void)
         /* Force cpp symbols to be at the beginning of the hash */
         curctx = UCHAR_MAX;
         sym = lookup(NS_CPP);
+ sym->flags |= ISDECLARED;
         curctx = ctx;
         return sym;
 }
Received on Tue Aug 11 2015 - 22:04:26 CEST

This archive was generated by hypermail 2.3.0 : Tue Aug 11 2015 - 22:12:11 CEST