Introduce "struct ui"
This is a step towards supporting multiple consoles/MIs, each on its own stdio streams / terminal. See intro comment in top.h. (I've had trouble picking a name for this object. I've started out with "struct console" originally. But then this is about MI as well, and there's "interpreter-exec console", which is specifically about the CLI... So I changed to "struct terminal", but, then we have a terminal object that works when the input is not a terminal as well ... Then I sort of gave up and renamed it to "struct top_level". But it then gets horribly confusing when we talk about the "top level interpreter that's running on the current top level". In the end, I realized we're already sort of calling this "ui", in struct ui_out, struct ui_file, and a few coments here and there.) gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * event-top.c: Update readline-related comments. (input_handler, call_readline): Delete globals. (gdb_rl_callback_handler): Call the current UI's input_handler method. (change_line_handler): Adjust to set current UI's properties instead of globals. (current_ui_, current_ui): New globals. (get_command_line_buffer): Rewrite to refer to the current UI. (stdin_event_handler): Adjust to call the call_readline method of the current UI. (gdb_readline_no_editing_callback): Adjust to call the current UI's input_handler method. (gdb_setup_readline): Adjust to set current UI's properties instead of globals. * event-top.h (call_readline, input_handler): Delete declarations. * mi/mi-interp.c (mi_interpreter_resume): Adjust to set current UI's properties instead of globals. * top.c (gdb_readline_wrapper_cleanup): Adjust to set current UI's properties instead of globals. (gdb_readline_wrapper): Adjust to call and set current UI's methods instead of globals. * top.h: Include buffer.h and event-loop.h. (struct ui): New struct. (current_ui): New declaration.
This commit is contained in:
parent
45db7c09c3
commit
a74e1786ac
|
@ -1,3 +1,30 @@
|
|||
2016-06-21 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* event-top.c: Update readline-related comments.
|
||||
(input_handler, call_readline): Delete globals.
|
||||
(gdb_rl_callback_handler): Call the current UI's input_handler
|
||||
method.
|
||||
(change_line_handler): Adjust to set current UI's properties
|
||||
instead of globals.
|
||||
(current_ui_, current_ui): New globals.
|
||||
(get_command_line_buffer): Rewrite to refer to the current UI.
|
||||
(stdin_event_handler): Adjust to call the call_readline method of
|
||||
the current UI.
|
||||
(gdb_readline_no_editing_callback): Adjust to call the current UI's
|
||||
input_handler method.
|
||||
(gdb_setup_readline): Adjust to set current UI's properties
|
||||
instead of globals.
|
||||
* event-top.h (call_readline, input_handler): Delete declarations.
|
||||
* mi/mi-interp.c (mi_interpreter_resume): Adjust to set current
|
||||
UI's properties instead of globals.
|
||||
* top.c (gdb_readline_wrapper_cleanup): Adjust to set current UI's
|
||||
properties instead of globals.
|
||||
(gdb_readline_wrapper): Adjust to call and set current UI's
|
||||
methods instead of globals.
|
||||
* top.h: Include buffer.h and event-loop.h.
|
||||
(struct ui): New struct.
|
||||
(current_ui): New declaration.
|
||||
|
||||
2016-06-21 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* ada-lang.c (ada_exception_name_addr_1): Add comment.
|
||||
|
|
|
@ -75,28 +75,10 @@ static void async_stop_sig (gdb_client_data);
|
|||
#endif
|
||||
static void async_sigterm_handler (gdb_client_data arg);
|
||||
|
||||
/* Readline offers an alternate interface, via callback
|
||||
functions. These are all included in the file callback.c in the
|
||||
readline distribution. This file provides (mainly) a function, which
|
||||
the event loop uses as callback (i.e. event handler) whenever an event
|
||||
is detected on the standard input file descriptor.
|
||||
readline_callback_read_char is called (by the GDB event loop) whenever
|
||||
there is a new character ready on the input stream. This function
|
||||
incrementally builds a buffer internal to readline where it
|
||||
accumulates the line read up to the point of invocation. In the
|
||||
special case in which the character read is newline, the function
|
||||
invokes a GDB supplied callback routine, which does the processing of
|
||||
a full command line. This latter routine is the asynchronous analog
|
||||
of the old command_line_input in gdb. Instead of invoking (and waiting
|
||||
for) readline to read the command line and pass it back to
|
||||
command_loop for processing, the new command_line_handler function has
|
||||
the command line already available as its parameter. INPUT_HANDLER is
|
||||
to be set to the function that readline will invoke when a complete
|
||||
line of input is ready. CALL_READLINE is to be set to the function
|
||||
that readline offers as callback to the event_loop. */
|
||||
|
||||
void (*input_handler) (char *);
|
||||
void (*call_readline) (gdb_client_data);
|
||||
/* Instead of invoking (and waiting for) readline to read the command
|
||||
line and pass it back for processing, we use readline's alternate
|
||||
interface, via callback functions, so that the event loop can react
|
||||
to other event sources while we wait for input. */
|
||||
|
||||
/* Important variables for the event loop. */
|
||||
|
||||
|
@ -217,10 +199,11 @@ static void
|
|||
gdb_rl_callback_handler (char *rl)
|
||||
{
|
||||
struct gdb_exception gdb_rl_expt = exception_none;
|
||||
struct ui *ui = current_ui;
|
||||
|
||||
TRY
|
||||
{
|
||||
input_handler (rl);
|
||||
ui->input_handler (rl);
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
|
@ -261,6 +244,8 @@ cli_command_loop (void *data)
|
|||
static void
|
||||
change_line_handler (void)
|
||||
{
|
||||
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
|
||||
|
@ -270,18 +255,18 @@ change_line_handler (void)
|
|||
if (async_command_editing_p)
|
||||
{
|
||||
/* Turn on editing by using readline. */
|
||||
call_readline = gdb_rl_callback_read_char_wrapper;
|
||||
input_handler = command_line_handler;
|
||||
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 ();
|
||||
call_readline = gdb_readline_no_editing_callback;
|
||||
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. */
|
||||
input_handler = command_line_handler;
|
||||
ui->input_handler = command_line_handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,22 +437,16 @@ top_level_prompt (void)
|
|||
return xstrdup (prompt);
|
||||
}
|
||||
|
||||
/* Get a pointer to the command line buffer. This is used to
|
||||
static struct ui current_ui_;
|
||||
struct ui *current_ui = ¤t_ui_;
|
||||
|
||||
/* Get a pointer to the current UI's line buffer. This is used to
|
||||
construct a whole line of input from partial input. */
|
||||
|
||||
static struct buffer *
|
||||
get_command_line_buffer (void)
|
||||
{
|
||||
static struct buffer line_buffer;
|
||||
static int line_buffer_initialized;
|
||||
|
||||
if (!line_buffer_initialized)
|
||||
{
|
||||
buffer_init (&line_buffer);
|
||||
line_buffer_initialized = 1;
|
||||
}
|
||||
|
||||
return &line_buffer;
|
||||
return ¤t_ui->line_buffer;
|
||||
}
|
||||
|
||||
/* When there is an event ready on the stdin file descriptor, instead
|
||||
|
@ -478,6 +457,8 @@ get_command_line_buffer (void)
|
|||
void
|
||||
stdin_event_handler (int error, gdb_client_data client_data)
|
||||
{
|
||||
struct ui *ui = current_ui;
|
||||
|
||||
if (error)
|
||||
{
|
||||
printf_unfiltered (_("error detected on stdin\n"));
|
||||
|
@ -499,7 +480,7 @@ stdin_event_handler (int error, gdb_client_data client_data)
|
|||
do
|
||||
{
|
||||
call_stdin_event_handler_again_p = 0;
|
||||
(*call_readline) (client_data);
|
||||
ui->call_readline (client_data);
|
||||
} while (call_stdin_event_handler_again_p != 0);
|
||||
}
|
||||
}
|
||||
|
@ -756,6 +737,7 @@ gdb_readline_no_editing_callback (gdb_client_data client_data)
|
|||
char *result;
|
||||
struct buffer line_buffer;
|
||||
static int done_once = 0;
|
||||
struct ui *ui = current_ui;
|
||||
|
||||
buffer_init (&line_buffer);
|
||||
|
||||
|
@ -795,7 +777,7 @@ gdb_readline_no_editing_callback (gdb_client_data client_data)
|
|||
break;
|
||||
}
|
||||
xfree (buffer_finish (&line_buffer));
|
||||
(*input_handler) (0);
|
||||
ui->input_handler (NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -812,7 +794,7 @@ gdb_readline_no_editing_callback (gdb_client_data client_data)
|
|||
|
||||
buffer_grow_char (&line_buffer, '\0');
|
||||
result = buffer_finish (&line_buffer);
|
||||
(*input_handler) (result);
|
||||
ui->input_handler (result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1198,6 +1180,8 @@ set_async_editing_command (char *args, int from_tty,
|
|||
void
|
||||
gdb_setup_readline (void)
|
||||
{
|
||||
struct ui *ui = current_ui;
|
||||
|
||||
/* This function is a noop for the sync case. The assumption is
|
||||
that the sync setup is ALL done in gdb_init, and we would only
|
||||
mess it up here. The sync stuff should really go away over
|
||||
|
@ -1220,18 +1204,18 @@ gdb_setup_readline (void)
|
|||
|
||||
/* When a character is detected on instream by select or poll,
|
||||
readline will be invoked via this callback function. */
|
||||
call_readline = gdb_rl_callback_read_char_wrapper;
|
||||
ui->call_readline = gdb_rl_callback_read_char_wrapper;
|
||||
}
|
||||
else
|
||||
{
|
||||
async_command_editing_p = 0;
|
||||
call_readline = gdb_readline_no_editing_callback;
|
||||
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. */
|
||||
input_handler = command_line_handler;
|
||||
ui->input_handler = command_line_handler;
|
||||
|
||||
/* Tell readline to use the same input stream that gdb uses. */
|
||||
rl_instream = instream;
|
||||
|
|
|
@ -57,8 +57,6 @@ extern void async_enable_stdin (void);
|
|||
extern int async_command_editing_p;
|
||||
extern int exec_done_display_p;
|
||||
extern struct prompts the_prompts;
|
||||
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;
|
||||
|
|
|
@ -175,6 +175,7 @@ static int
|
|||
mi_interpreter_resume (void *data)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) data;
|
||||
struct ui *ui = current_ui;
|
||||
|
||||
/* As per hack note in mi_interpreter_init, swap in the output
|
||||
channels... */
|
||||
|
@ -182,8 +183,8 @@ mi_interpreter_resume (void *data)
|
|||
|
||||
/* These overwrite some of the initialization done in
|
||||
_intialize_event_loop. */
|
||||
call_readline = gdb_readline_no_editing_callback;
|
||||
input_handler = mi_execute_command_input_handler;
|
||||
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
|
||||
|
|
10
gdb/top.c
10
gdb/top.c
|
@ -794,13 +794,14 @@ struct gdb_readline_wrapper_cleanup
|
|||
static void
|
||||
gdb_readline_wrapper_cleanup (void *arg)
|
||||
{
|
||||
struct ui *ui = current_ui;
|
||||
struct gdb_readline_wrapper_cleanup *cleanup
|
||||
= (struct gdb_readline_wrapper_cleanup *) arg;
|
||||
|
||||
rl_already_prompted = cleanup->already_prompted_orig;
|
||||
|
||||
gdb_assert (input_handler == gdb_readline_wrapper_line);
|
||||
input_handler = cleanup->handler_orig;
|
||||
gdb_assert (ui->input_handler == gdb_readline_wrapper_line);
|
||||
ui->input_handler = cleanup->handler_orig;
|
||||
|
||||
/* Don't restore our input handler in readline yet. That would make
|
||||
readline prep the terminal (putting it in raw mode), while the
|
||||
|
@ -826,13 +827,14 @@ gdb_readline_wrapper_cleanup (void *arg)
|
|||
char *
|
||||
gdb_readline_wrapper (const char *prompt)
|
||||
{
|
||||
struct ui *ui = current_ui;
|
||||
struct cleanup *back_to;
|
||||
struct gdb_readline_wrapper_cleanup *cleanup;
|
||||
char *retval;
|
||||
|
||||
cleanup = XNEW (struct gdb_readline_wrapper_cleanup);
|
||||
cleanup->handler_orig = input_handler;
|
||||
input_handler = gdb_readline_wrapper_line;
|
||||
cleanup->handler_orig = ui->input_handler;
|
||||
ui->input_handler = gdb_readline_wrapper_line;
|
||||
|
||||
cleanup->already_prompted_orig = rl_already_prompted;
|
||||
|
||||
|
|
33
gdb/top.h
33
gdb/top.h
|
@ -20,7 +20,38 @@
|
|||
#ifndef TOP_H
|
||||
#define TOP_H
|
||||
|
||||
struct buffer;
|
||||
#include "buffer.h"
|
||||
#include "event-loop.h"
|
||||
|
||||
/* All about a user interface instance. Each user interface has its
|
||||
own I/O files/streams, readline state, its own top level
|
||||
interpreter (for the main UI, this is the interpreter specified
|
||||
with -i on the command line) and secondary interpreters (for
|
||||
interpreter-exec ...), etc. There's always one UI associated with
|
||||
stdin/stdout/stderr, but the user can create secondary UIs, for
|
||||
example, to create a separate MI channel on its own stdio
|
||||
streams. */
|
||||
|
||||
struct ui
|
||||
{
|
||||
/* The UI's command line buffer. This is to used to accumulate
|
||||
input until we have a whole command line. */
|
||||
struct buffer line_buffer;
|
||||
|
||||
/* The callback used by the event loop whenever an event is detected
|
||||
on the UI's input file descriptor. This function incrementally
|
||||
builds a buffer where it accumulates the line read up to the
|
||||
point of invocation. In the special case in which the character
|
||||
read is newline, the function invokes the INPUT_HANDLER callback
|
||||
(see below). */
|
||||
void (*call_readline) (gdb_client_data);
|
||||
|
||||
/* The function to invoke when a complete line of input is ready for
|
||||
processing. */
|
||||
void (*input_handler) (char *);
|
||||
};
|
||||
|
||||
extern struct ui *current_ui;
|
||||
|
||||
/* From top.c. */
|
||||
extern char *saved_command_line;
|
||||
|
|
Loading…
Reference in New Issue