summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2019-04-22 17:30:20 +0200
committerAkim Demaille <akim.demaille@gmail.com>2019-04-23 18:29:10 +0200
commita992a3cb9e5687a303ca3eba2b3f7afaea91ec5b (patch)
treecacf527414d193bbb3ca188bdb31184bc92be072
parent95d688957fccb504c7dc588be1bd72fe029b7460 (diff)
downloadbison-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--THANKS1
-rw-r--r--src/location.c54
-rw-r--r--tests/diagnostics.at22
3 files changed, 66 insertions, 11 deletions
diff --git a/THANKS b/THANKS
index 3a8baf3f..53a357ae 100644
--- a/THANKS
+++ b/THANKS
@@ -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])