aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/event-top.c68
-rw-r--r--gdb/event-top.h6
-rw-r--r--gdb/top.c1
3 files changed, 63 insertions, 12 deletions
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 6261020..3566431 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -742,6 +742,25 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
return cmd;
}
+/* See event-top.h. */
+
+void
+gdb_rl_deprep_term_function (void)
+{
+#ifdef RL_STATE_EOF
+ gdb::optional<scoped_restore_tmpl<int>> restore_eof_found;
+
+ if (RL_ISSTATE (RL_STATE_EOF))
+ {
+ printf_unfiltered ("quit\n");
+ restore_eof_found.emplace (&rl_eof_found, 0);
+ }
+
+#endif /* RL_STATE_EOF */
+
+ rl_deprep_terminal ();
+}
+
/* Handle a complete line of input. This is called by the callback
mechanism within the readline library. Deal with incomplete
commands as well, by saving the partial input in a global
@@ -764,26 +783,51 @@ command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
This happens at the end of a testsuite run, after Expect has
hung up but GDB is still alive. In such a case, we just quit
gdb killing the inferior program too. This also happens if the
- user sends EOF, which is usually bound to ctrl+d.
+ user sends EOF, which is usually bound to ctrl+d. */
+
+#ifndef RL_STATE_EOF
+ /* When readline is using bracketed paste mode, then, when eof is
+ received, readline will emit the control sequence to leave
+ bracketed paste mode.
+
+ This control sequence ends with \r, which means that the "quit" we
+ are about to print will overwrite the prompt on this line.
+
+ The solution to this problem is to actually print the "quit"
+ message from gdb_rl_deprep_term_function (see above), however, we
+ can only do that if we can know, in that function, when eof was
+ received.
+
+ Unfortunately, with older versions of readline, it is not possible
+ in the gdb_rl_deprep_term_function to know if eof was received or
+ not, and, as GDB can be built against the system readline, which
+ could be older than the readline in GDB's repository, then we
+ can't be sure that we can work around this prompt corruption in
+ the gdb_rl_deprep_term_function function.
- What we want to do in this case is print "quit" after the GDB
- prompt, as if the user had just typed "quit" and pressed return.
+ If we get here, RL_STATE_EOF is not defined. This indicates that
+ we are using an older readline, and couldn't print the quit
+ message in gdb_rl_deprep_term_function. So, what we do here is
+ check to see if bracketed paste mode is on or not. If it's on
+ then we print a \n and then the quit, this means the user will
+ see:
- This used to work just fine, but unfortunately, doesn't play well
- with readline's bracketed paste mode. By the time we get here,
- readline has already sent the control sequence to leave bracketed
- paste mode, and this sequence ends with a '\r' character. As a
- result, if bracketed paste mode is on, and we print quit here,
- then this will overwrite the prompt.
+ (gdb)
+ quit
- To work around this issue, when bracketed paste mode is enabled,
- we first print '\n' to move to the next line, and then print the
- quit. This isn't ideal, but avoids corrupting the prompt. */
+ Rather than the usual:
+
+ (gdb) quit
+
+ Which we will get with a newer readline, but this really is the
+ best we can do with older versions of readline. */
const char *value = rl_variable_value ("enable-bracketed-paste");
if (value != nullptr && strcmp (value, "on") == 0
&& ((rl_readline_version >> 8) & 0xff) > 0x07)
printf_unfiltered ("\n");
printf_unfiltered ("quit\n");
+#endif
+
execute_command ("quit", 1);
}
else if (cmd == NULL)
diff --git a/gdb/event-top.h b/gdb/event-top.h
index 078482b..722e636 100644
--- a/gdb/event-top.h
+++ b/gdb/event-top.h
@@ -70,6 +70,12 @@ extern void gdb_rl_callback_handler_install (const char *prompt);
currently installed. */
extern void gdb_rl_callback_handler_reinstall (void);
+/* Called by readline after a complete line has been gathered from the
+ user, but before the line is dispatched to back to GDB. This function
+ is a wrapper around readline's builtin rl_deprep_terminal function, and
+ handles the case where readline received EOF. */
+extern void gdb_rl_deprep_term_function (void);
+
typedef void (*segv_handler_t) (int);
/* On construction, replaces the current thread's SIGSEGV handler with
diff --git a/gdb/top.c b/gdb/top.c
index 1cfffbe..73cb389 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -2225,6 +2225,7 @@ init_main (void)
rl_completion_display_matches_hook = cli_display_match_list;
rl_readline_name = "gdb";
rl_terminal_name = getenv ("TERM");
+ rl_deprep_term_function = gdb_rl_deprep_term_function;
/* The name for this defun comes from Bash, where it originated.
15 is Control-o, the same binding this function has in Bash. */