summaryrefslogtreecommitdiff
path: root/gcc/fortran/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/error.c')
-rw-r--r--gcc/fortran/error.c90
1 files changed, 69 insertions, 21 deletions
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 40eccde5adf..a9cbe9ef5f2 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -152,6 +152,70 @@ error_integer (long int i)
}
+static char wide_char_print_buffer[11];
+
+const char *
+gfc_print_wide_char (gfc_char_t c)
+{
+ static const char xdigit[16] = { '0', '1', '2', '3', '4', '5', '6',
+ '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ char *buf = wide_char_print_buffer;
+
+ if (gfc_wide_is_printable (c))
+ {
+ buf[1] = '\0';
+ buf[0] = (unsigned char) c;
+ }
+ else if (c < ((gfc_char_t) 1 << 8))
+ {
+ buf[4] = '\0';
+ buf[3] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[2] = xdigit[c & 0x0F];
+
+ buf[1] = '\\';
+ buf[0] = 'x';
+ }
+ else if (c < ((gfc_char_t) 1 << 16))
+ {
+ buf[6] = '\0';
+ buf[5] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[4] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[3] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[2] = xdigit[c & 0x0F];
+
+ buf[1] = '\\';
+ buf[0] = 'u';
+ }
+ else
+ {
+ buf[10] = '\0';
+ buf[9] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[8] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[7] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[6] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[5] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[4] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[3] = xdigit[c & 0x0F];
+ c = c >> 4;
+ buf[2] = xdigit[c & 0x0F];
+
+ buf[1] = '\\';
+ buf[0] = 'U';
+ }
+
+ return buf;
+}
+
/* Show the file, where it was included, and the source line, give a
locus. Calls error_printf() recursively, but the recursion is at
most one level deep. */
@@ -163,8 +227,8 @@ show_locus (locus *loc, int c1, int c2)
{
gfc_linebuf *lb;
gfc_file *f;
- char c, *p;
- int i, m, offset, cmax;
+ gfc_char_t c, *p;
+ int i, offset, cmax;
/* TODO: Either limit the total length and number of included files
displayed or add buffering of arbitrary number of characters in
@@ -246,8 +310,8 @@ show_locus (locus *loc, int c1, int c2)
to work correctly when nonprintable characters exist. A better
solution should be found. */
- p = lb->line + offset;
- i = strlen (p);
+ p = &(lb->line[offset]);
+ i = gfc_wide_strlen (p);
if (i > terminal_width)
i = terminal_width - 1;
@@ -257,23 +321,7 @@ show_locus (locus *loc, int c1, int c2)
if (c == '\t')
c = ' ';
- if (ISPRINT (c))
- error_char (c);
- else
- {
- error_char ('\\');
- error_char ('x');
-
- m = ((c >> 4) & 0x0F) + '0';
- if (m > '9')
- m += 'A' - '9' - 1;
- error_char (m);
-
- m = (c & 0x0F) + '0';
- if (m > '9')
- m += 'A' - '9' - 1;
- error_char (m);
- }
+ error_string (gfc_print_wide_char (c));
}
error_char ('\n');