From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH v3 14/34] Make command line editing (use of readline) be per UI
Date: Fri, 06 May 2016 12:35:00 -0000 [thread overview]
Message-ID: <1462538104-19109-15-git-send-email-palves@redhat.com> (raw)
In-Reply-To: <1462538104-19109-1-git-send-email-palves@redhat.com>
Due to the way that readline's API works (based on globals), we can
only have one instance of readline in a process. So the goal of this
patch is to only allow editing in the main UI, and make sure that only
one UI calls into readline. Some MI paths touch readline variables
currently, which is bad as that is changing variables that matter for
the main console UI. This patch fixes those.
This actually fixes a nasty bug -- starting gdb in MI mode ("gdb
-i=mi"), and then doing "set editing on" crashes GDB, because MI is
not prepared to use readline:
set editing on
&"set editing on\n"
=cmd-param-changed,param="editing",value="on"
^done
(gdb)
p 1
readline: readline_callback_read_char() called with no handler!
Aborted (core dumped)
The fix for that was to add an interp_proc method to query the
interpreter whether it actually supports editing. New test included.
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>
PR mi/20034
* cli/cli-interp.c: Include cli-interp.h and event-top.h.
(cli_interpreter_resume): Pass 1 to gdb_setup_readline. Set the
UI's input_handler here.
(cli_interpreter_supports_command_editing): New function.
(cli_interp_procs): Install it.
* cli/cli-interp.h: New file.
* event-top.c (async_command_editing_p): Rename to ...
(set_editing_cmd_var): ... this.
(change_line_handler): Add parameter 'editing', and use it. Bail
early if the interpreter doesn't support editing. Don't touch
readline state if editing is off.
(gdb_rl_callback_handler_remove, gdb_rl_callback_handler_install)
(gdb_rl_callback_handler_reinstall): Assert the current UI is the
main UI.
(display_gdb_prompt): Don't call gdb_rl_callback_handler_remove if
not using readline. Check whether the current UI is using command
editing instead of checking the async_command_editing_p global.
(set_async_editing_command): Delete.
(gdb_setup_readline): Add 'editing' parameter. Only allow editing
on the main UI. Don't touch readline state if editing is off.
(gdb_disable_readline): Don't touch readline state if editing is
off.
* event-top.h (gdb_setup_readline): Add 'int' parameter.
(set_async_editing_command): Delete declaration.
(change_line_handler, command_line_handler): Declare.
(async_command_editing_p): Rename to ...
(set_editing_cmd_var): ... this.
* infrun.c (reinstall_readline_callback_handler_cleanup): Check
whether the current UI has editing enabled rather than checking
the async_command_editing_p global.
* interps.c (interp_supports_command_editing): New function.
* interps.h (interp_supports_command_editing_ftype): New typedef.
(struct interp_procs) <supports_command_editing_proc>: New field.
(interp_supports_command_editing): Declare.
* mi/mi-interp.c (mi_interpreter_resume): Pass 0 to
gdb_setup_readline. Don't clear the async_command_editing_p
global. Update comments.
* top.c (gdb_readline_wrapper_line, gdb_readline_wrapper): Check
whether the current UI has editing enabled rather than checking
the async_command_editing_p global. Don't touch readline state if
editing is off.
(undo_terminal_modifications_before_exit): Switch to the main UI.
Unconditionally call gdb_disable_readline.
(set_editing): New function.
(show_async_command_editing_p): Rename to ...
(show_editing): ... this. Show the state of the current UI.
(_initialize_top): Adjust.
* top.h (struct ui) <command_editing>: New field.
* tui/tui-interp.c: Include cli/cli-interp.h.
(tui_resume): Pass 1 to gdb_setup_readline. Set the UI's
input_handler.
(tui_interp_procs): Install
cli_interpreter_supports_command_editing.
* tui/tui-io.c (tui_getc): Check whether the current UI has
editing enabled rather than checking the async_command_editing_p
global.
gdb/testsuite/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>
PR mi/20034
* gdb.mi/mi-editing.exp: New file.
---
gdb/cli/cli-interp.c | 16 ++++++-
gdb/cli/cli-interp.h | 25 ++++++++++
gdb/event-top.c | 94 ++++++++++++++++++++-----------------
gdb/event-top.h | 10 ++--
gdb/infrun.c | 2 +-
gdb/interps.c | 10 ++++
gdb/interps.h | 11 +++++
gdb/mi/mi-interp.c | 5 +-
gdb/testsuite/gdb.mi/mi-editing.exp | 37 +++++++++++++++
gdb/top.c | 46 +++++++++++++-----
gdb/top.h | 5 ++
gdb/tui/tui-interp.c | 9 +++-
gdb/tui/tui-io.c | 2 +-
13 files changed, 201 insertions(+), 71 deletions(-)
create mode 100644 gdb/cli/cli-interp.h
create mode 100644 gdb/testsuite/gdb.mi/mi-editing.exp
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index cd33dd2..d67baf3 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -18,11 +18,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "cli-interp.h"
#include "interps.h"
#include "event-top.h"
#include "ui-out.h"
#include "cli-out.h"
#include "top.h" /* for "execute_command" */
+#include "event-top.h"
#include "infrun.h"
#include "observer.h"
@@ -199,6 +201,7 @@ cli_interpreter_init (struct interp *self, int top_level)
static int
cli_interpreter_resume (void *data)
{
+ struct ui *ui = current_ui;
struct cli_interp *cli = (struct cli_interp *) data;
struct ui_file *stream;
@@ -215,7 +218,9 @@ cli_interpreter_resume (void *data)
stream = NULL;
}
- gdb_setup_readline ();
+ gdb_setup_readline (1);
+
+ ui->input_handler = command_line_handler;
if (stream != NULL)
cli_out_set_stream (cli->cli_uiout, gdb_stdout);
@@ -255,6 +260,12 @@ cli_interpreter_exec (void *data, const char *command_str)
return result;
}
+int
+cli_interpreter_supports_command_editing (struct interp *interp)
+{
+ return 1;
+}
+
static struct gdb_exception
safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
{
@@ -301,7 +312,8 @@ static const struct interp_procs cli_interp_procs = {
cli_interpreter_exec, /* exec_proc */
cli_ui_out, /* ui_out_proc */
NULL, /* set_logging_proc */
- cli_command_loop /* command_loop_proc */
+ cli_command_loop, /* command_loop_proc */
+ cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
};
/* Factory for CLI interpreters. */
diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
new file mode 100644
index 0000000..07b7505
--- /dev/null
+++ b/gdb/cli/cli-interp.h
@@ -0,0 +1,25 @@
+/* CLI Definitions for GDB, the GNU debugger.
+
+ Copyright (C) 2016 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef CLI_INTERP_H
+#define CLI_INTERP_H 1
+
+struct interp;
+
+extern int cli_interpreter_supports_command_editing (struct interp *interp);
+
+#endif
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 08eb89d..c84b3f4 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -48,8 +48,6 @@
/* readline defines this. */
#undef savestring
-static void command_line_handler (char *rl);
-static void change_line_handler (void);
static char *top_level_prompt (void);
/* Signal handlers. */
@@ -88,7 +86,7 @@ static void async_sigterm_handler (gdb_client_data arg);
ezannoni: as of 1999-04-29 I expect that this
variable will not be used after gdb is changed to use the event
loop as default engine, and event-top.c is merged into top.c. */
-int async_command_editing_p;
+int set_editing_cmd_var;
/* This is used to display the notification of the completion of an
asynchronous execution command. */
@@ -236,34 +234,45 @@ cli_command_loop (void *data)
therefore bypassing readline, and letting gdb handle the input
itself, via gdb_readline_no_editing_callback. Also it is used in
the opposite case in which the user sets editing on again, by
- restoring readline handling of the input. */
-static void
-change_line_handler (void)
+ restoring readline handling of the input.
+
+ NOTE: this operates on input_fd, not instream. If we are reading
+ commands from a file, instream will point to the file. However, we
+ always read commands from a file with editing off. This means that
+ the 'set editing on/off' will have effect only on the interactive
+ session. */
+
+void
+change_line_handler (int editing)
{
struct ui *ui = current_ui;
- /* NOTE: this operates on input_fd, not instream. If we are reading
- commands from a file, instream will point to the file. However in
- async mode, we always read commands from a file with editing
- off. This means that the 'set editing on/off' will have effect
- only on the interactive session. */
+ /* We can only have one instance of readline, so we only allow
+ editing on the main UI. */
+ if (ui != main_ui)
+ return;
+
+ /* Don't try enabling editing if the interpreter doesn't support it
+ (e.g., MI). */
+ if (!interp_supports_command_editing (top_level_interpreter ())
+ || !interp_supports_command_editing (command_interp ()))
+ return;
- if (async_command_editing_p)
+ if (editing)
{
+ gdb_assert (ui == main_ui);
+
/* Turn on editing by using readline. */
ui->call_readline = gdb_rl_callback_read_char_wrapper;
- ui->input_handler = command_line_handler;
}
else
{
/* Turn off editing by using gdb_readline_no_editing_callback. */
- gdb_rl_callback_handler_remove ();
+ if (ui->command_editing)
+ gdb_rl_callback_handler_remove ();
ui->call_readline = gdb_readline_no_editing_callback;
-
- /* Set up the command handler as well, in case we are called as
- first thing from .gdbinit. */
- ui->input_handler = command_line_handler;
}
+ ui->command_editing = editing;
}
/* The functions below are wrappers for rl_callback_handler_remove and
@@ -284,6 +293,8 @@ static int callback_handler_installed;
void
gdb_rl_callback_handler_remove (void)
{
+ gdb_assert (current_ui == main_ui);
+
rl_callback_handler_remove ();
callback_handler_installed = 0;
}
@@ -295,6 +306,8 @@ gdb_rl_callback_handler_remove (void)
void
gdb_rl_callback_handler_install (const char *prompt)
{
+ gdb_assert (current_ui == main_ui);
+
/* Calling rl_callback_handler_install resets readline's input
buffer. Calling this when we were already processing input
therefore loses input. */
@@ -309,6 +322,8 @@ gdb_rl_callback_handler_install (const char *prompt)
void
gdb_rl_callback_handler_reinstall (void)
{
+ gdb_assert (current_ui == main_ui);
+
if (!callback_handler_installed)
{
/* Passing NULL as prompt argument tells readline to not display
@@ -370,7 +385,8 @@ display_gdb_prompt (const char *new_prompt)
the above two functions. Calling
rl_callback_handler_remove(), does the job. */
- gdb_rl_callback_handler_remove ();
+ if (current_ui->command_editing)
+ gdb_rl_callback_handler_remove ();
do_cleanups (old_chain);
return;
}
@@ -383,7 +399,7 @@ display_gdb_prompt (const char *new_prompt)
else
actual_gdb_prompt = xstrdup (new_prompt);
- if (async_command_editing_p)
+ if (current_ui->command_editing)
{
gdb_rl_callback_handler_remove ();
gdb_rl_callback_handler_install (actual_gdb_prompt);
@@ -1214,21 +1230,13 @@ async_float_handler (gdb_client_data arg)
}
\f
-/* Called by do_setshow_command. */
-void
-set_async_editing_command (char *args, int from_tty,
- struct cmd_list_element *c)
-{
- change_line_handler ();
-}
-
/* Set things up for readline to be invoked via the alternate
interface, i.e. via a callback function
(gdb_rl_callback_read_char), and hook up instream to the event
loop. */
void
-gdb_setup_readline (void)
+gdb_setup_readline (int editing)
{
struct ui *ui = current_ui;
@@ -1243,32 +1251,28 @@ gdb_setup_readline (void)
gdb_stdtarg = gdb_stderr; /* for moment */
gdb_stdtargerr = gdb_stderr; /* for moment */
- /* If the input stream is connected to a terminal, turn on
- editing. */
- if (ISATTY (ui->instream))
+ /* If the input stream is connected to a terminal, turn on editing.
+ However, that is only allowed on the main UI, as we can only have
+ one instance of readline. */
+ if (ISATTY (ui->instream) && editing && ui == main_ui)
{
/* Tell gdb that we will be using the readline library. This
could be overwritten by a command in .gdbinit like 'set
editing on' or 'off'. */
- async_command_editing_p = 1;
-
+ ui->command_editing = 1;
+
/* When a character is detected on instream by select or poll,
readline will be invoked via this callback function. */
ui->call_readline = gdb_rl_callback_read_char_wrapper;
+
+ /* Tell readline to use the same input stream that gdb uses. */
+ rl_instream = ui->instream;
}
else
{
- async_command_editing_p = 0;
+ ui->command_editing = 0;
ui->call_readline = gdb_readline_no_editing_callback;
}
-
- /* When readline has read an end-of-line character, it passes the
- complete line to gdb for processing; command_line_handler is the
- function that does this. */
- ui->input_handler = command_line_handler;
-
- /* Tell readline to use the same input stream that gdb uses. */
- rl_instream = ui->instream;
/* Now create the event source for this UI's input file descriptor.
Another source is going to be the target program (inferior), but
@@ -1280,6 +1284,7 @@ gdb_setup_readline (void)
/* Disable command input through the standard CLI channels. Used in
the suspend proc for interpreters that use the standard gdb readline
interface, like the cli & the mi. */
+
void
gdb_disable_readline (void)
{
@@ -1298,6 +1303,7 @@ gdb_disable_readline (void)
gdb_stdtargerr = NULL;
#endif
- gdb_rl_callback_handler_remove ();
+ if (ui->command_editing)
+ gdb_rl_callback_handler_remove ();
delete_file_handler (ui->input_fd);
}
diff --git a/gdb/event-top.h b/gdb/event-top.h
index 4fe7737..dd0b4bc 100644
--- a/gdb/event-top.h
+++ b/gdb/event-top.h
@@ -28,12 +28,12 @@ struct cmd_list_element;
FIXME: these should really go into top.h. */
extern void display_gdb_prompt (const char *new_prompt);
-void gdb_setup_readline (void);
-void gdb_disable_readline (void);
+extern void gdb_setup_readline (int);
+extern void gdb_disable_readline (void);
extern void async_init_signals (void);
-extern void set_async_editing_command (char *args, int from_tty,
- struct cmd_list_element *c);
+extern void change_line_handler (int);
+extern void command_line_handler (char *rl);
extern void command_handler (char *command);
/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
@@ -54,7 +54,7 @@ extern void async_enable_stdin (void);
/* Exported variables from event-top.c.
FIXME: these should really go into top.h. */
-extern int async_command_editing_p;
+extern int set_editing_cmd_var;
extern int exec_done_display_p;
extern struct prompts the_prompts;
extern void (*after_char_processing_hook) (void);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index ba7144a..eb2388b 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3816,7 +3816,7 @@ reinstall_readline_callback_handler_cleanup (void *arg)
return;
}
- if (async_command_editing_p && !sync_execution)
+ if (current_ui->command_editing && !sync_execution)
gdb_rl_callback_handler_reinstall ();
}
diff --git a/gdb/interps.c b/gdb/interps.c
index ca8512b..536630a 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -416,6 +416,16 @@ current_interp_command_loop (void)
interp->procs->command_loop_proc (interp->data);
}
+/* See interp.h */
+
+int
+interp_supports_command_editing (struct interp *interp)
+{
+ if (interp->procs->supports_command_editing_proc != NULL)
+ return interp->procs->supports_command_editing_proc (interp);
+ return 0;
+}
+
int
interp_quiet_p (struct interp *interp)
{
diff --git a/gdb/interps.h b/gdb/interps.h
index 3065fdf..4922544 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -54,6 +54,8 @@ typedef int (interp_set_logging_ftype) (struct interp *self, int start_log,
struct ui_file *out,
struct ui_file *logfile);
+typedef int (interp_supports_command_editing_ftype) (struct interp *self);
+
struct interp_procs
{
interp_init_ftype *init_proc;
@@ -73,6 +75,11 @@ struct interp_procs
interp_set_logging_ftype *set_logging_proc;
interp_command_loop_ftype *command_loop_proc;
+
+ /* Returns true if this interpreter supports using the readline
+ library; false if it uses GDB's own simplified readline
+ emulation. */
+ interp_supports_command_editing_ftype *supports_command_editing_proc;
};
extern struct interp *interp_new (const char *name,
@@ -114,6 +121,10 @@ extern struct interp *command_interp (void);
extern void clear_interpreter_hooks (void);
+/* Returns true if INTERP supports using the readline library; false
+ if it uses GDB's own simplified form of readline. */
+extern int interp_supports_command_editing (struct interp *interp);
+
/* well-known interpreters */
#define INTERP_CONSOLE "console"
#define INTERP_MI1 "mi1"
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 22250d9..8f6a57b 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -158,13 +158,10 @@ mi_interpreter_resume (void *data)
/* As per hack note in mi_interpreter_init, swap in the output
channels... */
- gdb_setup_readline ();
+ gdb_setup_readline (0);
- /* These overwrite some of the initialization done in
- _intialize_event_loop. */
ui->call_readline = gdb_readline_no_editing_callback;
ui->input_handler = mi_execute_command_input_handler;
- async_command_editing_p = 0;
/* FIXME: This is a total hack for now. PB's use of the MI
implicitly relies on a bug in the async support which allows
asynchronous commands to leak through the commmand loop. The bug
diff --git a/gdb/testsuite/gdb.mi/mi-editing.exp b/gdb/testsuite/gdb.mi/mi-editing.exp
new file mode 100644
index 0000000..b7c6bd1
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-editing.exp
@@ -0,0 +1,37 @@
+# Copyright 2016 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# Regression test for PR mi/20034. Trying to turn on "set editing"
+# when the top-level interpreter is MI would result in GDB/readline
+# aborting with:
+#
+# readline: readline_callback_read_char() called with no handler!
+# Aborted (core dumped)
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if {[mi_gdb_start]} {
+ continue
+}
+
+mi_gdb_test "-interpreter-exec console \"set editing on\"" \
+ {=cmd-param-changed,param=\"editing\",.*\^done} \
+ "-interpreter-exec console \"set editing on\""
+
+mi_gdb_test "-interpreter-exec console \"show editing\"" \
+ ".*Editing of command lines as they are typed is off.*" \
+ "-interpreter-exec console \"show editing\""
diff --git a/gdb/top.c b/gdb/top.c
index 2e6cf31..7e82dcf 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -793,7 +793,7 @@ gdb_readline_wrapper_line (char *line)
we're handling an asynchronous target event and running in the
background, just before returning to the event loop to process
further input (or more target events). */
- if (async_command_editing_p)
+ if (current_ui->command_editing)
gdb_rl_callback_handler_remove ();
}
@@ -813,7 +813,8 @@ gdb_readline_wrapper_cleanup (void *arg)
struct gdb_readline_wrapper_cleanup *cleanup
= (struct gdb_readline_wrapper_cleanup *) arg;
- rl_already_prompted = cleanup->already_prompted_orig;
+ if (ui->command_editing)
+ rl_already_prompted = cleanup->already_prompted_orig;
gdb_assert (ui->input_handler == gdb_readline_wrapper_line);
ui->input_handler = cleanup->handler_orig;
@@ -851,7 +852,10 @@ gdb_readline_wrapper (const char *prompt)
cleanup->handler_orig = ui->input_handler;
ui->input_handler = gdb_readline_wrapper_line;
- cleanup->already_prompted_orig = rl_already_prompted;
+ if (ui->command_editing)
+ cleanup->already_prompted_orig = rl_already_prompted;
+ else
+ cleanup->already_prompted_orig = 0;
cleanup->target_is_async_orig = target_is_async_p ();
@@ -863,7 +867,8 @@ gdb_readline_wrapper (const char *prompt)
/* Display our prompt and prevent double prompt display. */
display_gdb_prompt (prompt);
- rl_already_prompted = 1;
+ if (ui->command_editing)
+ rl_already_prompted = 1;
if (after_char_processing_hook)
(*after_char_processing_hook) ();
@@ -1420,12 +1425,18 @@ quit_confirm (void)
static void
undo_terminal_modifications_before_exit (void)
{
+ struct ui *saved_top_level = current_ui;
+
target_terminal_ours ();
+
+ current_ui = main_ui;
+
#if defined(TUI)
tui_disable ();
#endif
- if (async_command_editing_p)
- gdb_disable_readline ();
+ gdb_disable_readline ();
+
+ current_ui = saved_top_level;
}
@@ -1739,13 +1750,24 @@ show_prompt (struct ui_file *file, int from_tty,
fprintf_filtered (file, _("Gdb's prompt is \"%s\".\n"), value);
}
+/* "set editing" command. */
+
+static void
+set_editing (char *args, int from_tty, struct cmd_list_element *c)
+{
+ change_line_handler (set_editing_cmd_var);
+ /* Update the control variable so that MI's =cmd-param-changed event
+ shows the correct value. */
+ set_editing_cmd_var = current_ui->command_editing;
+}
+
static void
-show_async_command_editing_p (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
+show_editing (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file, _("Editing of command lines as "
"they are typed is %s.\n"),
- value);
+ current_ui->command_editing ? _("on") : _("off"));
}
static void
@@ -1836,14 +1858,14 @@ used inside of user-defined commands that should not be repeated when\n\
hitting return."));
add_setshow_boolean_cmd ("editing", class_support,
- &async_command_editing_p, _("\
+ &set_editing_cmd_var, _("\
Set editing of command lines as they are typed."), _("\
Show editing of command lines as they are typed."), _("\
Use \"on\" to enable the editing, and \"off\" to disable it.\n\
Without an argument, command line editing is enabled. To edit, use\n\
EMACS-like or VI-like commands like control-P or ESC."),
- set_async_editing_command,
- show_async_command_editing_p,
+ set_editing,
+ show_editing,
&setlist, &showlist);
add_setshow_boolean_cmd ("save", no_class, &write_history_p, _("\
diff --git a/gdb/top.h b/gdb/top.h
index dfef32c..2facd1e 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -55,6 +55,11 @@ struct ui
processing. */
void (*input_handler) (char *);
+ /* True if this UI is using the readline library for command
+ editing; false if using GDB's own simple readline emulation, with
+ no editing support. */
+ int command_editing;
+
/* Each UI has its own independent set of interpreters. */
struct ui_interp_info *interp_info;
diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c
index 7691f8c..fc3c0ff 100644
--- a/gdb/tui/tui-interp.c
+++ b/gdb/tui/tui-interp.c
@@ -18,6 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
+#include "cli/cli-interp.h"
#include "interps.h"
#include "top.h"
#include "event-top.h"
@@ -219,6 +220,7 @@ tui_init (struct interp *self, int top_level)
static int
tui_resume (void *data)
{
+ struct ui *ui = current_ui;
struct ui_file *stream;
/* gdb_setup_readline will change gdb_stdout. If the TUI was
@@ -232,7 +234,9 @@ tui_resume (void *data)
stream = NULL;
}
- gdb_setup_readline ();
+ gdb_setup_readline (1);
+
+ ui->input_handler = command_line_handler;
if (stream != NULL)
cli_out_set_stream (tui_old_uiout, gdb_stdout);
@@ -274,7 +278,8 @@ static const struct interp_procs tui_interp_procs = {
tui_exec,
tui_ui_out,
NULL,
- cli_command_loop
+ cli_command_loop,
+ cli_interpreter_supports_command_editing,
};
/* Factory for TUI interpreters. */
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 3fa32db..6f2d892 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -616,7 +616,7 @@ tui_getc (FILE *fp)
if (ch == KEY_BACKSPACE)
return '\b';
- if (async_command_editing_p && key_is_start_sequence (ch))
+ if (current_ui->command_editing && key_is_start_sequence (ch))
{
int ch_pending;
--
2.5.5
next prev parent reply other threads:[~2016-05-06 12:35 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-06 12:35 [PATCH v3 00/34] Towards great frontend GDB consoles Pedro Alves
2016-05-06 12:35 ` [PATCH v3 01/34] Prepare gdb.python/mi-py-events.exp for Python/MI in separate channels Pedro Alves
2016-05-06 12:35 ` [PATCH v3 24/34] Push thread->control.command_interp to the struct thread_fsm Pedro Alves
2016-07-01 11:02 ` Thomas Preudhomme
[not found] ` <20144b4c-11ee-fc84-e3ad-b9992f14ce15@redhat.com>
2016-07-01 15:24 ` [PATCH] Build gdb.opt/inline-*.exp tests at -O0, rely on __attribute__((always_inline)) (was: Re: [PATCH v3 24/34] Push thread->control.command_interp to the struct thread_fsm) Thomas Preudhomme
2016-07-15 12:05 ` Thomas Preudhomme
2016-07-19 17:02 ` [PATCH] Build gdb.opt/inline-*.exp tests at -O0, rely on __attribute__((always_inline)) Pedro Alves
2016-07-20 16:35 ` Thomas Preudhomme
2016-05-06 12:35 ` [PATCH v3 29/34] Add new command to create extra console/mi UI channels Pedro Alves
2016-05-26 18:34 ` Pedro Alves
2016-05-06 12:35 ` [PATCH v3 03/34] Introduce "struct ui" Pedro Alves
2016-05-06 12:35 ` [PATCH v3 16/34] Make target_terminal_inferior/ours almost nops on non-main UIs Pedro Alves
2016-05-06 12:35 ` [PATCH v3 15/34] Always process target events in the main UI Pedro Alves
2016-05-06 12:35 ` [PATCH v3 20/34] Make gdb_in_secondary_prompt_p() be per UI Pedro Alves
2016-05-06 12:35 ` [PATCH v3 33/34] Make mi-break.exp always expect breakpoint commands output on the main UI Pedro Alves
2016-05-06 12:35 ` [PATCH v3 02/34] [Ada catchpoints] Fix "warning: failed to get exception name: No definition of \"e.full_name\" in current context" Pedro Alves
2016-05-06 12:35 ` Pedro Alves [this message]
2016-05-06 12:35 ` [PATCH v3 21/34] Replace the sync_execution global with a new enum prompt_state tristate Pedro Alves
2016-05-06 12:36 ` [PATCH v3 31/34] Add testing infrastruture bits for running with MI on a separate UI Pedro Alves
2016-06-28 20:19 ` Simon Marchi
2016-06-29 10:50 ` Pedro Alves
2016-06-30 11:12 ` [pushed] Fix gdbserver/MI testing regression (was: Re: [PATCH v3 31/34] Add testing infrastruture bits for running with MI on a separate UI) Pedro Alves
2016-06-30 12:10 ` gdbserver/ada testing broken (was: Re: [pushed] Fix gdbserver/MI testing regression) Pedro Alves
2016-07-04 20:40 ` gdbserver/ada testing broken Simon Marchi
2016-07-05 15:28 ` Joel Brobecker
2016-07-05 15:47 ` Joel Brobecker
2016-07-05 16:36 ` gdbserver/ada testing broken (was: Re: [pushed] Fix gdbserver/MI testing regression) Joel Brobecker
2016-07-05 17:19 ` gdbserver/ada testing broken Simon Marchi
2016-07-06 13:23 ` Joel Brobecker
2016-07-06 14:28 ` Simon Marchi
2016-07-19 17:11 ` Pedro Alves
2016-07-04 17:22 ` [pushed] Fix gdbserver/MI testing regression Simon Marchi
2016-05-06 12:40 ` [PATCH v3 13/34] Make current_ui_out be per UI Pedro Alves
2016-05-06 12:40 ` [PATCH v3 23/34] New function should_print_stop_to_console Pedro Alves
2016-05-06 12:40 ` [PATCH v3 11/34] Make out and error streams be per UI Pedro Alves
2016-05-06 12:41 ` [PATCH v3 06/34] Introduce interpreter factories Pedro Alves
2016-05-18 19:18 ` Simon Marchi
2016-05-26 18:11 ` Pedro Alves
2016-05-18 19:20 ` Simon Marchi
2016-05-26 18:08 ` Pedro Alves
2016-05-06 12:42 ` [PATCH v3 30/34] [DOC] Document support for running interpreters on separate UI channels Pedro Alves
2016-05-06 13:04 ` Eli Zaretskii
2016-05-26 11:11 ` Pedro Alves
2016-06-17 17:24 ` Pedro Alves
2016-06-17 20:02 ` Eli Zaretskii
2016-05-06 12:43 ` [PATCH v3 05/34] Make the interpreters be per UI Pedro Alves
2016-05-18 17:51 ` Simon Marchi
2016-05-26 18:08 ` Pedro Alves
2016-05-06 12:43 ` [PATCH v3 10/34] Make input_fd " Pedro Alves
2016-05-06 12:43 ` [PATCH v3 12/34] Delete def_uiout Pedro Alves
2016-05-06 12:43 ` [PATCH v3 04/34] Make gdb_stdout&co be per UI Pedro Alves
2016-05-06 12:43 ` [PATCH v3 17/34] Introduce display_mi_prompt Pedro Alves
2016-05-06 12:43 ` [PATCH v3 28/34] Make stdin be per UI Pedro Alves
2016-05-06 12:43 ` [PATCH v3 07/34] Make the intepreters output to all UIs Pedro Alves
2016-05-19 15:16 ` Simon Marchi
2016-05-26 18:12 ` Pedro Alves
2016-05-06 12:43 ` [PATCH v3 25/34] Only send sync execution command output to the UI that ran the command Pedro Alves
2016-05-06 12:43 ` [PATCH v3 08/34] Always run async signal handlers in the main UI Pedro Alves
2016-05-19 19:28 ` Simon Marchi
2016-05-26 18:13 ` Pedro Alves
2016-05-26 18:15 ` Simon Marchi
2016-05-06 12:45 ` [PATCH v3 34/34] Always switch fork child to " Pedro Alves
2016-05-06 12:45 ` [PATCH v3 32/34] Send deleted watchpoint-scope output to all UIs Pedro Alves
2016-05-06 12:45 ` [PATCH v3 22/34] Fix for spurious prompts in secondary UIs Pedro Alves
2016-05-06 12:45 ` [PATCH v3 27/34] Handle UI's terminal closing Pedro Alves
2016-05-06 12:45 ` [PATCH v3 26/34] Make main_ui be heap allocated Pedro Alves
2016-05-06 12:52 ` [PATCH v3 18/34] Make raw_stdout be per MI instance Pedro Alves
2016-05-06 12:53 ` [PATCH v3 19/34] Simplify starting the command event loop Pedro Alves
2016-05-06 12:53 ` [PATCH v3 09/34] Make instream be per UI Pedro Alves
2016-05-26 18:37 ` [PATCH v3 35/34] Add "new-ui console" tests Pedro Alves
2016-06-21 0:23 ` [pushed] Re: [PATCH v3 00/34] Towards great frontend GDB consoles Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1462538104-19109-15-git-send-email-palves@redhat.com \
--to=palves@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox