aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog9
-rw-r--r--gdb/event-top.c13
-rw-r--r--gdb/event-top.h1
-rw-r--r--gdb/tui/tui-io.c28
4 files changed, 49 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e16f28f..326a0d6 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,14 @@
2014-11-23 Patrick Palka <patrick@parcs.ath.cx>
+ * event-top.h (call_stdin_event_handler_again_p): Declare.
+ * event-top.c (call_stdin_event_handler_again_p): Define.
+ (stdin_event_handler): Use it.
+ * tui/tui-io.c (tui_getc): Prepare to call the stdin event
+ handler again if there is pending input following a
+ start sequence.
+
+2014-11-23 Patrick Palka <patrick@parcs.ath.cx>
+
Pushed by Joel Brobecker <brobecker@adacore.com>
* linux-fork.c (checkpoint_command): Print index of new
checkpoint in response message.
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 282c0fe..cb438ac 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -119,6 +119,11 @@ int exec_done_display_p = 0;
read commands from. */
int input_fd;
+/* Used by the stdin event handler to compensate for missed stdin events.
+ Setting this to a non-zero value inside an stdin callback makes the callback
+ run again. */
+int call_stdin_event_handler_again_p;
+
/* Signal handling variables. */
/* Each of these is a pointer to a function that the event loop will
invoke if the corresponding signal has received. The real signal
@@ -420,7 +425,13 @@ stdin_event_handler (int error, gdb_client_data client_data)
quit_command ((char *) 0, stdin == instream);
}
else
- (*call_readline) (client_data);
+ {
+ do
+ {
+ call_stdin_event_handler_again_p = 0;
+ (*call_readline) (client_data);
+ } while (call_stdin_event_handler_again_p != 0);
+ }
}
/* Re-enable stdin after the end of an execution command in
diff --git a/gdb/event-top.h b/gdb/event-top.h
index ac0d47b..919287e 100644
--- a/gdb/event-top.h
+++ b/gdb/event-top.h
@@ -61,6 +61,7 @@ extern void (*call_readline) (void *);
extern void (*input_handler) (char *);
extern int input_fd;
extern void (*after_char_processing_hook) (void);
+extern int call_stdin_event_handler_again_p;
/* Wrappers for rl_callback_handler_remove and
rl_callback_handler_install that keep track of whether the callback
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 601d278..aa1d1c7 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -691,7 +691,33 @@ tui_getc (FILE *fp)
TUI_CMD_WIN->detail.command_info.curch = 0;
if (ch == KEY_BACKSPACE)
return '\b';
-
+
+ if (async_command_editing_p && key_is_start_sequence (ch))
+ {
+ int ch_pending;
+
+ nodelay (w, TRUE);
+ ch_pending = wgetch (w);
+ nodelay (w, FALSE);
+
+ /* If we have pending input following a start sequence, call the stdin
+ event handler again because ncurses may have already read and stored
+ the input into its internal buffer, meaning that we won't get an stdin
+ event for it. If we don't compensate for this missed stdin event, key
+ sequences as Alt_F (^[f) will not behave promptly.
+
+ (We only compensates for the missed 2nd byte of a key sequence because
+ 2-byte sequences are by far the most commonly used. ncurses may have
+ buffered a larger, 3+-byte key sequence though it remains to be seen
+ whether it is useful to compensate for all the bytes of such
+ sequences.) */
+ if (ch_pending != ERR)
+ {
+ ungetch (ch_pending);
+ call_stdin_event_handler_again_p = 1;
+ }
+ }
+
return ch;
}