- Backport readline history for input mode commands like `command' (BZ

215816).
- Resolves: rhbz#215816
This commit is contained in:
Jan Kratochvil 2007-01-11 21:28:57 +00:00
parent 65bc5f9692
commit 3cdd4d2bbe
3 changed files with 209 additions and 128 deletions

View File

@ -1,97 +1,52 @@
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=215816
Index: ./gdb/testsuite/gdb.base/readline-callback-history.c
===================================================================
RCS file: ./gdb/testsuite/gdb.base/readline-callback-history.c
diff -N ./gdb/testsuite/gdb.base/readline-callback-history.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/readline-callback-history.c 25 Dec 2006 22:54:37 -0000
@@ -0,0 +1,25 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+int main()
+{
+ return 0;
2007-01-03 Jan Kratochvil <jan.kratochvil@redhat.com>
Daniel Jacobowitz <dan@codesourcery.com>
* gdb.base/readline.exp: Set $TERM. Test arrow keys in
secondary prompts.
--- ./gdb/testsuite/gdb.base/readline.exp 8 Jun 2003 13:14:05 -0000 1.2
+++ ./gdb/testsuite/gdb.base/readline.exp 3 Jan 2007 21:22:47 -0000
@@ -1,4 +1,4 @@
-# Copyright 2002 Free Software Foundation, Inc.
+# Copyright 2002, 2003, 2007 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -159,6 +159,14 @@ if [info exists env(INPUTRC)] {
}
set env(INPUTRC) "/dev/null"
+# The arrow key test relies on the standard VT100 bindings, so make
+# sure that an appropriate terminal is selected. The same bug
+# doesn't show up if we use ^P / ^N instead.
+if [info exists env(TERM)] {
+ set old_term $env(TERM)
+}
Index: ./gdb/testsuite/gdb.base/readline-callback-history.exp
===================================================================
RCS file: ./gdb/testsuite/gdb.base/readline-callback-history.exp
diff -N ./gdb/testsuite/gdb.base/readline-callback-history.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/readline-callback-history.exp 25 Dec 2006 22:54:37 -0000
@@ -0,0 +1,55 @@
+# Copyright 2006 Free Software Foundation, Inc.
+set env(TERM) "vt100"
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if $tracelevel then {
+ strace $tracelevel
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
@@ -178,6 +186,18 @@ operate_and_get_next "operate-and-get-ne
"p 5" "" \
"end" ".* = 5"
+# Verify that arrow keys work in secondary prompts. The control
+# sequence is a hard-coded VT100 up arrow.
+gdb_test "print 42" "\\\$\[0-9\]* = 42"
+set msg "arrow keys with secondary prompt"
+gdb_test_multiple "if 1 > 0\n\033\[A\033\[A\nend" $msg {
+ -re ".*\\\$\[0-9\]* = 42\r\n$gdb_prompt $" {
+ pass $msg
+ }
+ -re ".*Undefined command:.*$gdb_prompt $" {
+ fail $msg
+ }
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile start
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# For: \033[A (up arrow)
+set env(TERM) vt100
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# For C programs, "start" should stop in main().
+
+gdb_test "b main" \
+ "Breakpoint 1 at.*" \
+ "Breakpoint put"
+
+gdb_test "run" \
+ "Breakpoint 1, main (.*) at .*" \
+ "Stopped at the breakpoint"
+
+# \033[A (up arrow)
+gdb_test "command 1\n\033\[A\nend" \
+ "Type commands for when breakpoint 1 is hit.*\n>command 1.*" \
+ "History is available even from callback"
# Now repeat the first test with a history file that fills the entire
# history list.

View File

@ -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;
}

View File

@ -11,7 +11,7 @@ Name: gdb
Version: 6.5
# The release always contains a leading reserved number, start it at 0.
Release: 23%{?dist}
Release: 24%{?dist}
License: GPL
Group: Development/Debuggers
@ -613,6 +613,9 @@ fi
# don't include the files in include, they are part of binutils
%changelog
* Thu Jan 11 2007 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.5-24
- Backport readline history for input mode commands like `command' (BZ 215816).
* Tue Jan 9 2007 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.5-23
- Find symbols properly at their original (included) file (BZ 109921).
- Remove the stuck mock(1) builds disfunctional workaround (-> mock BZ 221351).