| Index: gdb/valprint.c
|
| diff --git a/gdb/valprint.c b/gdb/valprint.c
|
| index fc5942da77887069a9a1e19192245711df5c8755..7ebcdfd99106dc3ecdf5a6d927ce4c9b3e823f69 100644
|
| --- a/gdb/valprint.c
|
| +++ b/gdb/valprint.c
|
| @@ -1,6 +1,6 @@
|
| /* Print values for GDB, the GNU debugger.
|
|
|
| - Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -18,7 +18,7 @@
|
| along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
| #include "defs.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include "symtab.h"
|
| #include "gdbtypes.h"
|
| #include "value.h"
|
| @@ -40,10 +40,50 @@
|
|
|
| #include <errno.h>
|
|
|
| +/* Maximum number of wchars returned from wchar_iterate. */
|
| +#define MAX_WCHARS 4
|
| +
|
| +/* A convenience macro to compute the size of a wchar_t buffer containing X
|
| + characters. */
|
| +#define WCHAR_BUFLEN(X) ((X) * sizeof (gdb_wchar_t))
|
| +
|
| +/* Character buffer size saved while iterating over wchars. */
|
| +#define WCHAR_BUFLEN_MAX WCHAR_BUFLEN (MAX_WCHARS)
|
| +
|
| +/* A structure to encapsulate state information from iterated
|
| + character conversions. */
|
| +struct converted_character
|
| +{
|
| + /* The number of characters converted. */
|
| + int num_chars;
|
| +
|
| + /* The result of the conversion. See charset.h for more. */
|
| + enum wchar_iterate_result result;
|
| +
|
| + /* The (saved) converted character(s). */
|
| + gdb_wchar_t chars[WCHAR_BUFLEN_MAX];
|
| +
|
| + /* The first converted target byte. */
|
| + const gdb_byte *buf;
|
| +
|
| + /* The number of bytes converted. */
|
| + size_t buflen;
|
| +
|
| + /* How many times this character(s) is repeated. */
|
| + int repeat_count;
|
| +};
|
| +
|
| +typedef struct converted_character converted_character_d;
|
| +DEF_VEC_O (converted_character_d);
|
| +
|
| +/* Command lists for set/show print raw. */
|
| +struct cmd_list_element *setprintrawlist;
|
| +struct cmd_list_element *showprintrawlist;
|
| +
|
| /* Prototypes for local functions */
|
|
|
| static int partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
|
| - int len, int *errnoptr);
|
| + int len, int *errptr);
|
|
|
| static void show_print (char *, int);
|
|
|
| @@ -67,9 +107,9 @@ void _initialize_valprint (void);
|
|
|
| struct value_print_options user_print_options =
|
| {
|
| - Val_pretty_default, /* pretty */
|
| - 0, /* prettyprint_arrays */
|
| - 0, /* prettyprint_structs */
|
| + Val_prettyformat_default, /* prettyformat */
|
| + 0, /* prettyformat_arrays */
|
| + 0, /* prettyformat_structs */
|
| 0, /* vtblprint */
|
| 1, /* unionprint */
|
| 1, /* addressprint */
|
| @@ -79,7 +119,6 @@ struct value_print_options user_print_options =
|
| 0, /* output_format */
|
| 0, /* format */
|
| 0, /* stop_print_at_null */
|
| - 0, /* inspect_it */
|
| 0, /* print_array_indexes */
|
| 0, /* deref_ref */
|
| 1, /* static_field_print */
|
| @@ -97,12 +136,12 @@ get_user_print_options (struct value_print_options *opts)
|
| }
|
|
|
| /* Initialize *OPTS to be a copy of the user print options, but with
|
| - pretty-printing disabled. */
|
| + pretty-formatting disabled. */
|
| void
|
| -get_raw_print_options (struct value_print_options *opts)
|
| +get_no_prettyformat_print_options (struct value_print_options *opts)
|
| {
|
| *opts = user_print_options;
|
| - opts->pretty = Val_no_prettyprint;
|
| + opts->prettyformat = Val_no_prettyformat;
|
| }
|
|
|
| /* Initialize *OPTS to be a copy of the user print options, but using
|
| @@ -185,19 +224,19 @@ show_stop_print_at_null (struct ui_file *file, int from_tty,
|
| /* Controls pretty printing of structures. */
|
|
|
| static void
|
| -show_prettyprint_structs (struct ui_file *file, int from_tty,
|
| +show_prettyformat_structs (struct ui_file *file, int from_tty,
|
| struct cmd_list_element *c, const char *value)
|
| {
|
| - fprintf_filtered (file, _("Prettyprinting of structures is %s.\n"), value);
|
| + fprintf_filtered (file, _("Pretty formatting of structures is %s.\n"), value);
|
| }
|
|
|
| /* Controls pretty printing of arrays. */
|
|
|
| static void
|
| -show_prettyprint_arrays (struct ui_file *file, int from_tty,
|
| +show_prettyformat_arrays (struct ui_file *file, int from_tty,
|
| struct cmd_list_element *c, const char *value)
|
| {
|
| - fprintf_filtered (file, _("Prettyprinting of arrays is %s.\n"), value);
|
| + fprintf_filtered (file, _("Pretty formatting of arrays is %s.\n"), value);
|
| }
|
|
|
| /* If nonzero, causes unions inside structures or other unions to be
|
| @@ -236,8 +275,8 @@ show_symbol_print (struct ui_file *file, int from_tty,
|
| we want to print scalar arguments, but not aggregate arguments.
|
| This function distinguishes between the two. */
|
|
|
| -static int
|
| -scalar_type_p (struct type *type)
|
| +int
|
| +val_print_scalar_type_p (struct type *type)
|
| {
|
| CHECK_TYPEDEF (type);
|
| while (TYPE_CODE (type) == TYPE_CODE_REF)
|
| @@ -252,7 +291,6 @@ scalar_type_p (struct type *type)
|
| case TYPE_CODE_UNION:
|
| case TYPE_CODE_SET:
|
| case TYPE_CODE_STRING:
|
| - case TYPE_CODE_BITSTRING:
|
| return 0;
|
| default:
|
| return 1;
|
| @@ -276,7 +314,7 @@ valprint_check_validity (struct ui_file *stream,
|
| if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
|
| TARGET_CHAR_BIT * TYPE_LENGTH (type)))
|
| {
|
| - val_print_optimized_out (stream);
|
| + val_print_optimized_out (val, stream);
|
| return 0;
|
| }
|
|
|
| @@ -298,9 +336,18 @@ valprint_check_validity (struct ui_file *stream,
|
| }
|
|
|
| void
|
| -val_print_optimized_out (struct ui_file *stream)
|
| +val_print_optimized_out (const struct value *val, struct ui_file *stream)
|
| +{
|
| + if (val != NULL && value_lval_const (val) == lval_register)
|
| + val_print_not_saved (stream);
|
| + else
|
| + fprintf_filtered (stream, _("<optimized out>"));
|
| +}
|
| +
|
| +void
|
| +val_print_not_saved (struct ui_file *stream)
|
| {
|
| - fprintf_filtered (stream, _("<optimized out>"));
|
| + fprintf_filtered (stream, _("<not saved>"));
|
| }
|
|
|
| void
|
| @@ -335,7 +382,6 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
|
| const struct generic_val_print_decorations *decorations)
|
| {
|
| struct gdbarch *gdbarch = get_type_arch (type);
|
| - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
| unsigned int i = 0; /* Number of characters printed. */
|
| unsigned len;
|
| struct type *elttype, *unresolved_elttype;
|
| @@ -356,7 +402,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
|
| if (!get_array_bounds (type, &low_bound, &high_bound))
|
| error (_("Could not determine the array high bound"));
|
|
|
| - if (options->prettyprint_arrays)
|
| + if (options->prettyformat_arrays)
|
| {
|
| print_spaces_filtered (2 + 2 * recurse, stream);
|
| }
|
| @@ -702,9 +748,9 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
| struct value_print_options local_opts = *options;
|
| struct type *real_type = check_typedef (type);
|
|
|
| - if (local_opts.pretty == Val_pretty_default)
|
| - local_opts.pretty = (local_opts.prettyprint_structs
|
| - ? Val_prettyprint : Val_no_prettyprint);
|
| + if (local_opts.prettyformat == Val_prettyformat_default)
|
| + local_opts.prettyformat = (local_opts.prettyformat_structs
|
| + ? Val_prettyformat : Val_no_prettyformat);
|
|
|
| QUIT;
|
|
|
| @@ -733,7 +779,7 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
|
|
| /* Handle summary mode. If the value is a scalar, print it;
|
| otherwise, print an ellipsis. */
|
| - if (options->summary && !scalar_type_p (type))
|
| + if (options->summary && !val_print_scalar_type_p (type))
|
| {
|
| fprintf_filtered (stream, "...");
|
| return;
|
| @@ -765,10 +811,19 @@ value_check_printable (struct value *val, struct ui_file *stream,
|
|
|
| if (value_entirely_optimized_out (val))
|
| {
|
| - if (options->summary && !scalar_type_p (value_type (val)))
|
| + if (options->summary && !val_print_scalar_type_p (value_type (val)))
|
| + fprintf_filtered (stream, "...");
|
| + else
|
| + val_print_optimized_out (val, stream);
|
| + return 0;
|
| + }
|
| +
|
| + if (value_entirely_unavailable (val))
|
| + {
|
| + if (options->summary && !val_print_scalar_type_p (value_type (val)))
|
| fprintf_filtered (stream, "...");
|
| else
|
| - val_print_optimized_out (stream);
|
| + val_print_unavailable (stream);
|
| return 0;
|
| }
|
|
|
| @@ -929,7 +984,7 @@ val_print_scalar_formatted (struct type *type,
|
| printed, because all bits contribute to its representation. */
|
| if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
|
| TARGET_CHAR_BIT * TYPE_LENGTH (type)))
|
| - val_print_optimized_out (stream);
|
| + val_print_optimized_out (val, stream);
|
| else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
|
| val_print_unavailable (stream);
|
| else
|
| @@ -1608,7 +1663,7 @@ val_print_array_elements (struct type *type,
|
| {
|
| if (i != 0)
|
| {
|
| - if (options->prettyprint_arrays)
|
| + if (options->prettyformat_arrays)
|
| {
|
| fprintf_filtered (stream, ",\n");
|
| print_spaces_filtered (2 + 2 * recurse, stream);
|
| @@ -1671,15 +1726,15 @@ val_print_array_elements (struct type *type,
|
|
|
| /* Read LEN bytes of target memory at address MEMADDR, placing the
|
| results in GDB's memory at MYADDR. Returns a count of the bytes
|
| - actually read, and optionally an errno value in the location
|
| - pointed to by ERRNOPTR if ERRNOPTR is non-null. */
|
| + actually read, and optionally a target_xfer_error value in the
|
| + location pointed to by ERRPTR if ERRPTR is non-null. */
|
|
|
| /* FIXME: cagney/1999-10-14: Only used by val_print_string. Can this
|
| function be eliminated. */
|
|
|
| static int
|
| partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
|
| - int len, int *errnoptr)
|
| + int len, int *errptr)
|
| {
|
| int nread; /* Number of bytes actually read. */
|
| int errcode; /* Error from last read. */
|
| @@ -1704,9 +1759,9 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
|
| nread--;
|
| }
|
| }
|
| - if (errnoptr != NULL)
|
| + if (errptr != NULL)
|
| {
|
| - *errnoptr = errcode;
|
| + *errptr = errcode;
|
| }
|
| return (nread);
|
| }
|
| @@ -1715,13 +1770,15 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
|
| each. Fetch at most FETCHLIMIT characters. BUFFER will be set to a newly
|
| allocated buffer containing the string, which the caller is responsible to
|
| free, and BYTES_READ will be set to the number of bytes read. Returns 0 on
|
| - success, or errno on failure.
|
| + success, or a target_xfer_error on failure.
|
|
|
| - If LEN > 0, reads exactly LEN characters (including eventual NULs in
|
| - the middle or end of the string). If LEN is -1, stops at the first
|
| - null character (not necessarily the first null byte) up to a maximum
|
| - of FETCHLIMIT characters. Set FETCHLIMIT to UINT_MAX to read as many
|
| - characters as possible from the string.
|
| + If LEN > 0, reads the lesser of LEN or FETCHLIMIT characters
|
| + (including eventual NULs in the middle or end of the string).
|
| +
|
| + If LEN is -1, stops at the first null character (not necessarily
|
| + the first null byte) up to a maximum of FETCHLIMIT characters. Set
|
| + FETCHLIMIT to UINT_MAX to read as many characters as possible from
|
| + the string.
|
|
|
| Unless an exception is thrown, BUFFER will always be allocated, even on
|
| failure. In this case, some characters might have been read before the
|
| @@ -1767,10 +1824,12 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
|
|
|
| if (len > 0)
|
| {
|
| - *buffer = (gdb_byte *) xmalloc (len * width);
|
| + unsigned int fetchlen = min (len, fetchlimit);
|
| +
|
| + *buffer = (gdb_byte *) xmalloc (fetchlen * width);
|
| bufptr = *buffer;
|
|
|
| - nfetch = partial_memory_read (addr, bufptr, len * width, &errcode)
|
| + nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
|
| / width;
|
| addr += nfetch * width;
|
| bufptr += nfetch * width;
|
| @@ -1938,9 +1997,10 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
|
| /* 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));
|
| + xsnprintf (octal, sizeof (octal), "\\%.3o",
|
| + (int) (value & 0777));
|
| else
|
| - sprintf (octal, "\\x%lx", (long) value);
|
| + xsnprintf (octal, sizeof (octal), "\\x%lx", (long) value);
|
| append_string_as_wide (octal, output);
|
| }
|
| /* If we somehow have extra bytes, print them now. */
|
| @@ -1948,7 +2008,7 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
|
| {
|
| char octal[5];
|
|
|
| - sprintf (octal, "\\%.3o", orig[i] & 0xff);
|
| + xsnprintf (octal, sizeof (octal), "\\%.3o", orig[i] & 0xff);
|
| append_string_as_wide (octal, output);
|
| ++i;
|
| }
|
| @@ -2036,9 +2096,9 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
|
| make_cleanup_obstack_free (&output);
|
|
|
| convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
|
| - obstack_base (&wchar_buf),
|
| + (gdb_byte *) obstack_base (&wchar_buf),
|
| obstack_object_size (&wchar_buf),
|
| - 1, &output, translit_char);
|
| + sizeof (gdb_wchar_t), &output, translit_char);
|
| obstack_1grow (&output, '\0');
|
|
|
| fputs_filtered (obstack_base (&output), stream);
|
| @@ -2046,6 +2106,243 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
|
| do_cleanups (cleanups);
|
| }
|
|
|
| +/* Return the repeat count of the next character/byte in ITER,
|
| + storing the result in VEC. */
|
| +
|
| +static int
|
| +count_next_character (struct wchar_iterator *iter,
|
| + VEC (converted_character_d) **vec)
|
| +{
|
| + struct converted_character *current;
|
| +
|
| + if (VEC_empty (converted_character_d, *vec))
|
| + {
|
| + struct converted_character tmp;
|
| + gdb_wchar_t *chars;
|
| +
|
| + tmp.num_chars
|
| + = wchar_iterate (iter, &tmp.result, &chars, &tmp.buf, &tmp.buflen);
|
| + if (tmp.num_chars > 0)
|
| + {
|
| + gdb_assert (tmp.num_chars < MAX_WCHARS);
|
| + memcpy (tmp.chars, chars, tmp.num_chars * sizeof (gdb_wchar_t));
|
| + }
|
| + VEC_safe_push (converted_character_d, *vec, &tmp);
|
| + }
|
| +
|
| + current = VEC_last (converted_character_d, *vec);
|
| +
|
| + /* Count repeated characters or bytes. */
|
| + current->repeat_count = 1;
|
| + if (current->num_chars == -1)
|
| + {
|
| + /* EOF */
|
| + return -1;
|
| + }
|
| + else
|
| + {
|
| + gdb_wchar_t *chars;
|
| + struct converted_character d;
|
| + int repeat;
|
| +
|
| + d.repeat_count = 0;
|
| +
|
| + while (1)
|
| + {
|
| + /* Get the next character. */
|
| + d.num_chars
|
| + = wchar_iterate (iter, &d.result, &chars, &d.buf, &d.buflen);
|
| +
|
| + /* If a character was successfully converted, save the character
|
| + into the converted character. */
|
| + if (d.num_chars > 0)
|
| + {
|
| + gdb_assert (d.num_chars < MAX_WCHARS);
|
| + memcpy (d.chars, chars, WCHAR_BUFLEN (d.num_chars));
|
| + }
|
| +
|
| + /* Determine if the current character is the same as this
|
| + new character. */
|
| + if (d.num_chars == current->num_chars && d.result == current->result)
|
| + {
|
| + /* There are two cases to consider:
|
| +
|
| + 1) Equality of converted character (num_chars > 0)
|
| + 2) Equality of non-converted character (num_chars == 0) */
|
| + if ((current->num_chars > 0
|
| + && memcmp (current->chars, d.chars,
|
| + WCHAR_BUFLEN (current->num_chars)) == 0)
|
| + || (current->num_chars == 0
|
| + && current->buflen == d.buflen
|
| + && memcmp (current->buf, d.buf, current->buflen) == 0))
|
| + ++current->repeat_count;
|
| + else
|
| + break;
|
| + }
|
| + else
|
| + break;
|
| + }
|
| +
|
| + /* Push this next converted character onto the result vector. */
|
| + repeat = current->repeat_count;
|
| + VEC_safe_push (converted_character_d, *vec, &d);
|
| + return repeat;
|
| + }
|
| +}
|
| +
|
| +/* Print the characters in CHARS to the OBSTACK. QUOTE_CHAR is the quote
|
| + character to use with string output. WIDTH is the size of the output
|
| + character type. BYTE_ORDER is the the target byte order. OPTIONS
|
| + is the user's print options. */
|
| +
|
| +static void
|
| +print_converted_chars_to_obstack (struct obstack *obstack,
|
| + VEC (converted_character_d) *chars,
|
| + int quote_char, int width,
|
| + enum bfd_endian byte_order,
|
| + const struct value_print_options *options)
|
| +{
|
| + unsigned int idx;
|
| + struct converted_character *elem;
|
| + enum {START, SINGLE, REPEAT, INCOMPLETE, FINISH} state, last;
|
| + gdb_wchar_t wide_quote_char = gdb_btowc (quote_char);
|
| + int need_escape = 0;
|
| +
|
| + /* Set the start state. */
|
| + idx = 0;
|
| + last = state = START;
|
| + elem = NULL;
|
| +
|
| + while (1)
|
| + {
|
| + switch (state)
|
| + {
|
| + case START:
|
| + /* Nothing to do. */
|
| + break;
|
| +
|
| + case SINGLE:
|
| + {
|
| + int j;
|
| +
|
| + /* We are outputting a single character
|
| + (< options->repeat_count_threshold). */
|
| +
|
| + if (last != SINGLE)
|
| + {
|
| + /* We were outputting some other type of content, so we
|
| + must output and a comma and a quote. */
|
| + if (last != START)
|
| + obstack_grow_wstr (obstack, LCST (", "));
|
| + obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));
|
| + }
|
| + /* Output the character. */
|
| + for (j = 0; j < elem->repeat_count; ++j)
|
| + {
|
| + if (elem->result == wchar_iterate_ok)
|
| + print_wchar (elem->chars[0], elem->buf, elem->buflen, width,
|
| + byte_order, obstack, quote_char, &need_escape);
|
| + else
|
| + print_wchar (gdb_WEOF, elem->buf, elem->buflen, width,
|
| + byte_order, obstack, quote_char, &need_escape);
|
| + }
|
| + }
|
| + break;
|
| +
|
| + case REPEAT:
|
| + {
|
| + int j;
|
| + char *s;
|
| +
|
| + /* We are outputting a character with a repeat count
|
| + greater than options->repeat_count_threshold. */
|
| +
|
| + if (last == SINGLE)
|
| + {
|
| + /* We were outputting a single string. Terminate the
|
| + string. */
|
| + obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));
|
| + }
|
| + if (last != START)
|
| + obstack_grow_wstr (obstack, LCST (", "));
|
| +
|
| + /* Output the character and repeat string. */
|
| + obstack_grow_wstr (obstack, LCST ("'"));
|
| + if (elem->result == wchar_iterate_ok)
|
| + print_wchar (elem->chars[0], elem->buf, elem->buflen, width,
|
| + byte_order, obstack, quote_char, &need_escape);
|
| + else
|
| + print_wchar (gdb_WEOF, elem->buf, elem->buflen, width,
|
| + byte_order, obstack, quote_char, &need_escape);
|
| + obstack_grow_wstr (obstack, LCST ("'"));
|
| + s = xstrprintf (_(" <repeats %u times>"), elem->repeat_count);
|
| + for (j = 0; s[j]; ++j)
|
| + {
|
| + gdb_wchar_t w = gdb_btowc (s[j]);
|
| + obstack_grow (obstack, &w, sizeof (gdb_wchar_t));
|
| + }
|
| + xfree (s);
|
| + }
|
| + break;
|
| +
|
| + case INCOMPLETE:
|
| + /* We are outputting an incomplete sequence. */
|
| + if (last == SINGLE)
|
| + {
|
| + /* If we were outputting a string of SINGLE characters,
|
| + terminate the quote. */
|
| + obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));
|
| + }
|
| + if (last != START)
|
| + obstack_grow_wstr (obstack, LCST (", "));
|
| +
|
| + /* Output the incomplete sequence string. */
|
| + obstack_grow_wstr (obstack, LCST ("<incomplete sequence "));
|
| + print_wchar (gdb_WEOF, elem->buf, elem->buflen, width, byte_order,
|
| + obstack, 0, &need_escape);
|
| + obstack_grow_wstr (obstack, LCST (">"));
|
| +
|
| + /* We do not attempt to outupt anything after this. */
|
| + state = FINISH;
|
| + break;
|
| +
|
| + case FINISH:
|
| + /* All done. If we were outputting a string of SINGLE
|
| + characters, the string must be terminated. Otherwise,
|
| + REPEAT and INCOMPLETE are always left properly terminated. */
|
| + if (last == SINGLE)
|
| + obstack_grow (obstack, &wide_quote_char, sizeof (gdb_wchar_t));
|
| +
|
| + return;
|
| + }
|
| +
|
| + /* Get the next element and state. */
|
| + last = state;
|
| + if (state != FINISH)
|
| + {
|
| + elem = VEC_index (converted_character_d, chars, idx++);
|
| + switch (elem->result)
|
| + {
|
| + case wchar_iterate_ok:
|
| + case wchar_iterate_invalid:
|
| + if (elem->repeat_count > options->repeat_count_threshold)
|
| + state = REPEAT;
|
| + else
|
| + state = SINGLE;
|
| + break;
|
| +
|
| + case wchar_iterate_incomplete:
|
| + state = INCOMPLETE;
|
| + break;
|
| +
|
| + case wchar_iterate_eof:
|
| + state = FINISH;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| /* Print the character string STRING, printing at most LENGTH
|
| characters. LENGTH is -1 if the string is nul terminated. TYPE is
|
| the type of each character. OPTIONS holds the printing options;
|
| @@ -2065,16 +2362,13 @@ generic_printstr (struct ui_file *stream, struct type *type,
|
| {
|
| enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
|
| unsigned int i;
|
| - unsigned int things_printed = 0;
|
| - int in_quotes = 0;
|
| - int need_comma = 0;
|
| int width = TYPE_LENGTH (type);
|
| struct obstack wchar_buf, output;
|
| struct cleanup *cleanup;
|
| struct wchar_iterator *iter;
|
| int finished = 0;
|
| - int need_escape = 0;
|
| - gdb_wchar_t wide_quote_char = gdb_btowc (quote_char);
|
| + struct converted_character *last;
|
| + VEC (converted_character_d) *converted_chars;
|
|
|
| if (length == -1)
|
| {
|
| @@ -2108,166 +2402,46 @@ generic_printstr (struct ui_file *stream, struct type *type,
|
| /* 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);
|
| + converted_chars = NULL;
|
| + make_cleanup (VEC_cleanup (converted_character_d), &converted_chars);
|
|
|
| - /* 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)
|
| + /* Convert characters until the string is over or the maximum
|
| + number of printed characters has been reached. */
|
| + i = 0;
|
| + while (i < options->print_max)
|
| {
|
| - int num_chars;
|
| - enum wchar_iterate_result result;
|
| - gdb_wchar_t *chars;
|
| - const gdb_byte *buf;
|
| - size_t buflen;
|
| + int r;
|
|
|
| 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;
|
| + /* Grab the next character and repeat count. */
|
| + r = count_next_character (iter, &converted_chars);
|
|
|
| - 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 ("\\"));
|
| - obstack_grow (&wchar_buf, &wide_quote_char,
|
| - sizeof (gdb_wchar_t));
|
| - 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 ("\\"));
|
| - obstack_grow (&wchar_buf, &wide_quote_char,
|
| - sizeof (gdb_wchar_t));
|
| - in_quotes = 1;
|
| - need_escape = 0;
|
| - }
|
| + /* If less than zero, the end of the input string was reached. */
|
| + if (r < 0)
|
| + break;
|
|
|
| - while (reps-- > 0)
|
| - {
|
| - print_wchar (current_char, orig_buf,
|
| - orig_len, width,
|
| - byte_order, &wchar_buf,
|
| - quote_char, &need_escape);
|
| - ++things_printed;
|
| - }
|
| - }
|
| - }
|
| + /* Otherwise, add the count to the total print count and get
|
| + the next character. */
|
| + i += r;
|
| + }
|
|
|
| - /* 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;
|
| - }
|
| + /* Get the last element and determine if the entire string was
|
| + processed. */
|
| + last = VEC_last (converted_character_d, converted_chars);
|
| + finished = (last->result == wchar_iterate_eof);
|
|
|
| - switch (result)
|
| - {
|
| - case wchar_iterate_invalid:
|
| - if (!in_quotes)
|
| - {
|
| - if (options->inspect_it)
|
| - obstack_grow_wstr (&wchar_buf, LCST ("\\"));
|
| - obstack_grow (&wchar_buf, &wide_quote_char,
|
| - sizeof (gdb_wchar_t));
|
| - in_quotes = 1;
|
| - }
|
| - need_escape = 0;
|
| - print_wchar (gdb_WEOF, buf, buflen, width, byte_order,
|
| - &wchar_buf, quote_char, &need_escape);
|
| - break;
|
| + /* Ensure that CONVERTED_CHARS is terminated. */
|
| + last->result = wchar_iterate_eof;
|
|
|
| - case wchar_iterate_incomplete:
|
| - if (in_quotes)
|
| - {
|
| - if (options->inspect_it)
|
| - obstack_grow_wstr (&wchar_buf, LCST ("\\"));
|
| - obstack_grow (&wchar_buf, &wide_quote_char,
|
| - sizeof (gdb_wchar_t));
|
| - 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;
|
| - }
|
| - }
|
| + /* 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);
|
|
|
| - /* Terminate the quotes if necessary. */
|
| - if (in_quotes)
|
| - {
|
| - if (options->inspect_it)
|
| - obstack_grow_wstr (&wchar_buf, LCST ("\\"));
|
| - obstack_grow (&wchar_buf, &wide_quote_char,
|
| - sizeof (gdb_wchar_t));
|
| - }
|
| + /* Print the output string to the obstack. */
|
| + print_converted_chars_to_obstack (&wchar_buf, converted_chars, quote_char,
|
| + width, byte_order, options);
|
|
|
| if (force_ellipses || !finished)
|
| obstack_grow_wstr (&wchar_buf, LCST ("..."));
|
| @@ -2277,9 +2451,9 @@ generic_printstr (struct ui_file *stream, struct type *type,
|
| make_cleanup_obstack_free (&output);
|
|
|
| convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
|
| - obstack_base (&wchar_buf),
|
| + (gdb_byte *) obstack_base (&wchar_buf),
|
| obstack_object_size (&wchar_buf),
|
| - 1, &output, translit_char);
|
| + sizeof (gdb_wchar_t), &output, translit_char);
|
| obstack_1grow (&output, '\0');
|
|
|
| fputs_filtered (obstack_base (&output), stream);
|
| @@ -2369,18 +2543,14 @@ val_print_string (struct type *elttype, const char *encoding,
|
|
|
| if (errcode != 0)
|
| {
|
| - if (errcode == EIO)
|
| - {
|
| - fprintf_filtered (stream, "<Address ");
|
| - fputs_filtered (paddress (gdbarch, addr), stream);
|
| - fprintf_filtered (stream, " out of bounds>");
|
| - }
|
| - else
|
| - {
|
| - fprintf_filtered (stream, "<Error reading address ");
|
| - fputs_filtered (paddress (gdbarch, addr), stream);
|
| - fprintf_filtered (stream, ": %s>", safe_strerror (errcode));
|
| - }
|
| + char *str;
|
| +
|
| + str = memory_error_message (errcode, gdbarch, addr);
|
| + make_cleanup (xfree, str);
|
| +
|
| + fprintf_filtered (stream, "<error: ");
|
| + fputs_filtered (str, stream);
|
| + fprintf_filtered (stream, ">");
|
| }
|
|
|
| gdb_flush (stream);
|
| @@ -2537,6 +2707,21 @@ show_print (char *args, int from_tty)
|
| {
|
| cmd_show_list (showprintlist, from_tty, "");
|
| }
|
| +
|
| +static void
|
| +set_print_raw (char *arg, int from_tty)
|
| +{
|
| + printf_unfiltered (
|
| + "\"set print raw\" must be followed by the name of a \"print raw\" subcommand.\n");
|
| + help_list (setprintrawlist, "set print raw ", -1, gdb_stdout);
|
| +}
|
| +
|
| +static void
|
| +show_print_raw (char *args, int from_tty)
|
| +{
|
| + cmd_show_list (showprintrawlist, from_tty, "");
|
| +}
|
| +
|
|
|
| void
|
| _initialize_valprint (void)
|
| @@ -2554,11 +2739,19 @@ _initialize_valprint (void)
|
| add_alias_cmd ("p", "print", no_class, 1, &showlist);
|
| add_alias_cmd ("pr", "print", no_class, 1, &showlist);
|
|
|
| + add_prefix_cmd ("raw", no_class, set_print_raw,
|
| + _("\
|
| +Generic command for setting what things to print in \"raw\" mode."),
|
| + &setprintrawlist, "set print raw ", 0, &setprintlist);
|
| + add_prefix_cmd ("raw", no_class, show_print_raw,
|
| + _("Generic command for showing \"print raw\" settings."),
|
| + &showprintrawlist, "show print raw ", 0, &showprintlist);
|
| +
|
| add_setshow_uinteger_cmd ("elements", no_class,
|
| &user_print_options.print_max, _("\
|
| Set limit on string chars or array elements to print."), _("\
|
| Show limit on string chars or array elements to print."), _("\
|
| -\"set print elements 0\" causes there to be no limit."),
|
| +\"set print elements unlimited\" causes there to be no limit."),
|
| NULL,
|
| show_print_max,
|
| &setprintlist, &showprintlist);
|
| @@ -2575,17 +2768,17 @@ Show printing of char arrays to stop at first null char."), NULL,
|
| &user_print_options.repeat_count_threshold, _("\
|
| Set threshold for repeated print elements."), _("\
|
| Show threshold for repeated print elements."), _("\
|
| -\"set print repeats 0\" causes all elements to be individually printed."),
|
| +\"set print repeats unlimited\" causes all elements to be individually printed."),
|
| NULL,
|
| show_repeat_count_threshold,
|
| &setprintlist, &showprintlist);
|
|
|
| add_setshow_boolean_cmd ("pretty", class_support,
|
| - &user_print_options.prettyprint_structs, _("\
|
| -Set prettyprinting of structures."), _("\
|
| -Show prettyprinting of structures."), NULL,
|
| + &user_print_options.prettyformat_structs, _("\
|
| +Set pretty formatting of structures."), _("\
|
| +Show pretty formatting of structures."), NULL,
|
| NULL,
|
| - show_prettyprint_structs,
|
| + show_prettyformat_structs,
|
| &setprintlist, &showprintlist);
|
|
|
| add_setshow_boolean_cmd ("union", class_support,
|
| @@ -2597,11 +2790,11 @@ Show printing of unions interior to structures."), NULL,
|
| &setprintlist, &showprintlist);
|
|
|
| add_setshow_boolean_cmd ("array", class_support,
|
| - &user_print_options.prettyprint_arrays, _("\
|
| -Set prettyprinting of arrays."), _("\
|
| -Show prettyprinting of arrays."), NULL,
|
| + &user_print_options.prettyformat_arrays, _("\
|
| +Set pretty formatting of arrays."), _("\
|
| +Show pretty formatting of arrays."), NULL,
|
| NULL,
|
| - show_prettyprint_arrays,
|
| + show_prettyformat_arrays,
|
| &setprintlist, &showprintlist);
|
|
|
| add_setshow_boolean_cmd ("address", class_support,
|
|
|