aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>2012-03-04 14:35:56 +0000
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>2012-03-04 14:35:56 +0000
commita5d6c7540ae44bc8fb2f4ca2aba5f16420b574a2 (patch)
tree82c0a8937026e7006001e06651a39cd00f27d7a2
parentc8191119d6481dd0e3ba4fcf2bbcbc662e0c278a (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/fortran/error.c59
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 (' ');
}