From 85c4be7c83b80acf647e6ffcaed0f0cdbcb8c3eb Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 12 Oct 2017 08:27:21 -0600 Subject: [PATCH] Add set_repeat_arguments function The "x", "list", and "show commands" commands have special repetition behavior: repeating the command doesn't re-run it with the same arguments This is currently implemented by modifying the passed-in argument; but that won't work properly with const arguments (and seems pretty obscure besides). This patch adds a new "set_repeat_arguments" function and changes the relevant places to call it. gdb/ChangeLog 2017-11-07 Tom Tromey * printcmd.c (x_command): Call set_repeat_arguments. * cli/cli-cmds.c (list_command): Call set_repeat_arguments. * top.c (repeat_arguments): New global. (set_repeat_arguments): New function. (execute_command): Handle repeat_arguments. (show_commands): Calls set_repeat_arguments. * command.h (set_repeat_arguments): Declare. --- gdb/ChangeLog | 10 ++++++++++ gdb/cli/cli-cmds.c | 2 +- gdb/command.h | 5 +++++ gdb/printcmd.c | 2 +- gdb/top.c | 29 ++++++++++++++++++++++++----- gdb/value.c | 5 +---- 6 files changed, 42 insertions(+), 11 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ce8110fc27..740d75f204 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2017-11-07 Tom Tromey + + * printcmd.c (x_command): Call set_repeat_arguments. + * cli/cli-cmds.c (list_command): Call set_repeat_arguments. + * top.c (repeat_arguments): New global. + (set_repeat_arguments): New function. + (execute_command): Handle repeat_arguments. + (show_commands): Calls set_repeat_arguments. + * command.h (set_repeat_arguments): Declare. + 2017-11-07 Tom Tromey * stack.c (backtrace_command): Use std::string. diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index a1c308a38d..a8edb1341f 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -1082,7 +1082,7 @@ list_command (char *arg, int from_tty) turn it into the no-arg variant. */ if (from_tty) - *arg = 0; + set_repeat_arguments (""); if (dummy_beg && sal_end.symtab == 0) error (_("No default source file yet. Do \"help list\".")); diff --git a/gdb/command.h b/gdb/command.h index a99544563c..63c76589c8 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -445,6 +445,11 @@ extern void dont_repeat (void); extern scoped_restore_tmpl prevent_dont_repeat (void); +/* Set the arguments that will be passed if the current command is + repeated. Note that the passed-in string must be a constant. */ + +extern void set_repeat_arguments (const char *args); + /* Used to mark commands that don't do anything. If we just leave the function field NULL, the command is interpreted as a help topic, or as a class of commands. */ diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 017c7bee07..51e3d38479 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1646,7 +1646,7 @@ x_command (char *exp, int from_tty) repeated with Newline. But don't clobber a user-defined command's definition. */ if (from_tty) - *exp = 0; + set_repeat_arguments (""); val = evaluate_expression (expr.get ()); if (TYPE_IS_REFERENCE (value_type (val))) val = coerce_ref (val); diff --git a/gdb/top.c b/gdb/top.c index f006c669a1..14abfecbd4 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -522,6 +522,19 @@ maybe_wait_sync_command_done (int was_sync) wait_sync_command_done (); } +/* If not NULL, the arguments that should be passed if the current + command is repeated. */ + +static const char *repeat_arguments; + +/* See command.h. */ + +void +set_repeat_arguments (const char *args) +{ + repeat_arguments = args; +} + /* Execute the line P as a command, in the current user context. Pass FROM_TTY as second argument to the defining function. */ @@ -564,6 +577,10 @@ execute_command (char *p, int from_tty) c = lookup_cmd (&cmd, cmdlist, "", 0, 1); p = (char *) cmd; + scoped_restore save_repeat_args + = make_scoped_restore (&repeat_arguments, nullptr); + char *args_pointer = p; + /* Pass null arg rather than an empty one. */ arg = *p ? p : 0; @@ -612,6 +629,11 @@ execute_command (char *p, int from_tty) /* If this command has been post-hooked, run the hook last. */ execute_cmd_post_hook (c); + if (repeat_arguments != NULL) + { + gdb_assert (strlen (args_pointer) >= strlen (repeat_arguments)); + strcpy (args_pointer, repeat_arguments); + } } check_frame_language_change (); @@ -1667,7 +1689,7 @@ dont_repeat_command (char *ignored, int from_tty) /* Number of commands to print in each call to show_commands. */ #define Hist_print 10 void -show_commands (char *args, int from_tty) +show_commands (const char *args, int from_tty) { /* Index for history commands. Relative to history_base. */ int offset; @@ -1721,10 +1743,7 @@ show_commands (char *args, int from_tty) "show commands +" does. This is unnecessary if arg is null, because "show commands +" is not useful after "show commands". */ if (from_tty && args) - { - args[0] = '+'; - args[1] = '\0'; - } + set_repeat_arguments ("+"); } /* Update the size of our command history file to HISTORY_SIZE. diff --git a/gdb/value.c b/gdb/value.c index 8fd391e637..ade5ebd78b 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -2003,10 +2003,7 @@ show_values (char *num_exp, int from_tty) "show values +". If num_exp is null, this is unnecessary, since "show values +" is not useful after "show values". */ if (from_tty && num_exp) - { - num_exp[0] = '+'; - num_exp[1] = '\0'; - } + set_repeat_arguments ("+"); } enum internalvar_kind -- 2.34.1