diff options
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/diagnostic.c | 17 | ||||
-rw-r--r-- | gcc/input.c | 115 | ||||
-rw-r--r-- | gcc/input.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/cpp/warning-zero-in-literals-1.c | bin | 0 -> 240 bytes |
6 files changed, 127 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50464673d60..9192b780952 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2013-11-06 Dodji Seketeli <dodji@redhat.com> + + preprocessor/58580 + * input.h (location_get_source_line): Take an additional line_size + parameter. + * input.c (get_line): New static function definition. + (read_line): Take an additional line_length output parameter to be + set to the size of the line. Use the new get_line function do the + actual line reading. + (location_get_source_line): Take an additional output line_len + parameter. Update the use of read_line to pass it the line_len + parameter. + * diagnostic.c (adjust_line): Take an additional input parameter + for the length of the line, rather than calculating it with + strlen. + (diagnostic_show_locus): Adjust the use of + location_get_source_line and adjust_line with respect to their new + signature. While displaying a line now, do not stop at the first + null byte. Rather, display the zero byte as a space and keep + going until we reach the size of the line. + 2013-11-06 Eric Botcazou <ebotcazou@adacore.com> * config/i386/i386.c (ix86_expand_prologue): Optimize stack checking for diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 36094a19c9a..e0c5d9dc79a 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -259,12 +259,13 @@ diagnostic_build_prefix (diagnostic_context *context, MAX_WIDTH by some margin, then adjust the start of the line such that the COLUMN is smaller than MAX_WIDTH minus the margin. The margin is either 10 characters or the difference between the column - and the length of the line, whatever is smaller. */ + and the length of the line, whatever is smaller. The length of + LINE is given by LINE_WIDTH. */ static const char * -adjust_line (const char *line, int max_width, int *column_p) +adjust_line (const char *line, int line_width, + int max_width, int *column_p) { int right_margin = 10; - int line_width = strlen (line); int column = *column_p; right_margin = MIN (line_width - column, right_margin); @@ -284,6 +285,7 @@ diagnostic_show_locus (diagnostic_context * context, const diagnostic_info *diagnostic) { const char *line; + int line_width; char *buffer; expanded_location s; int max_width; @@ -297,22 +299,25 @@ diagnostic_show_locus (diagnostic_context * context, context->last_location = diagnostic->location; s = expand_location_to_spelling_point (diagnostic->location); - line = location_get_source_line (s); + line = location_get_source_line (s, &line_width); if (line == NULL) return; max_width = context->caret_max_width; - line = adjust_line (line, max_width, &(s.column)); + line = adjust_line (line, line_width, max_width, &(s.column)); pp_newline (context->printer); saved_prefix = pp_get_prefix (context->printer); pp_set_prefix (context->printer, NULL); pp_space (context->printer); - while (max_width > 0 && *line != '\0') + while (max_width > 0 && line_width > 0) { char c = *line == '\t' ? ' ' : *line; + if (c == '\0') + c = ' '; pp_character (context->printer, c); max_width--; + line_width--; line++; } pp_newline (context->printer); diff --git a/gcc/input.c b/gcc/input.c index a141a92cac3..cb3a0a09f33 100644 --- a/gcc/input.c +++ b/gcc/input.c @@ -87,53 +87,114 @@ expand_location_1 (source_location loc, return xloc; } -/* Reads one line from file into a static buffer. */ -static const char * -read_line (FILE *file) +/* This function reads a line that might contain bytes whose value is + zero. It returns the number of bytes read. The 'end-of-line' + character found at the end of the line is not contained in the + returned buffer. Note that this function has been adapted from + getline() and _IO_getdelim() GNU C library functions. It's been + duplicated here because the getline() function is not necessarily + present on all platforms. + + LINEPTR points to a buffer that is to contain the line read. + + N points to the size of the the LINEPTR buffer. + + FP points to the file to consider. */ + +static ssize_t +get_line (char **lineptr, size_t *n, FILE *fp) { - static char *string; - static size_t string_len; - size_t pos = 0; - char *ptr; + ssize_t cur_len = 0, len; + char buf[16384]; + + if (lineptr == NULL || n == NULL) + return -1; - if (!string_len) + if (*lineptr == NULL || *n == 0) { - string_len = 200; - string = XNEWVEC (char, string_len); + *n = 120; + *lineptr = XNEWVEC (char, *n); } - while ((ptr = fgets (string + pos, string_len - pos, file))) - { - size_t len = strlen (string + pos); + len = fread (buf, 1, sizeof buf, fp); + if (ferror (fp)) + return -1; - if (string[pos + len - 1] == '\n') + for (;;) + { + size_t needed; + char *t = (char*) memchr (buf, '\n', len); + if (t != NULL) len = (t - buf); + if (__builtin_expect (len >= SSIZE_MAX - cur_len, 0)) + return -1; + needed = cur_len + len + 1; + if (needed > *n) { - string[pos + len - 1] = 0; - return string; + char *new_lineptr; + if (needed < 2 * *n) + needed = 2 * *n; + new_lineptr = XRESIZEVEC (char, *lineptr, needed); + *lineptr = new_lineptr; + *n = needed; } - pos += len; - string = XRESIZEVEC (char, string, string_len * 2); - string_len *= 2; + memcpy (*lineptr + cur_len, buf, len); + cur_len += len; + if (t != NULL) + break; + len = fread (buf, 1, sizeof buf, fp); + if (ferror (fp)) + return -1; + if (len == 0) + break; } - - return pos ? string : NULL; + + if (cur_len) + (*lineptr)[cur_len] = '\0'; + return cur_len; +} + +/* Reads one line from FILE into a static buffer. If LINE_LENGTH is + *non-null LINE_LENGTH, will be set by this function to the length of + *the returned line. Note that the returned line can contain several + *zero bytes. Also note that the returned string is allocated in + *static storage that is going to be re-used by subsequent invocations + *of read_line. */ +static const char * +read_line (FILE *file, int *line_length) +{ + static char *string; + static size_t string_len; + int len; + + len = get_line (&string, &string_len, file); + if (line_length) + *line_length = len; + return len ? string : NULL; } /* Return the physical source line that corresponds to xloc in a buffer that is statically allocated. The newline is replaced by - the null character. */ + the null character. Note that the line can contain several null + characters, so LINE_LEN, if non-null, points to the actual length + of the line. */ const char * -location_get_source_line (expanded_location xloc) +location_get_source_line (expanded_location xloc, + int *line_len) { - const char *buffer; - int lines = 1; + const char *buffer = NULL, *ptr; + int lines = 0, len = 0; FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL; if (!stream) return NULL; - while ((buffer = read_line (stream)) && lines < xloc.line) - lines++; + while ((ptr = read_line (stream, &len)) && lines < xloc.line) + { + buffer = ptr; + lines++; + if (line_len) + *line_len = len; + } fclose (stream); return buffer; diff --git a/gcc/input.h b/gcc/input.h index 8fdc7b28d92..128e28cd942 100644 --- a/gcc/input.h +++ b/gcc/input.h @@ -37,7 +37,8 @@ extern char builtins_location_check[(BUILTINS_LOCATION < RESERVED_LOCATION_COUNT) ? 1 : -1]; extern expanded_location expand_location (source_location); -extern const char *location_get_source_line (expanded_location xloc); +extern const char *location_get_source_line (expanded_location xloc, + int *line_size); extern expanded_location expand_location_to_spelling_point (source_location); extern source_location expansion_point_location_if_in_system_header (source_location); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8460edb8d0a..b93ee34822a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-06 Dodji Seketeli <dodji@redhat.com> + + preprocessor/58580 + * c-c++-common/cpp/warning-zero-in-literals-1.c: New test file. + 2013-11-06 Christian Bruel <christian.bruel@st.com> * gcc.target/sh/strlen.c: New test. diff --git a/gcc/testsuite/c-c++-common/cpp/warning-zero-in-literals-1.c b/gcc/testsuite/c-c++-common/cpp/warning-zero-in-literals-1.c Binary files differnew file mode 100644 index 00000000000..ff2ed962ac9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/warning-zero-in-literals-1.c |