diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-04-30 15:01:56 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-04-30 15:01:56 +0000 |
commit | 7761dfbee17cb7a4bb3539a381bec63d31af7c28 (patch) | |
tree | e583063e82b23bf43e882069fe4de7790d5e078d /gcc/input.c | |
parent | b6e33d73d8aa1b7965d6b2bf08b5bbd673e63284 (diff) |
Use char_span for return type of location_get_source_line
location_get_source_line returns a const char * that isn't 0-terminated,
writing back a length through an int * param.
This is error-prone, as all call-sites have to take into account the
lack of 0-termination, and respect the length of the buffer.
It's cleaner to bundle together this pointer+length state into a class,
so this patch does so, reusing the "char_span" class that I introduced
in r250187 (as part of the fix for PR c/81405).
The patch also adds assertions to all access to the char_span.
gcc/c-family/ChangeLog:
* c-format.c (get_corrected_substring): Update for
location_get_source_line returning a char_span. Use a char_span
when handling the prefix of the correction.
* c-indentation.c (get_visual_column): Update for
location_get_source_line returning a char_span.
(get_first_nws_vis_column): Likewise.
gcc/ChangeLog:
* diagnostic-show-locus.c (layout::layout): Update for
location_get_source_line returning a char_span.
(struct char_span): Move to input.h.
(struct correction): Update for fields in char_span becoming
private.
(struct source_line): Update for location_get_source_line
returning a char_span.
(layout::print_line): Likewise.
* edit-context.c (edited_file::print_content): Likewise.
(edited_file::print_diff_hunk): Likewise.
(edited_file::print_run_of_changed_lines): Likewise.
(edited_file::get_num_lines): Likewise.
(edited_line::edited_line): Likewise.
* final.c (asm_show_source): Likewise.
* input.c (location_get_source_line): Convert return type
from const char * to char_span, losing the final "line_len"
param.
(dump_location_info): Update for the above.
(get_substring_ranges_for_loc): Likewise. Use a char_span
when handling the literal within the line.
(test_reading_source_line): Update for location_get_source_line
returning a char_span.
* input.h (class char_span): Move here from
diagnostic-show-locus.c, converting from a struct to a class.
Make data members private.
(char_span::operator bool): New.
(char_span::length): New.
(char_span::get_buffer): New.
(char_span::operator[]): New.
(char_span::subspan): Make const.
(char_span::xstrdup): New.
(location_get_source_line): Convert return type from const char *
to char_span, losing the final "line_size" param.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(test_show_locus): Update for location_get_source_line returning a
char_span. Use char_span for handling words in the
"test_many_nested_locations" fix-it example.
From-SVN: r259768
Diffstat (limited to 'gcc/input.c')
-rw-r--r-- | gcc/input.c | 76 |
1 files changed, 35 insertions, 41 deletions
diff --git a/gcc/input.c b/gcc/input.c index b6675768722..d65a82dc26e 100644 --- a/gcc/input.c +++ b/gcc/input.c @@ -741,29 +741,27 @@ read_line_num (fcache *c, size_t line_num, The line is not nul-terminated. The returned pointer is only valid until the next call of location_get_source_line. Note that the line can contain several null characters, - so LINE_LEN, if non-null, points to the actual length of the line. - If the function fails, NULL is returned. */ + so the returned value's length has the actual length of the line. + If the function fails, a NULL char_span is returned. */ -const char * -location_get_source_line (const char *file_path, int line, - int *line_len) +char_span +location_get_source_line (const char *file_path, int line) { char *buffer = NULL; ssize_t len; if (line == 0) - return NULL; + return char_span (NULL, 0); fcache *c = lookup_or_add_file_to_cache_tab (file_path); if (c == NULL) - return NULL; + return char_span (NULL, 0); bool read = read_line_num (c, line, &buffer, &len); + if (!read) + return char_span (NULL, 0); - if (read && line_len) - *line_len = len; - - return read ? buffer : NULL; + return char_span (buffer, len); } /* Determine if FILE_PATH missing a trailing newline on its final line. @@ -1121,25 +1119,23 @@ dump_location_info (FILE *stream) { /* Beginning of a new source line: draw the line. */ - int line_size; - const char *line_text = location_get_source_line (exploc.file, - exploc.line, - &line_size); + char_span line_text = location_get_source_line (exploc.file, + exploc.line); if (!line_text) break; fprintf (stream, "%s:%3i|loc:%5i|%.*s\n", exploc.file, exploc.line, loc, - line_size, line_text); + (int)line_text.length (), line_text.get_buffer ()); /* "loc" is at column 0, which means "the whole line". Render the locations *within* the line, by underlining it, showing the source_location numeric values at each column. */ - int max_col = (1 << map->m_column_and_range_bits) - 1; - if (max_col > line_size) - max_col = line_size + 1; + size_t max_col = (1 << map->m_column_and_range_bits) - 1; + if (max_col > line_text.length ()) + max_col = line_text.length () + 1; int indent = 14 + strlen (exploc.file); @@ -1426,28 +1422,27 @@ get_substring_ranges_for_loc (cpp_reader *pfile, if (start.column > finish.column) return "range endpoints are reversed"; - int line_width; - const char *line = location_get_source_line (start.file, start.line, - &line_width); - if (line == NULL) + char_span line = location_get_source_line (start.file, start.line); + if (!line) return "unable to read source line"; /* Determine the location of the literal (including quotes and leading prefix chars, such as the 'u' in a u"" token). */ - const char *literal = line + start.column - 1; - int literal_length = finish.column - start.column + 1; + size_t literal_length = finish.column - start.column + 1; /* Ensure that we don't crash if we got the wrong location. */ - if (line_width < (start.column - 1 + literal_length)) + if (line.length () < (start.column - 1 + literal_length)) return "line is not wide enough"; + char_span literal = line.subspan (start.column - 1, literal_length); + cpp_string from; from.len = literal_length; /* Make a copy of the literal, to avoid having to rely on the lifetime of the copy of the line within the cache. This will be released by the auto_cpp_string_vec dtor. */ - from.text = XDUPVEC (unsigned char, literal, literal_length); + from.text = (unsigned char *)literal.xstrdup (); strs.safe_push (from); /* For very long lines, a new linemap could have started @@ -1908,24 +1903,23 @@ test_reading_source_line () "This is the 3rd line"); /* Read back a specific line from the tempfile. */ - int line_size; - const char *source_line = location_get_source_line (tmp.get_filename (), - 3, &line_size); - ASSERT_TRUE (source_line != NULL); - ASSERT_EQ (20, line_size); + char_span source_line = location_get_source_line (tmp.get_filename (), 3); + ASSERT_TRUE (source_line); + ASSERT_TRUE (source_line.get_buffer () != NULL); + ASSERT_EQ (20, source_line.length ()); ASSERT_TRUE (!strncmp ("This is the 3rd line", - source_line, line_size)); + source_line.get_buffer (), source_line.length ())); - source_line = location_get_source_line (tmp.get_filename (), - 2, &line_size); - ASSERT_TRUE (source_line != NULL); - ASSERT_EQ (21, line_size); + source_line = location_get_source_line (tmp.get_filename (), 2); + ASSERT_TRUE (source_line); + ASSERT_TRUE (source_line.get_buffer () != NULL); + ASSERT_EQ (21, source_line.length ()); ASSERT_TRUE (!strncmp ("This is the test text", - source_line, line_size)); + source_line.get_buffer (), source_line.length ())); - source_line = location_get_source_line (tmp.get_filename (), - 4, &line_size); - ASSERT_TRUE (source_line == NULL); + source_line = location_get_source_line (tmp.get_filename (), 4); + ASSERT_FALSE (source_line); + ASSERT_TRUE (source_line.get_buffer () == NULL); } /* Tests of lexing. */ |