diff options
author | Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2012-03-04 14:35:56 +0000 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2012-03-04 14:35:56 +0000 |
commit | a5d6c7540ae44bc8fb2f4ca2aba5f16420b574a2 (patch) | |
tree | 82c0a8937026e7006001e06651a39cd00f27d7a2 | |
parent | c8191119d6481dd0e3ba4fcf2bbcbc662e0c278a (diff) | |
download | gcc-a5d6c7540ae44bc8fb2f4ca2aba5f16420b574a2.zip gcc-a5d6c7540ae44bc8fb2f4ca2aba5f16420b574a2.tar.gz gcc-a5d6c7540ae44bc8fb2f4ca2aba5f16420b574a2.tar.bz2 |
re PR fortran/36160 (show_locus doesn't deal well with wide characters)
PR fortran/36160
* error.c (gfc_widechar_display_length, gfc_wide_display_length):
New functions.
(print_wide_char_into_buffer): Return length written.
(show_locus): Fix locus displayed when wide characters are present.
From-SVN: r184884
-rw-r--r-- | gcc/fortran/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/fortran/error.c | 59 |
2 files changed, 56 insertions, 11 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 97f91be..3a072e0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,13 @@ 2012-03-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + PR fortran/36160 + * error.c (gfc_widechar_display_length, gfc_wide_display_length): + New functions. + (print_wide_char_into_buffer): Return length written. + (show_locus): Fix locus displayed when wide characters are present. + +2012-03-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + * module.c (gfc_use_module): Improve error message some more. 2012-03-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c index aee9173..a8c2b63 100644 --- a/gcc/fortran/error.c +++ b/gcc/fortran/error.c @@ -175,7 +175,39 @@ error_integer (long int i) } -static void +static size_t +gfc_widechar_display_length (gfc_char_t c) +{ + if (gfc_wide_is_printable (c)) + /* Simple ASCII character */ + return 1; + else if (c < ((gfc_char_t) 1 << 8)) + /* Displayed as \x?? */ + return 4; + else if (c < ((gfc_char_t) 1 << 16)) + /* Displayed as \u???? */ + return 6; + else + /* Displayed as \U???????? */ + return 10; +} + + +/* Length of the ASCII representation of the wide string, escaping wide + characters as print_wide_char_into_buffer() does. */ + +static size_t +gfc_wide_display_length (const gfc_char_t *str) +{ + size_t i, len; + + for (i = 0, len = 0; str[i]; i++) + len += gfc_widechar_display_length (str[i]); + + return len; +} + +static int print_wide_char_into_buffer (gfc_char_t c, char *buf) { static const char xdigit[16] = { '0', '1', '2', '3', '4', '5', '6', @@ -185,6 +217,7 @@ print_wide_char_into_buffer (gfc_char_t c, char *buf) { buf[1] = '\0'; buf[0] = (unsigned char) c; + return 1; } else if (c < ((gfc_char_t) 1 << 8)) { @@ -195,6 +228,7 @@ print_wide_char_into_buffer (gfc_char_t c, char *buf) buf[1] = 'x'; buf[0] = '\\'; + return 4; } else if (c < ((gfc_char_t) 1 << 16)) { @@ -209,6 +243,7 @@ print_wide_char_into_buffer (gfc_char_t c, char *buf) buf[1] = 'u'; buf[0] = '\\'; + return 6; } else { @@ -231,6 +266,7 @@ print_wide_char_into_buffer (gfc_char_t c, char *buf) buf[1] = 'U'; buf[0] = '\\'; + return 10; } } @@ -326,16 +362,12 @@ show_locus (locus *loc, int c1, int c2) show up on the terminal. Tabs are converted to spaces, and nonprintable characters are converted to a "\xNN" sequence. */ - /* TODO: Although setting i to the terminal width is clever, it fails - to work correctly when nonprintable characters exist. A better - solution should be found. */ - p = &(lb->line[offset]); - i = gfc_wide_strlen (p); + i = gfc_wide_display_length (p); if (i > terminal_width) i = terminal_width - 1; - for (; i > 0; i--) + while (i > 0) { static char buffer[11]; @@ -343,7 +375,7 @@ show_locus (locus *loc, int c1, int c2) if (c == '\t') c = ' '; - print_wide_char_into_buffer (c, buffer); + i -= print_wide_char_into_buffer (c, buffer); error_string (buffer); } @@ -356,13 +388,18 @@ show_locus (locus *loc, int c1, int c2) c1 -= offset; c2 -= offset; + p = &(lb->line[offset]); for (i = 0; i <= cmax; i++) { + int spaces, j; + spaces = gfc_widechar_display_length (*p++); + if (i == c1) - error_char ('1'); + error_char ('1'), spaces--; else if (i == c2) - error_char ('2'); - else + error_char ('2'), spaces--; + + for (j = 0; j < spaces; j++) error_char (' '); } |