diff options
author | Tom Tromey <tromey@redhat.com> | 2011-06-29 15:32:40 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2011-06-29 15:32:40 +0000 |
commit | 3b2b8feaf4aaa62c7d55ad845c3ff34165a3af22 (patch) | |
tree | 05f9c11e7c9408d89574648e7b0b2a9c0aec63a7 /gdb/c-lang.c | |
parent | 168e6d44026869c1cd8dd66d7ef7cdeecdcff77d (diff) | |
download | binutils-3b2b8feaf4aaa62c7d55ad845c3ff34165a3af22.zip binutils-3b2b8feaf4aaa62c7d55ad845c3ff34165a3af22.tar.gz binutils-3b2b8feaf4aaa62c7d55ad845c3ff34165a3af22.tar.bz2 |
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.c | 412 |
1 files changed, 8 insertions, 404 deletions
diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 255fabe..3a35a78 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 |