summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2019-04-27 16:29:07 +0200
committerAkim Demaille <akim.demaille@gmail.com>2019-04-27 18:27:04 +0200
commit386cf2508891ebd2338b83b084bfabe469f510a9 (patch)
tree6644ee0c9a6609fded62b566017d8281aabc4102 /src
parenta514c51e555c7c5ee962a84eb571c2fdfa49a1ec (diff)
downloadbison-386cf2508891ebd2338b83b084bfabe469f510a9.tar.gz
diagnostics: give m4 precise locations
Currently we pass only the columns based on the screen-width, which is important for the carets. But we don't pass the bytes-based columns, which is important for the colors. Pass both. * src/muscle-tab.c (muscle_boundary_grow): Also pass the byte-based column. * src/location.c (location_caret): Clarify. (boundary_set_from_string): Adjust to the new format. * tests/diagnostics.at (Tabulations and multibyte characters from M4): New.
Diffstat (limited to 'src')
-rw-r--r--src/location.c46
-rw-r--r--src/location.h5
-rw-r--r--src/muscle-tab.c2
3 files changed, 33 insertions, 20 deletions
diff --git a/src/location.c b/src/location.c
index e2299c2e..2e8b62b8 100644
--- a/src/location.c
+++ b/src/location.c
@@ -238,8 +238,8 @@ location_caret (location loc, const char *style, FILE *out)
int c = getc (caret_info.source);
if (c != EOF)
{
- /* Quote the file (at most first line in the case of multiline
- location). Indent by a single column. */
+ /* Quote the file (at most the first line in the case of
+ multiline locations). */
fprintf (out, "%5d | ", loc.start.line);
bool single_line = loc.start.line == loc.end.line;
/* Consider that single point location (with equal boundaries)
@@ -269,9 +269,9 @@ location_caret (location loc, const char *style, FILE *out)
putc ('^', out);
/* Underlining a multiline location ends with the first
line. */
- int len = loc.start.line != loc.end.line
- ? ftell (caret_info.source) - caret_info.offset
- : loc.end.column;
+ int len = single_line
+ ? loc.end.column
+ : ftell (caret_info.source) - caret_info.offset;
for (int i = loc.start.column + 1; i < len; ++i)
putc ('~', out);
end_use_class (style, out);
@@ -289,17 +289,29 @@ location_empty (location loc)
}
void
-boundary_set_from_string (boundary *bound, char *loc_str)
+boundary_set_from_string (boundary *bound, char *str)
{
- /* Must search in reverse since the file name field may
- * contain '.' or ':'. */
- char *delim = strrchr (loc_str, '.');
- aver (delim);
- *delim = '\0';
- bound->byte = bound->column = atoi (delim+1);
- delim = strrchr (loc_str, ':');
- aver (delim);
- *delim = '\0';
- bound->line = atoi (delim+1);
- bound->file = uniqstr_new (loc_str);
+ /* Must search in reverse since the file name field may contain '.'
+ or ':'. */
+ char *at = strrchr (str, '@');
+ if (at)
+ {
+ *at = '\0';
+ bound->byte = atoi (at+1);
+ }
+ {
+ char *dot = strrchr (str, '.');
+ aver (dot);
+ *dot = '\0';
+ bound->column = atoi (dot+1);
+ if (!at)
+ bound->byte = bound->column;
+ }
+ {
+ char *colon = strrchr (str, ':');
+ aver (colon);
+ *colon = '\0';
+ bound->line = atoi (colon+1);
+ }
+ bound->file = uniqstr_new (str);
}
diff --git a/src/location.h b/src/location.h
index 7e473824..2539f27f 100644
--- a/src/location.h
+++ b/src/location.h
@@ -135,7 +135,8 @@ location_cmp (location a, location b)
/* Whether this is the empty location. */
bool location_empty (location loc);
-/* LOC_STR must be formatted as 'file:line.column', it will be modified. */
-void boundary_set_from_string (boundary *bound, char *loc_str);
+/* STR must be formatted as 'file:line.column@byte' or 'file:line.column',
+ it will be modified. */
+void boundary_set_from_string (boundary *bound, char *str);
#endif /* ! defined LOCATION_H_ */
diff --git a/src/muscle-tab.c b/src/muscle-tab.c
index cd4beeb2..fbb80fc2 100644
--- a/src/muscle-tab.c
+++ b/src/muscle-tab.c
@@ -275,7 +275,7 @@ muscle_boundary_grow (char const *key, boundary bound)
{
obstack_sgrow (&muscle_obstack, "[[");
obstack_escape (&muscle_obstack, bound.file);
- obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column);
+ obstack_printf (&muscle_obstack, ":%d.%d@@%d]]", bound.line, bound.column, bound.byte);
char const *extension = obstack_finish0 (&muscle_obstack);
muscle_grow (key, extension, "", "");
obstack_free (&muscle_obstack, extension);