- Backport readline history for input mode commands like `command' (BZ
215816). - Resolves: rhbz#215816
This commit is contained in:
parent
65bc5f9692
commit
3cdd4d2bbe
3 changed files with 206 additions and 125 deletions
|
|
@ -1,42 +1,165 @@
|
|||
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=215816
|
||||
|
||||
|
||||
Index: ./readline/readline.c
|
||||
===================================================================
|
||||
RCS file: /cvs/src/src/readline/readline.c,v
|
||||
retrieving revision 1.10
|
||||
diff -u -p -r1.10 readline.c
|
||||
--- ./readline/readline.c 5 May 2006 18:26:12 -0000 1.10
|
||||
+++ ./readline/readline.c 22 Nov 2006 19:40:17 -0000
|
||||
@@ -295,6 +295,7 @@ readline (prompt)
|
||||
const char *prompt;
|
||||
{
|
||||
char *value;
|
||||
+ int in_callback;
|
||||
2007-01-03 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* Makefile.in (top.o): Update.
|
||||
* top.c (gdb_readline_wrapper_done, gdb_readline_wrapper_result)
|
||||
(saved_after_char_processing_hook, gdb_readline_wrapper_line)
|
||||
(struct gdb_readline_wrapper_cleanup, gdb_readline_wrapper_cleanup):
|
||||
New.
|
||||
(gdb_readline_wrapper): Rewrite to use asynchronous readline.
|
||||
|
||||
|
||||
--- ./gdb/Makefile.in 3 Jan 2007 18:05:43 -0000 1.864
|
||||
+++ ./gdb/Makefile.in 3 Jan 2007 21:22:46 -0000
|
||||
@@ -2782,7 +2782,7 @@ top.o: top.c $(defs_h) $(gdbcmd_h) $(cal
|
||||
$(annotate_h) $(completer_h) $(top_h) $(version_h) $(serial_h) \
|
||||
$(doublest_h) $(gdb_assert_h) $(readline_h) $(readline_history_h) \
|
||||
$(event_top_h) $(gdb_string_h) $(gdb_stat_h) $(ui_out_h) \
|
||||
- $(cli_out_h) $(main_h)
|
||||
+ $(cli_out_h) $(main_h) $(event_loop_h)
|
||||
tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(gdbtypes_h) \
|
||||
$(expression_h) $(gdbcmd_h) $(value_h) $(target_h) $(language_h) \
|
||||
$(gdb_string_h) $(inferior_h) $(tracepoint_h) $(remote_h) \
|
||||
--- ./gdb/top.c 1 Jan 2007 05:57:49 -0000 1.116
|
||||
+++ ./gdb/top.c 3 Jan 2007 21:22:47 -0000
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "doublest.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "main.h"
|
||||
+#include "event-loop.h"
|
||||
|
||||
/* If we are at EOF return a NULL string. */
|
||||
if (rl_pending_input == EOF)
|
||||
@@ -303,6 +304,13 @@ readline (prompt)
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
+ /* When we call readline, we have to make sure that readline isn't in
|
||||
+ the callback state. Otherwise, it will get really confused.
|
||||
+ PR gdb tui/2173. */
|
||||
+ in_callback = RL_ISSTATE (RL_STATE_CALLBACK);
|
||||
+ if (in_callback)
|
||||
+ RL_UNSETSTATE (RL_STATE_CALLBACK);
|
||||
+
|
||||
rl_set_prompt (prompt);
|
||||
|
||||
rl_initialize ();
|
||||
@@ -321,6 +329,9 @@ readline (prompt)
|
||||
rl_clear_signals ();
|
||||
#endif
|
||||
|
||||
+ if (in_callback)
|
||||
+ RL_SETSTATE (RL_STATE_CALLBACK);
|
||||
+
|
||||
return (value);
|
||||
/* readline include files */
|
||||
#include "readline/readline.h"
|
||||
@@ -710,24 +710,84 @@
|
||||
}
|
||||
|
||||
/* This is like readline(), but it has some gdb-specific behavior.
|
||||
- gdb can use readline in both the synchronous and async modes during
|
||||
+ gdb may want readline in both the synchronous and async modes during
|
||||
a single gdb invocation. At the ordinary top-level prompt we might
|
||||
be using the async readline. That means we can't use
|
||||
rl_pre_input_hook, since it doesn't work properly in async mode.
|
||||
However, for a secondary prompt (" >", such as occurs during a
|
||||
- `define'), gdb just calls readline() directly, running it in
|
||||
- synchronous mode. So for operate-and-get-next to work in this
|
||||
- situation, we have to switch the hooks around. That is what
|
||||
- gdb_readline_wrapper is for. */
|
||||
+ `define'), gdb wants a synchronous response.
|
||||
+
|
||||
+ We used to call readline() directly, running it in synchronous
|
||||
+ mode. But mixing modes this way is not supported, and as of
|
||||
+ readline 5.x it no longer works; the arrow keys come unbound during
|
||||
+ the synchronous call. So we make a nested call into the event
|
||||
+ loop. That's what gdb_readline_wrapper is for. */
|
||||
+
|
||||
+/* A flag set as soon as gdb_readline_wrapper_line is called; we can't
|
||||
+ rely on gdb_readline_wrapper_result, which might still be NULL if
|
||||
+ the user types Control-D for EOF. */
|
||||
+static int gdb_readline_wrapper_done;
|
||||
+
|
||||
+/* The result of the current call to gdb_readline_wrapper, once a newline
|
||||
+ is seen. */
|
||||
+static char *gdb_readline_wrapper_result;
|
||||
+
|
||||
+/* Any intercepted hook. Operate-and-get-next sets this, expecting it
|
||||
+ to be called after the newline is processed (which will redisplay
|
||||
+ the prompt). But in gdb_readline_wrapper we will not get a new
|
||||
+ prompt until the next call, or until we return to the event loop.
|
||||
+ So we disable this hook around the newline and restore it before we
|
||||
+ return. */
|
||||
+static void (*saved_after_char_processing_hook) (void);
|
||||
+
|
||||
+/* This function is called when readline has seen a complete line of
|
||||
+ text. */
|
||||
+
|
||||
+static void
|
||||
+gdb_readline_wrapper_line (char *line)
|
||||
+{
|
||||
+ gdb_assert (!gdb_readline_wrapper_done);
|
||||
+ gdb_readline_wrapper_result = line;
|
||||
+ gdb_readline_wrapper_done = 1;
|
||||
+
|
||||
+ /* Prevent operate-and-get-next from acting too early. */
|
||||
+ saved_after_char_processing_hook = after_char_processing_hook;
|
||||
+ after_char_processing_hook = NULL;
|
||||
+}
|
||||
+
|
||||
+struct gdb_readline_wrapper_cleanup
|
||||
+ {
|
||||
+ void (*handler_orig) (char *);
|
||||
+ char *prompt_orig;
|
||||
+ int already_prompted_orig;
|
||||
+ };
|
||||
+
|
||||
+static void
|
||||
+gdb_readline_wrapper_cleanup (void *arg)
|
||||
+{
|
||||
+ struct gdb_readline_wrapper_cleanup *cleanup = arg;
|
||||
+
|
||||
+ gdb_assert (rl_already_prompted == 1);
|
||||
+ rl_already_prompted = cleanup->already_prompted_orig;
|
||||
+ PROMPT (0) = cleanup->prompt_orig;
|
||||
+
|
||||
+ gdb_assert (input_handler == gdb_readline_wrapper_line);
|
||||
+ input_handler = cleanup->handler_orig;
|
||||
+ gdb_readline_wrapper_result = NULL;
|
||||
+ gdb_readline_wrapper_done = 0;
|
||||
+
|
||||
+ after_char_processing_hook = saved_after_char_processing_hook;
|
||||
+ saved_after_char_processing_hook = NULL;
|
||||
+
|
||||
+ xfree (cleanup);
|
||||
+}
|
||||
+
|
||||
char *
|
||||
gdb_readline_wrapper (char *prompt)
|
||||
{
|
||||
- /* Set the hook that works in this case. */
|
||||
- if (after_char_processing_hook)
|
||||
- {
|
||||
- rl_pre_input_hook = (Function *) after_char_processing_hook;
|
||||
- after_char_processing_hook = NULL;
|
||||
- }
|
||||
+ struct cleanup *back_to;
|
||||
+ struct gdb_readline_wrapper_cleanup *cleanup;
|
||||
+ char *retval;
|
||||
|
||||
/* Before calling readline, ensure we have the terminal. If we don't
|
||||
have the terminal and call readline, we risk the possibility of
|
||||
@@ -737,7 +797,32 @@
|
||||
a page break prompt. */
|
||||
terminal_ours ();
|
||||
|
||||
- return readline (prompt);
|
||||
+ cleanup = xmalloc (sizeof (*cleanup));
|
||||
+ cleanup->handler_orig = input_handler;
|
||||
+ input_handler = gdb_readline_wrapper_line;
|
||||
+
|
||||
+ cleanup->prompt_orig = get_prompt ();
|
||||
+ PROMPT (0) = prompt;
|
||||
+ cleanup->already_prompted_orig = rl_already_prompted;
|
||||
+
|
||||
+ back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup);
|
||||
+
|
||||
+ /* Display our prompt and prevent double prompt display. */
|
||||
+ display_gdb_prompt (NULL);
|
||||
+ rl_already_prompted = 1;
|
||||
+
|
||||
+ if (after_char_processing_hook)
|
||||
+ (*after_char_processing_hook) ();
|
||||
+ gdb_assert (after_char_processing_hook == NULL);
|
||||
+
|
||||
+ /* gdb_do_one_event argument is unused. */
|
||||
+ while (gdb_do_one_event (NULL) >= 0)
|
||||
+ if (gdb_readline_wrapper_done)
|
||||
+ break;
|
||||
+
|
||||
+ retval = gdb_readline_wrapper_result;
|
||||
+ do_cleanups (back_to);
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue