PR fortran/36160
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 4 Mar 2012 14:35:56 +0000 (14:35 +0000)
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 4 Mar 2012 14:35:56 +0000 (14:35 +0000)
* 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
gcc/fortran/error.c

index 97f91be..3a072e0 100644 (file)
@@ -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>
index aee9173..a8c2b63 100644 (file)
@@ -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 (' ');
     }