X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fprintcmd.c;h=12249a004b0fe5b3c55d8ae21723e3b44b9673c9;hb=daac021a6ce0a672d67ff5d289851befbf0b9689;hp=d202330ab08160d2d3113f6eebeb679b192ceac6;hpb=8f78b329f08167847d9b94940b3bcae6ee292242;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/printcmd.c b/gdb/printcmd.c index d202330ab0..12249a004b 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -2,7 +2,7 @@ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010 Free Software Foundation, Inc. + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GDB. @@ -49,9 +49,10 @@ #include "parser-defs.h" #include "charset.h" #include "arch-utils.h" +#include "cli/cli-utils.h" #ifdef TUI -#include "tui/tui.h" /* For tui_active et.al. */ +#include "tui/tui.h" /* For tui_active et al. */ #endif #if defined(__MINGW32__) && !defined(PRINTF_HAS_LONG_LONG) @@ -61,7 +62,8 @@ # define USE_PRINTF_I64 0 #endif -extern int asm_demangle; /* Whether to demangle syms in asm printouts */ +extern int asm_demangle; /* Whether to demangle syms in asm + printouts. */ struct format_data { @@ -108,8 +110,9 @@ static void show_max_symbolic_offset (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("\ -The largest offset that will be printed in form is %s.\n"), + fprintf_filtered (file, + _("The largest offset that will be " + "printed in form is %s.\n"), value); } @@ -120,8 +123,8 @@ static void show_print_symbol_filename (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("\ -Printing of source filename and line number with is %s.\n"), + fprintf_filtered (file, _("Printing of source filename and " + "line number with is %s.\n"), value); } @@ -151,10 +154,10 @@ struct display /* Program space associated with `block'. */ struct program_space *pspace; - /* Innermost block required by this expression when evaluated */ + /* Innermost block required by this expression when evaluated. */ struct block *block; - /* Status of this display (enabled or disabled) */ + /* Status of this display (enabled or disabled). */ int enabled_p; }; @@ -165,13 +168,18 @@ static struct display *display_chain; static int display_number; -/* Prototypes for exported functions. */ +/* Walk the following statement or block through all displays. */ + +#define ALL_DISPLAYS(B) \ + for (B = display_chain; B; B = B->next) + +/* Prototypes for exported functions. */ void output_command (char *, int); void _initialize_printcmd (void); -/* Prototypes for local functions. */ +/* Prototypes for local functions. */ static void do_one_display (struct display *); @@ -260,7 +268,8 @@ decode_format (char **string_ptr, int oformat, int osize) val.size = osize ? 'b' : osize; break; case 's': - /* Display strings with byte size chars unless explicitly specified. */ + /* Display strings with byte size chars unless explicitly + specified. */ val.size = '\0'; break; @@ -296,8 +305,9 @@ print_formatted (struct value *val, int size, case 's': { struct type *elttype = value_type (val); + next_address = (value_address (val) - + val_print_string (elttype, + + val_print_string (elttype, NULL, value_address (val), -1, stream, options) * len); } @@ -323,10 +333,13 @@ print_formatted (struct value *val, int size, || TYPE_CODE (type) == TYPE_CODE_NAMESPACE) value_print (val, stream, options); else - /* User specified format, so don't look to the the type to - tell us what to do. */ - print_scalar_formatted (value_contents (val), type, - options, size, stream); + /* User specified format, so don't look to the type to tell us + what to do. */ + val_print_scalar_formatted (type, + value_contents_for_printing (val), + value_embedded_offset (val), + val, + options, size, stream); } /* Return builtin floating point type of same length as TYPE. @@ -349,11 +362,8 @@ float_type_from_length (struct type *type) } /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR, - according to OPTIONS and SIZE on STREAM. - Formats s and i are not supported at this level. - - This is how the elements of an array or structure are printed - with a format. */ + according to OPTIONS and SIZE on STREAM. Formats s and i are not + supported at this level. */ void print_scalar_formatted (const void *valaddr, struct type *type, @@ -365,18 +375,8 @@ print_scalar_formatted (const void *valaddr, struct type *type, unsigned int len = TYPE_LENGTH (type); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - /* If we get here with a string format, try again without it. Go - all the way back to the language printers, which may call us - again. */ - if (options->format == 's') - { - struct value_print_options opts = *options; - opts.format = 0; - opts.deref_ref = 0; - val_print (type, valaddr, 0, 0, stream, 0, &opts, - current_language); - return; - } + /* String printing should go through val_print_scalar_formatted. */ + gdb_assert (options->format != 's'); if (len > sizeof(LONGEST) && (TYPE_CODE (type) == TYPE_CODE_INT @@ -463,6 +463,7 @@ print_scalar_formatted (const void *valaddr, struct type *type, case 'a': { CORE_ADDR addr = unpack_pointer (type, valaddr); + print_address (gdbarch, addr, stream); } break; @@ -470,8 +471,8 @@ print_scalar_formatted (const void *valaddr, struct type *type, case 'c': { struct value_print_options opts = *options; - opts.format = 0; + opts.format = 0; if (TYPE_UNSIGNED (type)) type = builtin_type (gdbarch)->builtin_true_unsigned_char; else @@ -532,7 +533,7 @@ print_scalar_formatted (const void *valaddr, struct type *type, if (*cp == '\0') cp--; } - strcpy (buf, cp); + strncpy (buf, cp, sizeof (bits)); fputs_filtered (buf, stream); } break; @@ -615,11 +616,11 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, } /* Given an address ADDR return all the elements needed to print the - address in a symbolic form. NAME can be mangled or not depending + address in a symbolic form. NAME can be mangled or not depending on DO_DEMANGLE (and also on the asm_demangle global variable, - manipulated via ''set print asm-demangle''). Return 0 in case of - success, when all the info in the OUT paramters is valid. Return 1 - otherwise. */ + manipulated via ''set print asm-demangle''). Return 0 in case of + success, when all the info in the OUT paramters is valid. Return 1 + otherwise. */ int build_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr, /* IN */ @@ -769,6 +770,7 @@ print_address_demangle (struct gdbarch *gdbarch, CORE_ADDR addr, struct ui_file *stream, int do_demangle) { struct value_print_options opts; + get_user_print_options (&opts); if (addr == 0) { @@ -840,6 +842,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) if (format == 's') { struct type *char_type = NULL; + /* Search for "char16_t" or "char32_t" types or fall back to 8-bit char if type is not found. */ if (size == 'h') @@ -851,8 +854,8 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) else { if (size != '\0' && size != 'b') - warning (_("Unable to display strings with size '%c', using 'b' \ -instead."), size); + warning (_("Unable to display strings with " + "size '%c', using 'b' instead."), size); size = 'b'; val_type = builtin_type (next_gdbarch)->builtin_int8; } @@ -898,7 +901,7 @@ instead."), size); the address stored in LAST_EXAMINE_VALUE. FIXME: Should the disassembler be modified so that LAST_EXAMINE_VALUE is left with the byte sequence from the last complete - instruction fetched from memory? */ + instruction fetched from memory? */ last_examine_value = value_at_lazy (val_type, next_address); if (last_examine_value) @@ -1075,6 +1078,7 @@ set_command (char *exp, int from_tty) struct expression *expr = parse_expression (exp); struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); + evaluate_expression (expr); do_cleanups (old_chain); } @@ -1182,7 +1186,7 @@ address_info (char *exp, int from_tty) struct obj_section *section; CORE_ADDR load_addr, context_pc = 0; int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero - if exp is a field of `this'. */ + if exp is a field of `this'. */ if (exp == 0) error (_("Argument required.")); @@ -1268,7 +1272,8 @@ address_info (char *exp, int from_tty) Unfortunately DWARF 2 stores the frame-base (instead of the function) location in a function's symbol. Oops! For the moment enable this when/where applicable. */ - SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, context_pc, gdb_stdout); + SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, context_pc, + gdb_stdout); break; case LOC_REGISTER: @@ -1445,7 +1450,7 @@ x_command (char *exp, int from_tty) last_size = fmt.size; last_format = fmt.format; - /* Set a couple of internal variables if appropriate. */ + /* Set a couple of internal variables if appropriate. */ if (last_examine_value) { /* Make last address examined available to the user as $_. Use @@ -1556,35 +1561,26 @@ clear_displays (void) } } -/* Delete the auto-display number NUM. */ +/* Delete the auto-display DISPLAY. */ static void -delete_display (int num) +delete_display (struct display *display) { - struct display *d1, *d; + struct display *d; - if (!display_chain) - error (_("No display number %d."), num); + gdb_assert (display != NULL); - if (display_chain->number == num) - { - d1 = display_chain; - display_chain = d1->next; - free_display (d1); - } - else - for (d = display_chain;; d = d->next) + if (display_chain == display) + display_chain = display->next; + + ALL_DISPLAYS (d) + if (d->next == display) { - if (d->next == 0) - error (_("No display number %d."), num); - if (d->next->number == num) - { - d1 = d->next; - d->next = d1->next; - free_display (d1); - break; - } + d->next = display->next; + break; } + + free_display (display); } /* Delete some values from the auto-display chain. @@ -1608,25 +1604,31 @@ undisplay_command (char *args, int from_tty) while (*p) { p1 = p; - while (*p1 >= '0' && *p1 <= '9') - p1++; - if (*p1 && *p1 != ' ' && *p1 != '\t') - error (_("Arguments must be display numbers.")); - num = atoi (p); + num = get_number_or_range (&p1); + if (num == 0) + warning (_("bad display number at or near '%s'"), p); + else + { + struct display *d; - delete_display (num); + ALL_DISPLAYS (d) + if (d->number == num) + break; + if (d == NULL) + printf_unfiltered (_("No display number %d.\n"), num); + else + delete_display (d); + } p = p1; - while (*p == ' ' || *p == '\t') - p++; } dont_repeat (); } /* Display a single auto-display. Do nothing if the display cannot be printed in the current context, - or if the display is disabled. */ + or if the display is disabled. */ static void do_one_display (struct display *d) @@ -1653,6 +1655,7 @@ do_one_display (struct display *d) if (d->exp == NULL) { volatile struct gdb_exception ex; + TRY_CATCH (ex, RETURN_MASK_ALL) { innermost_block = NULL; @@ -1787,8 +1790,9 @@ disable_current_display (void) if (current_display_number >= 0) { disable_display (current_display_number); - fprintf_unfiltered (gdb_stderr, _("\ -Disabling display %d to avoid infinite recursion.\n"), + fprintf_unfiltered (gdb_stderr, + _("Disabling display %d to " + "avoid infinite recursion.\n"), current_display_number); } current_display_number = -1; @@ -1936,22 +1940,31 @@ print_variable_and_value (const char *name, struct symbol *var, struct frame_info *frame, struct ui_file *stream, int indent) { - struct value *val; - struct value_print_options opts; + volatile struct gdb_exception except; if (!name) name = SYMBOL_PRINT_NAME (var); fprintf_filtered (stream, "%s%s = ", n_spaces (2 * indent), name); + TRY_CATCH (except, RETURN_MASK_ERROR) + { + struct value *val; + struct value_print_options opts; - val = read_var_value (var, frame); - get_user_print_options (&opts); - common_val_print (val, stream, indent, &opts, current_language); + val = read_var_value (var, frame); + get_user_print_options (&opts); + common_val_print (val, stream, indent, &opts, current_language); + } + if (except.reason < 0) + fprintf_filtered(stream, "", name, + except.message); fprintf_filtered (stream, "\n"); } +/* printf "printf format string" ARG to STREAM. */ + static void -printf_command (char *arg, int from_tty) +ui_printf (char *arg, struct ui_file *stream) { char *f = NULL; char *s = arg; @@ -1969,9 +1982,7 @@ printf_command (char *arg, int from_tty) if (s == 0) error_no_arg (_("format-control string and values to print")); - /* Skip white space before format string */ - while (*s == ' ' || *s == '\t') - s++; + s = skip_spaces (s); /* A format string should follow, enveloped in double quotes. */ if (*s++ != '"') @@ -2021,7 +2032,7 @@ printf_command (char *arg, int from_tty) *f++ = '"'; break; default: - /* ??? TODO: handle other escape sequences */ + /* ??? TODO: handle other escape sequences. */ error (_("Unrecognized escape character \\%c in format string."), c); } @@ -2035,16 +2046,14 @@ printf_command (char *arg, int from_tty) /* Skip over " and following space and comma. */ s++; *f++ = '\0'; - while (*s == ' ' || *s == '\t') - s++; + s = skip_spaces (s); if (*s != ',' && *s != 0) error (_("Invalid argument syntax")); if (*s == ',') s++; - while (*s == ' ' || *s == '\t') - s++; + s = skip_spaces (s); /* Need extra space for the '\0's. Doubling the size is sufficient. */ substrings = alloca (strlen (string) * 2); @@ -2243,7 +2252,8 @@ printf_command (char *arg, int from_tty) } if (bad) - error (_("Inappropriate modifiers to format specifier '%c' in printf"), + error (_("Inappropriate modifiers to " + "format specifier '%c' in printf"), *f); f++; @@ -2253,6 +2263,7 @@ printf_command (char *arg, int from_tty) /* Windows' printf does support long long, but not the usual way. Convert %lld to %I64d. */ int length_before_ll = f - last_arg - 1 - lcount; + strncpy (current_substring, last_arg, length_before_ll); strcpy (current_substring + length_before_ll, "I64"); current_substring[length_before_ll + 3] = @@ -2264,6 +2275,7 @@ printf_command (char *arg, int from_tty) { /* Convert %ls or %lc to %s. */ int length_before_ls = f - last_arg - 2; + strncpy (current_substring, last_arg, length_before_ls); strcpy (current_substring + length_before_ls, "s"); current_substring += length_before_ls + 2; @@ -2284,6 +2296,7 @@ printf_command (char *arg, int from_tty) while (*s != '\0') { char *s1; + if (nargs == allocated_args) val_args = (struct value **) xrealloc ((char *) val_args, (allocated_args *= 2) @@ -2311,12 +2324,14 @@ printf_command (char *arg, int from_tty) gdb_byte *str; CORE_ADDR tem; int j; + tem = value_as_address (val_args[i]); /* This is a %s argument. Find the length of the string. */ for (j = 0;; j++) { gdb_byte c; + QUIT; read_memory (tem + j, &c, 1); if (c == 0) @@ -2329,7 +2344,7 @@ printf_command (char *arg, int from_tty) read_memory (tem, str, j); str[j] = 0; - printf_filtered (current_substring, (char *) str); + fprintf_filtered (stream, current_substring, (char *) str); } break; case wide_string_arg: @@ -2373,7 +2388,8 @@ printf_command (char *arg, int from_tty) &output, translit_char); obstack_grow_str0 (&output, ""); - printf_filtered (current_substring, obstack_base (&output)); + fprintf_filtered (stream, current_substring, + obstack_base (&output)); do_cleanups (inner_cleanup); } break; @@ -2405,7 +2421,8 @@ printf_command (char *arg, int from_tty) &output, translit_char); obstack_grow_str0 (&output, ""); - printf_filtered (current_substring, obstack_base (&output)); + fprintf_filtered (stream, current_substring, + obstack_base (&output)); do_cleanups (inner_cleanup); } break; @@ -2422,7 +2439,7 @@ printf_command (char *arg, int from_tty) if (inv) error (_("Invalid floating value found in program.")); - printf_filtered (current_substring, (double) val); + fprintf_filtered (stream, current_substring, (double) val); break; } case long_double_arg: @@ -2439,7 +2456,8 @@ printf_command (char *arg, int from_tty) if (inv) error (_("Invalid floating value found in program.")); - printf_filtered (current_substring, (long double) val); + fprintf_filtered (stream, current_substring, + (long double) val); break; } #else @@ -2449,7 +2467,8 @@ printf_command (char *arg, int from_tty) #if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG) { long long val = value_as_long (val_args[i]); - printf_filtered (current_substring, val); + + fprintf_filtered (stream, current_substring, val); break; } #else @@ -2458,13 +2477,15 @@ printf_command (char *arg, int from_tty) case int_arg: { int val = value_as_long (val_args[i]); - printf_filtered (current_substring, val); + + fprintf_filtered (stream, current_substring, val); break; } case long_arg: { long val = value_as_long (val_args[i]); - printf_filtered (current_substring, val); + + fprintf_filtered (stream, current_substring, val); break; } @@ -2472,10 +2493,11 @@ printf_command (char *arg, int from_tty) case decfloat_arg: { const gdb_byte *param_ptr = value_contents (val_args[i]); + #if defined (PRINTF_HAS_DECFLOAT) /* If we have native support for Decimal floating printing, handle it here. */ - printf_filtered (current_substring, param_ptr); + fprintf_filtered (stream, current_substring, param_ptr); #else /* As a workaround until vasprintf has native support for DFP @@ -2564,7 +2586,7 @@ printf_command (char *arg, int from_tty) decimal_to_string (dfp_ptr, dfp_len, byte_order, decstr); /* Print the DFP value. */ - printf_filtered (current_substring, decstr); + fprintf_filtered (stream, current_substring, decstr); break; #endif @@ -2592,6 +2614,7 @@ printf_command (char *arg, int from_tty) while (*p) { int is_percent = (*p == '%'); + *fmt_p++ = *p++; if (is_percent) { @@ -2618,13 +2641,13 @@ printf_command (char *arg, int from_tty) *fmt_p++ = 'l'; *fmt_p++ = 'x'; *fmt_p++ = '\0'; - printf_filtered (fmt, val); + fprintf_filtered (stream, fmt, val); } else { *fmt_p++ = 's'; *fmt_p++ = '\0'; - printf_filtered (fmt, "(nil)"); + fprintf_filtered (stream, fmt, "(nil)"); } break; @@ -2642,11 +2665,38 @@ printf_command (char *arg, int from_tty) puts_filtered here. Also, we pass a dummy argument because some platforms have modified GCC to include -Wformat-security by default, which will warn here if there is no argument. */ - printf_filtered (last_arg, 0); + fprintf_filtered (stream, last_arg, 0); } do_cleanups (old_cleanups); } +/* Implement the "printf" command. */ + +static void +printf_command (char *arg, int from_tty) +{ + ui_printf (arg, gdb_stdout); +} + +/* Implement the "eval" command. */ + +static void +eval_command (char *arg, int from_tty) +{ + struct ui_file *ui_out = mem_fileopen (); + struct cleanup *cleanups = make_cleanup_ui_file_delete (ui_out); + char *expanded; + + ui_printf (arg, ui_out); + + expanded = ui_file_xstrdup (ui_out, NULL); + make_cleanup (xfree, expanded); + + execute_command (expanded, from_tty); + + do_cleanups (cleanups); +} + void _initialize_printcmd (void) { @@ -2749,7 +2799,7 @@ Use \"set variable\" for variables with names identical to set subcommands.\n\ \nWith a subcommand, this command modifies parts of the gdb environment.\n\ You can see these environment settings with the \"show\" command.")); - /* "call" is the same as "set", but handy for dbx users to call fns. */ + /* "call" is the same as "set", but handy for dbx users to call fns. */ c = add_com ("call", class_vars, call_command, _("\ Call a function in the program.\n\ The argument is the function name and arguments, in the notation of the\n\ @@ -2810,4 +2860,8 @@ Show printing of source filename and line number with ."), NULL, NULL, show_print_symbol_filename, &setprintlist, &showprintlist); + + add_com ("eval", no_class, eval_command, _("\ +Convert \"printf format string\", arg1, arg2, arg3, ..., argn to\n\ +a command line, and call it.")); }