summaryrefslogtreecommitdiff
path: root/gdb/c-lang.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2011-06-29 15:32:39 +0000
committerTom Tromey <tromey@redhat.com>2011-06-29 15:32:39 +0000
commit8e0e6d6c674c223d9ecbc106ce946a1c59c062d2 (patch)
treeffd4e5dcc8d4329b927ee6d533f3df3595bcd39a /gdb/c-lang.c
parent721bbfcf65dfcf013f990b453a71942e25f59ec5 (diff)
downloadgdb-8e0e6d6c674c223d9ecbc106ce946a1c59c062d2.tar.gz
gdb
PR fortran/10036: * valprint.h (generic_emit_char, generic_printstr): Declare. * valprint.c (wchar_printable, append_string_as_wide) (print_wchar): Move from c-lang.c. (generic_emit_char): New function; mostly taken from c_emit_char. (generic_printstr): New function; mostly taken from c_printstr. * f-valprint.c (f_val_print) <TYPE_CODE_ARRAY>: Handle strings represented as arrays. <TYPE_CODE_CHAR>: Treat as TYPE_CODE_INT; recognize as character type. * f-typeprint.c (f_type_print_base) <TYPE_CODE_CHAR>: Treat identically to TYPE_CODE_INT. * f-lang.c (f_get_encoding): New function. (f_emit_char): Use generic_emit_char. (f_printchar): Replace comment. (f_printstr): Use generic_printstr. * dwarf2read.c (read_base_type) <DW_ATE_unsigned>: Handle Fortran "character" types specially. <DW_ATE_signed_char, DW_ATE_unsigned_char>: Make TYPE_CODE_CHAR for Fortran. * c-lang.c (wchar_printable, append_string_as_wide, print_wchar): Move to valprint.c (c_emit_char): Call generic_emit_char. (c_printstr): Call generic_printstr. gdb/testsuite * gdb.fortran/charset.exp: New file. * gdb.fortran/charset.f90: New file.
Diffstat (limited to 'gdb/c-lang.c')
-rw-r--r--gdb/c-lang.c412
1 files changed, 8 insertions, 404 deletions
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 255fabe2bfd..3a35a782057 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -140,123 +140,6 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch,
return result;
}
-/* Return true if print_wchar can display W without resorting to a
- numeric escape, false otherwise. */
-
-static int
-wchar_printable (gdb_wchar_t w)
-{
- return (gdb_iswprint (w)
- || w == LCST ('\a') || w == LCST ('\b')
- || w == LCST ('\f') || w == LCST ('\n')
- || w == LCST ('\r') || w == LCST ('\t')
- || w == LCST ('\v'));
-}
-
-/* A helper function that converts the contents of STRING to wide
- characters and then appends them to OUTPUT. */
-
-static void
-append_string_as_wide (const char *string,
- struct obstack *output)
-{
- for (; *string; ++string)
- {
- gdb_wchar_t w = gdb_btowc (*string);
- obstack_grow (output, &w, sizeof (gdb_wchar_t));
- }
-}
-
-/* Print a wide character W to OUTPUT. ORIG is a pointer to the
- original (target) bytes representing the character, ORIG_LEN is the
- number of valid bytes. WIDTH is the number of bytes in a base
- characters of the type. OUTPUT is an obstack to which wide
- characters are emitted. QUOTER is a (narrow) character indicating
- the style of quotes surrounding the character to be printed.
- NEED_ESCAPE is an in/out flag which is used to track numeric
- escapes across calls. */
-
-static void
-print_wchar (gdb_wint_t w, const gdb_byte *orig,
- int orig_len, int width,
- enum bfd_endian byte_order,
- struct obstack *output,
- int quoter, int *need_escapep)
-{
- int need_escape = *need_escapep;
-
- *need_escapep = 0;
- if (gdb_iswprint (w) && (!need_escape || (!gdb_iswdigit (w)
- && w != LCST ('8')
- && w != LCST ('9'))))
- {
- gdb_wchar_t wchar = w;
-
- if (w == gdb_btowc (quoter) || w == LCST ('\\'))
- obstack_grow_wstr (output, LCST ("\\"));
- obstack_grow (output, &wchar, sizeof (gdb_wchar_t));
- }
- else
- {
- switch (w)
- {
- case LCST ('\a'):
- obstack_grow_wstr (output, LCST ("\\a"));
- break;
- case LCST ('\b'):
- obstack_grow_wstr (output, LCST ("\\b"));
- break;
- case LCST ('\f'):
- obstack_grow_wstr (output, LCST ("\\f"));
- break;
- case LCST ('\n'):
- obstack_grow_wstr (output, LCST ("\\n"));
- break;
- case LCST ('\r'):
- obstack_grow_wstr (output, LCST ("\\r"));
- break;
- case LCST ('\t'):
- obstack_grow_wstr (output, LCST ("\\t"));
- break;
- case LCST ('\v'):
- obstack_grow_wstr (output, LCST ("\\v"));
- break;
- default:
- {
- int i;
-
- for (i = 0; i + width <= orig_len; i += width)
- {
- char octal[30];
- ULONGEST value;
-
- value = extract_unsigned_integer (&orig[i], width,
- byte_order);
- /* If the value fits in 3 octal digits, print it that
- way. Otherwise, print it as a hex escape. */
- if (value <= 0777)
- sprintf (octal, "\\%.3o", (int) (value & 0777));
- else
- sprintf (octal, "\\x%lx", (long) value);
- append_string_as_wide (octal, output);
- }
- /* If we somehow have extra bytes, print them now. */
- while (i < orig_len)
- {
- char octal[5];
-
- sprintf (octal, "\\%.3o", orig[i] & 0xff);
- append_string_as_wide (octal, output);
- ++i;
- }
-
- *need_escapep = 1;
- }
- break;
- }
- }
-}
-
/* Print the character C on STREAM as part of the contents of a
literal string whose delimiter is QUOTER. Note that that format
for printing characters and strings is language specific. */
@@ -265,85 +148,10 @@ void
c_emit_char (int c, struct type *type,
struct ui_file *stream, int quoter)
{
- enum bfd_endian byte_order
- = gdbarch_byte_order (get_type_arch (type));
- struct obstack wchar_buf, output;
- struct cleanup *cleanups;
const char *encoding;
- gdb_byte *buf;
- struct wchar_iterator *iter;
- int need_escape = 0;
classify_type (type, get_type_arch (type), &encoding);
-
- buf = alloca (TYPE_LENGTH (type));
- pack_long (buf, type, c);
-
- iter = make_wchar_iterator (buf, TYPE_LENGTH (type),
- encoding, TYPE_LENGTH (type));
- cleanups = make_cleanup_wchar_iterator (iter);
-
- /* This holds the printable form of the wchar_t data. */
- obstack_init (&wchar_buf);
- make_cleanup_obstack_free (&wchar_buf);
-
- while (1)
- {
- int num_chars;
- gdb_wchar_t *chars;
- const gdb_byte *buf;
- size_t buflen;
- int print_escape = 1;
- enum wchar_iterate_result result;
-
- num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
- if (num_chars < 0)
- break;
- if (num_chars > 0)
- {
- /* If all characters are printable, print them. Otherwise,
- we're going to have to print an escape sequence. We
- check all characters because we want to print the target
- bytes in the escape sequence, and we don't know character
- boundaries there. */
- int i;
-
- print_escape = 0;
- for (i = 0; i < num_chars; ++i)
- if (!wchar_printable (chars[i]))
- {
- print_escape = 1;
- break;
- }
-
- if (!print_escape)
- {
- for (i = 0; i < num_chars; ++i)
- print_wchar (chars[i], buf, buflen,
- TYPE_LENGTH (type), byte_order,
- &wchar_buf, quoter, &need_escape);
- }
- }
-
- /* This handles the NUM_CHARS == 0 case as well. */
- if (print_escape)
- print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type),
- byte_order, &wchar_buf, quoter, &need_escape);
- }
-
- /* The output in the host encoding. */
- obstack_init (&output);
- make_cleanup_obstack_free (&output);
-
- convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
- obstack_base (&wchar_buf),
- obstack_object_size (&wchar_buf),
- 1, &output, translit_char);
- obstack_1grow (&output, '\0');
-
- fputs_filtered (obstack_base (&output), stream);
-
- do_cleanups (cleanups);
+ generic_emit_char (c, type, stream, quoter, encoding);
}
void
@@ -385,6 +193,10 @@ c_printstr (struct ui_file *stream, struct type *type,
const char *user_encoding, int force_ellipses,
const struct value_print_options *options)
{
+ enum c_string_type str_type;
+ const char *type_encoding;
+ const char *encoding;
+
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
unsigned int i;
unsigned int things_printed = 0;
@@ -393,35 +205,10 @@ c_printstr (struct ui_file *stream, struct type *type,
int width = TYPE_LENGTH (type);
struct obstack wchar_buf, output;
struct cleanup *cleanup;
- enum c_string_type str_type;
- const char *type_encoding;
- const char *encoding;
struct wchar_iterator *iter;
int finished = 0;
int need_escape = 0;
- if (length == -1)
- {
- unsigned long current_char = 1;
-
- for (i = 0; current_char; ++i)
- {
- QUIT;
- current_char = extract_unsigned_integer (string + i * width,
- width, byte_order);
- }
- length = i;
- }
-
- /* If the string was not truncated due to `set print elements', and
- the last byte of it is a null, we don't print that, in
- traditional C style. */
- if (!force_ellipses
- && length > 0
- && (extract_unsigned_integer (string + (length - 1) * width,
- width, byte_order) == 0))
- length--;
-
str_type = (classify_type (type, get_type_arch (type), &type_encoding)
& ~C_CHAR);
switch (str_type)
@@ -439,193 +226,10 @@ c_printstr (struct ui_file *stream, struct type *type,
break;
}
- encoding = (user_encoding && *user_encoding)
- ? user_encoding : type_encoding;
-
- if (length == 0)
- {
- fputs_filtered ("\"\"", stream);
- return;
- }
-
- /* Arrange to iterate over the characters, in wchar_t form. */
- iter = make_wchar_iterator (string, length * width, encoding, width);
- cleanup = make_cleanup_wchar_iterator (iter);
-
- /* WCHAR_BUF is the obstack we use to represent the string in
- wchar_t form. */
- obstack_init (&wchar_buf);
- make_cleanup_obstack_free (&wchar_buf);
-
- while (!finished && things_printed < options->print_max)
- {
- int num_chars;
- enum wchar_iterate_result result;
- gdb_wchar_t *chars;
- const gdb_byte *buf;
- size_t buflen;
-
- QUIT;
-
- if (need_comma)
- {
- obstack_grow_wstr (&wchar_buf, LCST (", "));
- need_comma = 0;
- }
-
- num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
- /* We only look at repetitions when we were able to convert a
- single character in isolation. This makes the code simpler
- and probably does the sensible thing in the majority of
- cases. */
- while (num_chars == 1 && things_printed < options->print_max)
- {
- /* Count the number of repetitions. */
- unsigned int reps = 0;
- gdb_wchar_t current_char = chars[0];
- const gdb_byte *orig_buf = buf;
- int orig_len = buflen;
-
- if (need_comma)
- {
- obstack_grow_wstr (&wchar_buf, LCST (", "));
- need_comma = 0;
- }
-
- while (num_chars == 1 && current_char == chars[0])
- {
- num_chars = wchar_iterate (iter, &result, &chars,
- &buf, &buflen);
- ++reps;
- }
-
- /* Emit CURRENT_CHAR according to the repetition count and
- options. */
- if (reps > options->repeat_count_threshold)
- {
- if (in_quotes)
- {
- if (options->inspect_it)
- obstack_grow_wstr (&wchar_buf, LCST ("\\\", "));
- else
- obstack_grow_wstr (&wchar_buf, LCST ("\", "));
- in_quotes = 0;
- }
- obstack_grow_wstr (&wchar_buf, LCST ("'"));
- need_escape = 0;
- print_wchar (current_char, orig_buf, orig_len, width,
- byte_order, &wchar_buf, '\'', &need_escape);
- obstack_grow_wstr (&wchar_buf, LCST ("'"));
- {
- /* Painful gyrations. */
- int j;
- char *s = xstrprintf (_(" <repeats %u times>"), reps);
-
- for (j = 0; s[j]; ++j)
- {
- gdb_wchar_t w = gdb_btowc (s[j]);
- obstack_grow (&wchar_buf, &w, sizeof (gdb_wchar_t));
- }
- xfree (s);
- }
- things_printed += options->repeat_count_threshold;
- need_comma = 1;
- }
- else
- {
- /* Saw the character one or more times, but fewer than
- the repetition threshold. */
- if (!in_quotes)
- {
- if (options->inspect_it)
- obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
- else
- obstack_grow_wstr (&wchar_buf, LCST ("\""));
- in_quotes = 1;
- need_escape = 0;
- }
-
- while (reps-- > 0)
- {
- print_wchar (current_char, orig_buf,
- orig_len, width,
- byte_order, &wchar_buf,
- '"', &need_escape);
- ++things_printed;
- }
- }
- }
-
- /* NUM_CHARS and the other outputs from wchar_iterate are valid
- here regardless of which branch was taken above. */
- if (num_chars < 0)
- {
- /* Hit EOF. */
- finished = 1;
- break;
- }
-
- switch (result)
- {
- case wchar_iterate_invalid:
- if (!in_quotes)
- {
- if (options->inspect_it)
- obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
- else
- obstack_grow_wstr (&wchar_buf, LCST ("\""));
- in_quotes = 1;
- }
- need_escape = 0;
- print_wchar (gdb_WEOF, buf, buflen, width, byte_order,
- &wchar_buf, '"', &need_escape);
- break;
-
- case wchar_iterate_incomplete:
- if (in_quotes)
- {
- if (options->inspect_it)
- obstack_grow_wstr (&wchar_buf, LCST ("\\\","));
- else
- obstack_grow_wstr (&wchar_buf, LCST ("\","));
- in_quotes = 0;
- }
- obstack_grow_wstr (&wchar_buf,
- LCST (" <incomplete sequence "));
- print_wchar (gdb_WEOF, buf, buflen, width,
- byte_order, &wchar_buf,
- 0, &need_escape);
- obstack_grow_wstr (&wchar_buf, LCST (">"));
- finished = 1;
- break;
- }
- }
-
- /* Terminate the quotes if necessary. */
- if (in_quotes)
- {
- if (options->inspect_it)
- obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
- else
- obstack_grow_wstr (&wchar_buf, LCST ("\""));
- }
-
- if (force_ellipses || !finished)
- obstack_grow_wstr (&wchar_buf, LCST ("..."));
-
- /* OUTPUT is where we collect `char's for printing. */
- obstack_init (&output);
- make_cleanup_obstack_free (&output);
-
- convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
- obstack_base (&wchar_buf),
- obstack_object_size (&wchar_buf),
- 1, &output, translit_char);
- obstack_1grow (&output, '\0');
-
- fputs_filtered (obstack_base (&output), stream);
+ encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding;
- do_cleanups (cleanup);
+ generic_printstr (stream, type, string, length, encoding, force_ellipses,
+ '"', 1, options);
}
/* Obtain a C string from the inferior storing it in a newly allocated