]> gcc.gnu.org Git - gcc.git/commitdiff
re PR fortran/36160 (show_locus doesn't deal well with wide characters)
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Sun, 4 Mar 2012 14:35:56 +0000 (14:35 +0000)
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Sun, 4 Mar 2012 14:35:56 +0000 (14:35 +0000)
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

gcc/fortran/ChangeLog
gcc/fortran/error.c

index 97f91be914ee1a436482d60574b9fe49b910e128..3a072e0a9b0155366b2c24630a5e767ab14bac75 100644 (file)
@@ -1,3 +1,11 @@
+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.
index aee9173b66973844248229666edc7a4a66cdd4d5..a8c2b63a6d989b83b307c3b6866db2ca48879e86 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 (' ');
     }
 
This page took 0.06849 seconds and 5 git commands to generate.