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
This commit is contained in:
Francois-Xavier Coudert 2012-03-04 14:35:56 +00:00 committed by François-Xavier Coudert
parent c8191119d6
commit a5d6c7540a
2 changed files with 56 additions and 11 deletions

View 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> 2012-03-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* module.c (gfc_use_module): Improve error message some more. * module.c (gfc_use_module): Improve error message some more.

View 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) print_wide_char_into_buffer (gfc_char_t c, char *buf)
{ {
static const char xdigit[16] = { '0', '1', '2', '3', '4', '5', '6', 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[1] = '\0';
buf[0] = (unsigned char) c; buf[0] = (unsigned char) c;
return 1;
} }
else if (c < ((gfc_char_t) 1 << 8)) 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[1] = 'x';
buf[0] = '\\'; buf[0] = '\\';
return 4;
} }
else if (c < ((gfc_char_t) 1 << 16)) 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[1] = 'u';
buf[0] = '\\'; buf[0] = '\\';
return 6;
} }
else else
{ {
@ -231,6 +266,7 @@ print_wide_char_into_buffer (gfc_char_t c, char *buf)
buf[1] = 'U'; buf[1] = 'U';
buf[0] = '\\'; 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 show up on the terminal. Tabs are converted to spaces, and
nonprintable characters are converted to a "\xNN" sequence. */ 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]); p = &(lb->line[offset]);
i = gfc_wide_strlen (p); i = gfc_wide_display_length (p);
if (i > terminal_width) if (i > terminal_width)
i = terminal_width - 1; i = terminal_width - 1;
for (; i > 0; i--) while (i > 0)
{ {
static char buffer[11]; static char buffer[11];
@ -343,7 +375,7 @@ show_locus (locus *loc, int c1, int c2)
if (c == '\t') if (c == '\t')
c = ' '; c = ' ';
print_wide_char_into_buffer (c, buffer); i -= print_wide_char_into_buffer (c, buffer);
error_string (buffer); error_string (buffer);
} }
@ -356,13 +388,18 @@ show_locus (locus *loc, int c1, int c2)
c1 -= offset; c1 -= offset;
c2 -= offset; c2 -= offset;
p = &(lb->line[offset]);
for (i = 0; i <= cmax; i++) for (i = 0; i <= cmax; i++)
{ {
int spaces, j;
spaces = gfc_widechar_display_length (*p++);
if (i == c1) if (i == c1)
error_char ('1'); error_char ('1'), spaces--;
else if (i == c2) else if (i == c2)
error_char ('2'); error_char ('2'), spaces--;
else
for (j = 0; j < spaces; j++)
error_char (' '); error_char (' ');
} }