[hackers] [scc] [cc1] Use LOC variables for input || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 30 Jan 2017 16:09:14 +0100 (CET)

commit 49f35dc9bb53bafb4fced17fc3d62754620a7792
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon Jan 30 15:52:29 2017 +0100
Commit: Quentin Rameau <quinq_AT_fifth.space>
CommitDate: Mon Jan 30 16:07:06 2017 +0100

    [cc1] Use LOC variables for input
    
    It is a bad idea to use the values stored directly in input structures,
    because input structures disappear before the errors are printed, so it
    means that we can try to access through a NULL pointer.
    
    Small fix in newline() and addinput() clarification by quinq.

diff --git a/cc1/cc1.h b/cc1/cc1.h
index 1a9e3c5..e9eac6f 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -352,8 +352,8 @@ struct yystype {
 
 struct input {
         char flags;
- unsigned short nline;
- char *fname;
+ unsigned lineno;
+ char *filenam;
         FILE *fp;
         Symbol *hide;
         char *line, *begin, *p;
_AT_@ -406,6 +406,7 @@ extern int addinput(char *fname, Symbol *hide, char *buffer);
 extern void delinput(void);
 extern void setsafe(int type);
 extern void ilex(void);
+extern int setloc(char *fname, unsigned line);
 #define accept(t) ((yytoken == (t)) ? next() : 0)
 
 /* code.c */
_AT_@ -458,6 +459,8 @@ extern int onlycpp, onlyheader;
 extern unsigned curctx;
 extern Symbol *curfun, *zero, *one;
 extern char *infile, *outfile;
+unsigned lineno;
+char filenam[FILENAME_MAX];
 
 extern Type *voidtype, *pvoidtype, *booltype,
             *uchartype, *chartype, *schartype,
diff --git a/cc1/cpp.c b/cc1/cpp.c
index 30b59ea..bd65816 100644
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
_AT_@ -34,8 +34,8 @@ defdefine(char *macro, char *val, char *source)
         def = xmalloc(strlen(fmt) + strlen(macro) + strlen(val));
 
         sprintf(def, fmt, macro, val);
+ lineno = ++ncmdlines;
         addinput(source, &dummy, def);
- input->nline = ++ncmdlines;
         cpp();
         delinput();
 }
_AT_@ -254,11 +254,11 @@ expand(char *begin, Symbol *sym)
 
         macroname = sym->name;
         if (sym == symfile) {
- elen = sprintf(buffer, "\"%s\" ", input->fname);
+ elen = sprintf(buffer, "\"%s\" ", filenam);
                 goto substitute;
         }
         if (sym == symline) {
- elen = sprintf(buffer, "%d ", input->nline);
+ elen = sprintf(buffer, "%d ", lineno);
                 goto substitute;
         }
         if (!s)
_AT_@ -275,7 +275,7 @@ expand(char *begin, Symbol *sym)
 substitute:
         DBG("MACRO '%s' expanded to :'%s'", macroname, buffer);
         buffer[elen] = '\0';
- addinput(input->fname, sym, xstrdup(buffer));
+ addinput(filenam, sym, xstrdup(buffer));
 
         return 1;
 }
_AT_@ -448,7 +448,7 @@ includefile(char *dir, char *file, size_t filelen)
 static char *
 cwd(char *buf)
 {
- char *p, *s = input->fname;
+ char *p, *s = filenam;
         size_t len;
 
         if ((p = strrchr(s, '/')) == NULL)
_AT_@ -538,7 +538,7 @@ static void
 line(void)
 {
         long n;
- char *endp;
+ char *endp, *fname;
 
         if (cppoff)
                 return;
_AT_@ -552,20 +552,18 @@ line(void)
         }
 
         next();
- if (yytoken == EOFTOK)
- goto set_line;
-
- if (*yytext != '\"' || yylen == 1) {
- cpperror("second parameter of #line is not a valid filename");
- return;
+ if (yytoken == '\n') {
+ fname = NULL;
+ } else {
+ if (*yytext != '\"' || yylen == 1) {
+ cpperror("second parameter of #line is not a valid filename");
+ return;
+ }
+ fname = yylval.sym->u.s;
         }
-
- free(input->fname);
- input->fname = xstrdup(yylval.sym->u.s);
- next();
-
-set_line:
- input->nline = n - 1;
+ setloc(fname, n - 1);
+ if (yytoken != '\n')
+ next();
 }
 
 static void
diff --git a/cc1/error.c b/cc1/error.c
index 785e2ed..e60b785 100644
--- a/cc1/error.c
+++ b/cc1/error.c
_AT_@ -18,7 +18,7 @@ warn_error(int flag, char *fmt, va_list va)
         if (flag == 0)
                 return;
         fprintf(stderr, "%s:%u: %s: ",
- input->fname, input->nline,
+ filenam, lineno,
                (flag < 0) ? "error" : "warning");
         vfprintf(stderr, fmt, va);
         putc('\n', stderr);
diff --git a/cc1/lex.c b/cc1/lex.c
index dc17712..66612d6 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
_AT_@ -18,6 +18,8 @@ struct yystype yylval;
 char yytext[STRINGSIZ+3];
 unsigned short yylen;
 int lexmode = CCMODE;
+unsigned lineno;
+char filenam[FILENAME_MAX];
 
 int namespace = NS_IDEN;
 static int safe;
_AT_@ -69,17 +71,31 @@ ilex(void)
 }
 
 int
