From eb087c9e2e2e0b40de9b117862eeeb4265185d91 Mon Sep 17 00:00:00 2001 From: fxcoudert Date: Sun, 4 Mar 2012 14:35:56 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184884 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/fortran/ChangeLog | 8 +++++++ gcc/fortran/error.c | 59 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 97f91be914e..3a072e0a9b0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,13 @@ 2012-03-04 Francois-Xavier Coudert + 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 + * module.c (gfc_use_module): Improve error message some more. 2012-03-03 Francois-Xavier Coudert diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c index aee9173b669..a8c2b63a6d9 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 (' '); } -- 2.11.4.GIT