[RFA 1/4] Add previous_saved_command_line to allow a command to repeat a previous command.

Philippe Waroquiers philippe.waroquiers@skynet.be
Sat Apr 20 21:22:00 GMT 2019


Currently, a previous command can be repeated when the user types an
empty line.  This is implemented in handle_line_of_input by
returning saved_command_line in case an empty line has been input.

If we want a command to repeat the previous command, we need to save
the previous saved_command_line, as when a command runs, the saved_command_line
already contains the current command line of the command being executed.

gdb/ChangeLog
2019-04-20  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* top.h (previous_saved_command_line): New declaration.
	* main.c (captured_main_1): Initialize previous_saved_command_line.
	* event-top.c (handle_line_of_input): Copy saved_command_line into
	previous_saved_command_line before replacing saved_command_line.
	* command.h (repeat_previous): New declaration.
	* top.c (previous_saved_command_line): New variable.
	(repeat_previous): New function.
---
 gdb/command.h   |  1 +
 gdb/event-top.c |  3 ++-
 gdb/main.c      |  1 +
 gdb/top.c       | 29 ++++++++++++++++++++++++++++-
 gdb/top.h       |  1 +
 5 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/gdb/command.h b/gdb/command.h
index 4a239a7196..20a182db0c 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -449,6 +449,7 @@ extern void cmd_show_list (struct cmd_list_element *, int, const char *);
 extern void error_no_arg (const char *) ATTRIBUTE_NORETURN;
 
 extern void dont_repeat (void);
+extern void repeat_previous (void);
 
 extern scoped_restore_tmpl<int> prevent_dont_repeat (void);
 
diff --git a/gdb/event-top.c b/gdb/event-top.c
index cd54eb5a2c..6ff6203a0a 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -724,7 +724,8 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
   /* Save into global buffer if appropriate.  */
   if (repeat)
     {
-      xfree (saved_command_line);
+      xfree (previous_saved_command_line);
+      previous_saved_command_line = saved_command_line;
       saved_command_line = xstrdup (cmd);
       return saved_command_line;
     }
diff --git a/gdb/main.c b/gdb/main.c
index e67efc7bcd..c6295ab500 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -500,6 +500,7 @@ captured_main_1 (struct captured_main_args *context)
   notice_open_fds ();
 
   saved_command_line = (char *) xstrdup ("");
+  previous_saved_command_line = (char *) xstrdup ("");
 
 #ifdef __MINGW32__
   /* Ensure stderr is unbuffered.  A Cygwin pty or pipe is implemented
diff --git a/gdb/top.c b/gdb/top.c
index 9a1c258d3f..b46330ff2c 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -134,8 +134,13 @@ show_confirm (struct ui_file *file, int from_tty,
 char *current_directory;
 
 /* The last command line executed on the console.  Used for command
-   repetitions.  */
+   repetitions when the user enters an empty line.  */
 char *saved_command_line;
+/* The previous last command line executed on the console.  Used for command
+   repetitions when a command want to relaunch the previously launched
+   command.  We need this as when a command is running, saved_command_line
+   already contains the line of the currently executing command.  */
+char *previous_saved_command_line;
 
 /* Nonzero if the current command is modified by "server ".  This
    affects things like recording into the command history, commands
@@ -711,6 +716,28 @@ dont_repeat (void)
     *saved_command_line = 0;
 }
 
+/* Command call this if they want to repeat the previous command.
+   Such commands repeating the previous command must indicate
+   to not repeat themselves, to avoid recursive repeat.
+   repeat_previous will mark the current command as not repeating,
+   and will restore saved_command_line from the
+   previous_saved_command_line, so that the currently executing
+   command can repeat it by using saved_command_line.  */
+
+void
+repeat_previous (void)
+{
+  char *tmp = previous_saved_command_line;
+
+  /* Do not repeat this command, as this command is a repeating command.  */
+  dont_repeat ();
+
+  /* We cannot free saved_command_line, as this line is being executed,
+     so swap it with previous_saved_command_line.  */
+  previous_saved_command_line = saved_command_line;
+  saved_command_line = tmp;
+}
+
 /* Prevent dont_repeat from working, and return a cleanup that
    restores the previous state.  */
 
diff --git a/gdb/top.h b/gdb/top.h
index 025d9389d6..ff8cc10e55 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -218,6 +218,7 @@ extern void ui_unregister_input_event_handler (struct ui *ui);
 
 /* From top.c.  */
 extern char *saved_command_line;
+extern char *previous_saved_command_line;
 extern int confirm;
 extern int inhibit_gdbinit;
 extern const char gdbinit[];
-- 
2.20.1



More information about the Gdb-patches mailing list