aboutsummaryrefslogtreecommitdiff
path: root/gdb/printcmd.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2019-06-13 00:06:53 +0100
committerPedro Alves <palves@redhat.com>2019-06-13 00:18:24 +0100
commit7d8062de98203eeec70d4439ab460b9ef50a2e0f (patch)
tree3ac498d1e7a836b503e4a178ca35062255986f09 /gdb/printcmd.c
parent9d0faba9f52b898f0be539bc4d6fbd084772259d (diff)
downloadgdb-7d8062de98203eeec70d4439ab460b9ef50a2e0f.zip
gdb-7d8062de98203eeec70d4439ab460b9ef50a2e0f.tar.gz
gdb-7d8062de98203eeec70d4439ab460b9ef50a2e0f.tar.bz2
Make "print" and "compile print" support -OPT options
This patch adds support for "print -option optval --", etc. Likewise for "compile print". We'll get: ~~~~~~ (gdb) help print Print value of expression EXP. Usage: print [[OPTION]... --] [/FMT] [EXP] Options: -address [on|off] Set printing of addresses. -array [on|off] Set pretty formatting of arrays. -array-indexes [on|off] Set printing of array indexes. -elements NUMBER|unlimited Set limit on string chars or array elements to print. "unlimited" causes there to be no limit. -max-depth NUMBER|unlimited Set maximum print depth for nested structures, unions and arrays. When structures, unions, or arrays are nested beyond this depth then they will be replaced with either '{...}' or '(...)' depending on the language. Use "unlimited" to print the complete structure. -null-stop [on|off] Set printing of char arrays to stop at first null char. -object [on|off] Set printing of C++ virtual function tables. -pretty [on|off] Set pretty formatting of structures. -repeats NUMBER|unlimited Set threshold for repeated print elements. "unlimited" causes all elements to be individually printed. -static-members [on|off] Set printing of C++ static members. -symbol [on|off] Set printing of symbol names when printing pointers. -union [on|off] Set printing of unions interior to structures. -vtbl [on|off] Set printing of C++ virtual function tables. Note: because this command accepts arbitrary expressions, if you specify any command option, you must use a double dash ("--") to mark the end of option processing. E.g.: "print -o -- myobj". ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I want to highlight the comment above about "--". At first, I thought we could make the print command parse the options, and if the option wasn't recognized, fallback to parsing as an expression. Then, if the user wanted to disambiguate, he'd use the "--" option delimiter. For example, if you had a variable called "object" and you wanted to print its negative, you'd have to do: (gdb) print -- -object After getting that working, I saw that gdb.pascal/floats.exp regressed, in these tests: gdb_test "print -r" " = -1\\.2(499.*|5|500.*)" gdb_test "print -(r)" " = -1.2(499.*|5|500.*)" gdb_test "print -(r + s)" " = -3\\.4(499.*|5|500.*)" It's the first one that I found most concerning. It regressed because "-r" is the abbreviation of "-raw". I realized then that the behavior change was a bit risker than I'd like, considering scripts, wrappers around gdb, etc., and even user expectation. So instead, I made the print command _require_ the "--" options delimiter if you want to specify any option. So: (gdb) print -r is parsed as an expression, and (gdb) print -r -- is parsed as an option. I noticed that that's also what lldb's expr (the equivalent of print) does to handle the same problem. Going back the options themselves, note that: - you can shorten option names, as long as unambiguous. - For boolean options, 0/1 stand for off/on. - For boolean options, "true" is implied. So these are all equivalent: (gdb) print -object on -static-members off -pretty on -- foo (gdb) print -object -static-members off -pretty -- foo (gdb) print -object -static-members 0 -pretty -- foo (gdb) print -o -st 0 -p -- foo TAB completion is fully supported: (gdb) p -[TAB] -address -elements -pretty -symbol -array -null-stop -repeats -union -array-indexes -object -static-members -vtbl Note that the code is organized such that some of the options and the "set/show" commands code is shared. In particular, the "print" options and the corresponding "set print" commands are defined with the same structures. The commands are installed with the gdb::option::add_setshow_cmds_for_options function. gdb/ChangeLog: 2019-06-13 Pedro Alves <palves@redhat.com> * compile/compile.c: Include "cli/cli-option.h". (compile_print_value): Scope data pointer is now a value_print_options pointer; adjust. (compile_print_command): Process options. Scope data pointer is now a value_print_options pointer; adjust. (_initialize_compile): Update "compile print"'s help to include supported options. Install a completer for "compile print". * cp-valprint.c (show_vtblprint, show_objectprint) (show_static_field_print): Delete. (_initialize_cp_valprint): Don't install "set print static-members", "set print vtbl", "set print object" here. * printcmd.c: Include "cli/cli-option.h" and "common/gdb_optional.h". (print_command_parse_format): Rework to fill in a value_print_options instead of a format_data. (print_value): Change parameter type from format_data pointer to value_print_options reference. Adjust. (print_command_1): Process options. Adjust to pass down a value_print_options. (print_command_completer): New. (_initialize_printcmd): Install print_command_completer as handle_brkchars completer for the "print" command. Update "print"'s help to include supported options. * valprint.c: Include "cli/cli-option.h". (show_vtblprint, show_objectprint, show_static_field_print): Moved here from cp-valprint.c. (boolean_option_def, uinteger_option_def) (value_print_option_defs, make_value_print_options_def_group): New. Use gdb::option::add_setshow_cmds_for_options to install "set print elements", "set print null-stop", "set print repeats", "set print pretty", "set print union", "set print array", "set print address", "set print symbol", "set print array-indexes". * valprint.h: Include <string> and "cli/cli-option.h". (make_value_print_options_def_group): Declare. (print_value): Change parameter type from format_data pointer to value_print_options reference. (print_command_completer): Declare. gdb/testsuite/ChangeLog: 2019-06-13 Pedro Alves <palves@redhat.com> * gdb.base/options.exp: Build executable. (test-print): New procedure. (top level): Call it, once for "print" and another for "compile print".
Diffstat (limited to 'gdb/printcmd.c')
-rw-r--r--gdb/printcmd.c94
1 files changed, 64 insertions, 30 deletions
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 9e84594..0509360 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -45,11 +45,13 @@
#include "charset.h"
#include "arch-utils.h"
#include "cli/cli-utils.h"
+#include "cli/cli-option.h"
#include "cli/cli-script.h"
#include "cli/cli-style.h"
#include "common/format.h"
#include "source.h"
#include "common/byte-vector.h"
+#include "common/gdb_optional.h"
/* Last specified output format. */
@@ -1117,40 +1119,41 @@ validate_format (struct format_data fmt, const char *cmdname)
fmt.format, cmdname);
}
-/* Parse print command format string into *FMTP and update *EXPP.
+/* Parse print command format string into *OPTS and update *EXPP.
CMDNAME should name the current command. */
void
print_command_parse_format (const char **expp, const char *cmdname,
- struct format_data *fmtp)
+ value_print_options *opts)
{
const char *exp = *expp;
if (exp && *exp == '/')
{
+ format_data fmt;
+
exp++;
- *fmtp = decode_format (&exp, last_format, 0);
- validate_format (*fmtp, cmdname);
- last_format = fmtp->format;
+ fmt = decode_format (&exp, last_format, 0);
+ validate_format (fmt, cmdname);
+ last_format = fmt.format;
+
+ opts->format = fmt.format;
+ opts->raw = fmt.raw;
}
else
{
- fmtp->count = 1;
- fmtp->format = 0;
- fmtp->size = 0;
- fmtp->raw = 0;
+ opts->format = 0;
+ opts->raw = 0;
}
*expp = exp;
}
-/* Print VAL to console according to *FMTP, including recording it to
- the history. */
+/* See valprint.h. */
void
-print_value (struct value *val, const struct format_data *fmtp)
+print_value (value *val, const value_print_options &opts)
{
- struct value_print_options opts;
int histindex = record_latest_value (val);
annotate_value_history_begin (histindex, value_type (val));
@@ -1159,28 +1162,31 @@ print_value (struct value *val, const struct format_data *fmtp)
annotate_value_history_value ();
- get_formatted_print_options (&opts, fmtp->format);
- opts.raw = fmtp->raw;
-
- print_formatted (val, fmtp->size, &opts, gdb_stdout);
+ print_formatted (val, 0, &opts, gdb_stdout);
printf_filtered ("\n");
annotate_value_history_end ();
}
-/* Evaluate string EXP as an expression in the current language and
- print the resulting value. EXP may contain a format specifier as the
- first argument ("/x myvar" for example, to print myvar in hex). */
+/* Implementation of the "print" and "call" commands. */
static void
-print_command_1 (const char *exp, int voidprint)
+print_command_1 (const char *args, int voidprint)
{
struct value *val;
- struct format_data fmt;
+ value_print_options print_opts;
+
+ get_user_print_options (&print_opts);
+ /* Override global settings with explicit options, if any. */
+ auto group = make_value_print_options_def_group (&print_opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group);
+
+ print_command_parse_format (&args, "print", &print_opts);
- print_command_parse_format (&exp, "print", &fmt);
+ const char *exp = args;
- if (exp && *exp)
+ if (exp != nullptr && *exp)
{
expression_up expr = parse_expression (exp);
val = evaluate_expression (expr.get ());
@@ -1190,7 +1196,23 @@ print_command_1 (const char *exp, int voidprint)
if (voidprint || (val && value_type (val) &&
TYPE_CODE (value_type (val)) != TYPE_CODE_VOID))
- print_value (val, &fmt);
+ print_value (val, print_opts);
+}
+
+/* See valprint.h. */
+
+void
+print_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /*word*/)
+{
+ const auto group = make_value_print_options_def_group (nullptr);
+ if (gdb::option::complete_options
+ (tracker, &text, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group))
+ return;
+
+ const char *word = advance_to_expression_complete_word_point (tracker, text);
+ expression_completer (ignore, tracker, text, word);
}
static void
@@ -2761,7 +2783,7 @@ Usage: call EXP\n\
The argument is the function name and arguments, in the notation of the\n\
current working language. The result is printed and saved in the value\n\
history, if it is not void."));
- set_cmd_completer (c, expression_completer);
+ set_cmd_completer_handle_brkchars (c, print_command_completer);
add_cmd ("variable", class_vars, set_command, _("\
Evaluate expression EXP and assign result to variable VAR\n\
@@ -2775,9 +2797,18 @@ This may usually be abbreviated to simply \"set\"."),
&setlist);
add_alias_cmd ("var", "variable", class_vars, 0, &setlist);
- c = add_com ("print", class_vars, print_command, _("\
+ const auto print_opts = make_value_print_options_def_group (nullptr);
+
+ static const std::string print_help = gdb::option::build_help (N_("\
Print value of expression EXP.\n\
-Usage: print[/FMT] EXP\n\
+Usage: print [[OPTION]... --] [/FMT] [EXP]\n\
+\n\
+Options:\n\
+%OPTIONS%\
+Note: because this command accepts arbitrary expressions, if you\n\
+specify any command option, you must use a double dash (\"--\")\n\
+to mark the end of option processing. E.g.: \"print -o -- myobj\".\n\
+\n\
Variables accessible are those of the lexical environment of the selected\n\
stack frame, plus all those whose scope is global or an entire file.\n\
\n\
@@ -2797,8 +2828,11 @@ where FOO is stored, etc. FOO must be an expression whose value\n\
resides in memory.\n\
\n\
EXP may be preceded with /FMT, where FMT is a format letter\n\
-but no count or size letter (see \"x\" command)."));
- set_cmd_completer (c, expression_completer);
+but no count or size letter (see \"x\" command)."),
+ print_opts);
+
+ c = add_com ("print", class_vars, print_command, print_help.c_str ());
+ set_cmd_completer_handle_brkchars (c, print_command_completer);
add_com_alias ("p", "print", class_vars, 1);
add_com_alias ("inspect", "print", class_vars, 1);