diff options
-rw-r--r-- | gdb/event-top.c | 68 | ||||
-rw-r--r-- | gdb/event-top.h | 6 | ||||
-rw-r--r-- | gdb/top.c | 1 |
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 @@ -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. */ |