+setloc(char *fname, unsigned line)
+{
+ size_t len;
+
+ if ((len = strlen(fname)) >= FILENAME_MAX)
+ die("file name too long: '%s'", fname);
+ memcpy(filenam, fname, len);
+ filenam[len] = '\0';
+
+ free(input->filenam);
+ input->filenam = xstrdup(fname);
+ lineno = input->lineno = line;
+ return 1;
+}
+
+int
 addinput(char *fname, Symbol *hide, char *buffer)
 {
         FILE *fp;
- unsigned flags, nline = 0;
- Input *ip;
+ unsigned flags;
+ Input *newip, *curip = input;
 
         if (hide) {
                 /* this is a macro expansion */
                 fp = NULL;
- if (input)
- nline = input->nline;
                 if (hide->hide == UCHAR_MAX)
                         die("Too many macro expansions");
                 ++hide->hide;
_AT_@ -87,9 +103,9 @@ addinput(char *fname, Symbol *hide, char *buffer)
         } else if (fname) {
                 /* a new file */
                 if ((fp = fopen(fname, "r")) == NULL)
- return 0;
+ die("Error opening '%s': %s", fname, strerror(errno));
                 flags = IFILE;
- if (input && onlyheader)
+ if (curip && onlyheader)
                         printf("%s: %s\n", infile, fname);
         } else {
                 /* reading from stdin */
_AT_@ -98,23 +114,26 @@ addinput(char *fname, Symbol *hide, char *buffer)
                 flags = ISTDIN;
         }
 
- ip = xmalloc(sizeof(*ip));
+ newip = xmalloc(sizeof(*newip));
 
         if (!buffer) {
                 buffer = xmalloc(INPUTSIZ);
                 buffer[0] = '\0';
         }
 
- ip->p = ip->begin = ip->line = buffer;
- ip->fname = xstrdup(fname);
- ip->next = input;
- ip->fp = fp;
- ip->hide = hide;
- ip->nline = nline;
- ip->flags = flags;
- input = ip;
+ if (curip)
+ curip->lineno = lineno;
 
- return 1;
+ newip->p = newip->begin = newip->line = buffer;
+ newip->filenam = NULL;
+ newip->lineno = 0;
+ newip->next = curip;
+ newip->fp = fp;
+ newip->hide = hide;
+ newip->flags = flags;
+ input = newip;
+
+ return setloc(fname, (curip) ? curip->lineno : newip->lineno);
 }
 
 void
_AT_@ -127,7 +146,7 @@ delinput(void)
         case IFILE:
                 if (fclose(ip->fp))
                         die("error: failed to read from input file '%s'",
- ip->fname);
+ ip->filenam);
                 break;
         case IMACRO:
                 assert(hide->hide == 1);
_AT_@ -135,15 +154,19 @@ delinput(void)
                 break;
         }
         input = ip->next;
- free(ip->fname);
+ free(ip->filenam);
         free(ip->line);
+ if (input) {
+ lineno = input->lineno;
+ strcpy(filenam, input->filenam);
+ }
 }
 
 static void
 newline(void)
 {
- if (++input->nline == 0)
- die("error: input file '%s' too long", input->fname);
+ if (++lineno == 0)
+ die("error: input file '%s' too long", filenam);
 }
 
 /*
_AT_@ -280,15 +303,15 @@ repeat:
                 char *s;
 
                 putchar('\n');
- if (strcmp(file, input->fname)) {
- strcpy(file, input->fname);
+ if (strcmp(file, filenam)) {
+ strcpy(file, filenam);
                         s = "#line %u %s\n";
- } else if (nline+1 != input->nline) {
+ } else if (nline+1 != lineno) {
                         s = "#line %u\n";
                 } else {
                         s = "";
                 }
- nline = input->nline;
+ nline = lineno;
                 printf(s, nline, file);
         }
         return 1;
Received on Mon Jan 30 2017 - 16:09:14 CET

This archive was generated by hypermail 2.3.0 : Mon Jan 30 2017 - 16:12:21 CET