diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2019-04-22 17:30:20 +0200 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2019-04-23 18:29:10 +0200 |
commit | a992a3cb9e5687a303ca3eba2b3f7afaea91ec5b (patch) | |
tree | cacf527414d193bbb3ca188bdb31184bc92be072 | |
parent | 95d688957fccb504c7dc588be1bd72fe029b7460 (diff) | |
download | bison-a992a3cb9e5687a303ca3eba2b3f7afaea91ec5b.tar.gz |
diagnostics: don't try to quote special files
Based on a report by Todd Freed.
http://lists.gnu.org/archive/html/bug-bison/2019-04/msg00000.html
See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90034
* src/location.c (caret_info): Also track the file name.
(location_caret): Don't quote special files.
-rw-r--r-- | THANKS | 1 | ||||
-rw-r--r-- | src/location.c | 54 | ||||
-rw-r--r-- | tests/diagnostics.at | 22 |
3 files changed, 66 insertions, 11 deletions
@@ -170,6 +170,7 @@ Tim Josling tej@melbpc.org.au Tim Landscheidt tim@tim-landscheidt.de Tim Van Holder tim.van.holder@pandora.be Tobias Frost tobi@debian.org +Todd Freed todd.freed@gmail.com Tom Lane tgl@sss.pgh.pa.us Tom Tromey tromey@cygnus.com Tommy Nordgren tommy.nordgren@chello.se diff --git a/src/location.c b/src/location.c index c5ec8569..6d361c19 100644 --- a/src/location.c +++ b/src/location.c @@ -23,6 +23,8 @@ #include <mbswidth.h> #include <quotearg.h> +#include <stdio.h> /* fileno */ +#include <sys/stat.h> /* fstat */ #include "complain.h" #include "location.h" @@ -138,33 +140,63 @@ location_print (location loc, FILE *out) /* Persistent data used by location_caret to avoid reopening and rereading the same file all over for each error. */ -struct caret_info +static struct { FILE *source; + /* The last file we tried to open. If non NULL, but SOURCE is NULL, + it means this file is special and should not be quoted. */ + uniqstr file; size_t line; /* Offset in SOURCE where line LINE starts. */ size_t offset; -}; - -static struct caret_info caret_info = { NULL, 1, 0 }; +} caret_info; void caret_free () { if (caret_info.source) - fclose (caret_info.source); - caret_info.source = NULL; - caret_info.line = 1; - caret_info.offset = 0; + { + fclose (caret_info.source); + caret_info.source = NULL; + } } void location_caret (location loc, const char *style, FILE *out) { - if (! (caret_info.source - || (caret_info.source = fopen (loc.start.file, "r"))) - || loc.start.column == -1 || loc.start.line == -1) + if (loc.start.column == -1 || loc.start.line == -1) return; + /* If a different source than before, close and let the rest open + the new one. */ + if (caret_info.file && caret_info.file != loc.start.file) + { + caret_free (); + caret_info.file = NULL; + } + if (!caret_info.file) + { + caret_info.file = loc.start.file; + if ((caret_info.source = fopen (caret_info.file, "r"))) + { + /* If the file is not regular (imagine #line 1 "/dev/stdin" + in the input file for instance), don't try to quote the + source. Keep caret_info.file set so that we don't try to + open it again, but leave caret_info.source NULL so that + we don't try to quote it. */ + struct stat buf; + if (fstat (fileno (caret_info.source), &buf) == 0 + && buf.st_mode & S_IFREG) + { + caret_info.line = 1; + caret_info.offset = 0; + } + else + caret_free (); + } + } + if (!caret_info.source) + return; + /* If the line we want to quote is seekable (the same line as the previous location), just seek it. If it was a previous line, we lost track of it, diff --git a/tests/diagnostics.at b/tests/diagnostics.at index add313e0..8fc3aa66 100644 --- a/tests/diagnostics.at +++ b/tests/diagnostics.at @@ -161,5 +161,27 @@ input.y:18.4-17: <warning>warning:</warning> empty rule without %empty [<warning ]]) +## -------------- ## +## Special files. ## +## -------------- ## + +# Don't try to quote special files. +# http://lists.gnu.org/archive/html/bug-bison/2019-04/msg00000.html +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90034 + +AT_TEST([[Special files]], +[[%% +exp: a b +a: {} +#line 1 "/dev/stdout" +b: {} +]], +[[input.y:11.4-5: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>] + 11 | a: <warning>{}</warning> + | <warning>^~</warning> +/dev/stdout:1.4-5: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>] +]]) + + m4_popdef([AT_TEST]) |