2006-11-25 19:11:24 +00:00
|
|
|
|
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=215816
|
|
|
|
|
|
|
|
|
|
|
2007-01-11 21:28:57 +00:00
|
|
|
|
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"
|
2006-11-25 19:11:24 +00:00
|
|
|
|
|
2007-01-11 21:28:57 +00:00
|
|
|
|
/* readline include files */
|
|
|
|
|
#include "readline/readline.h"
|
|
|
|
|
@@ -710,24 +710,84 @@
|
|
|
|
|
}
|
2006-11-25 19:11:24 +00:00
|
|
|
|
|
2007-01-11 21:28:57 +00:00
|
|
|
|
/* 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;
|
2006-11-25 19:11:24 +00:00
|
|
|
|
|
2007-01-11 21:28:57 +00:00
|
|
|
|
/* 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 ();
|
2006-11-25 19:11:24 +00:00
|
|
|
|
|
2007-01-11 21:28:57 +00:00
|
|
|
|
- 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;
|
2006-11-25 19:11:24 +00:00
|
|
|
|
+
|
2007-01-11 21:28:57 +00:00
|
|
|
|
+ retval = gdb_readline_wrapper_result;
|
|
|
|
|
+ do_cleanups (back_to);
|
|
|
|
|
+ return retval;
|
2006-11-25 19:11:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-01-11 21:28:57 +00:00
|
|
|
|
|