diff options
Diffstat (limited to 'gcc/fortran/error.c')
-rw-r--r-- | gcc/fortran/error.c | 90 |
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'); |