mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-17 07:53:51 +08:00
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:
@ -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>
|
2016-06-21 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* ada-lang.c (ada_exception_name_addr_1): Add comment.
|
* ada-lang.c (ada_exception_name_addr_1): Add comment.
|
||||||
|
@ -75,28 +75,10 @@ static void async_stop_sig (gdb_client_data);
|
|||||||
#endif
|
#endif
|
||||||
static void async_sigterm_handler (gdb_client_data arg);
|
static void async_sigterm_handler (gdb_client_data arg);
|
||||||
|
|
||||||
/* Readline offers an alternate interface, via callback
|
/* Instead of invoking (and waiting for) readline to read the command
|
||||||
functions. These are all included in the file callback.c in the
|
line and pass it back for processing, we use readline's alternate
|
||||||
readline distribution. This file provides (mainly) a function, which
|
interface, via callback functions, so that the event loop can react
|
||||||
the event loop uses as callback (i.e. event handler) whenever an event
|
to other event sources while we wait for input. */
|
||||||
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);
|
|
||||||
|
|
||||||
/* Important variables for the event loop. */
|
/* Important variables for the event loop. */
|
||||||
|
|
||||||
@ -217,10 +199,11 @@ static void
|
|||||||
gdb_rl_callback_handler (char *rl)
|
gdb_rl_callback_handler (char *rl)
|
||||||
{
|
{
|
||||||
struct gdb_exception gdb_rl_expt = exception_none;
|
struct gdb_exception gdb_rl_expt = exception_none;
|
||||||
|
struct ui *ui = current_ui;
|
||||||
|
|
||||||
TRY
|
TRY
|
||||||
{
|
{
|
||||||
input_handler (rl);
|
ui->input_handler (rl);
|
||||||
}
|
}
|
||||||
CATCH (ex, RETURN_MASK_ALL)
|
CATCH (ex, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
@ -261,6 +244,8 @@ cli_command_loop (void *data)
|
|||||||
static void
|
static void
|
||||||
change_line_handler (void)
|
change_line_handler (void)
|
||||||
{
|
{
|
||||||
|
struct ui *ui = current_ui;
|
||||||
|
|
||||||
/* NOTE: this operates on input_fd, not instream. If we are reading
|
/* NOTE: this operates on input_fd, not instream. If we are reading
|
||||||
commands from a file, instream will point to the file. However in
|
commands from a file, instream will point to the file. However in
|
||||||
async mode, we always read commands from a file with editing
|
async mode, we always read commands from a file with editing
|
||||||
@ -270,18 +255,18 @@ change_line_handler (void)
|
|||||||
if (async_command_editing_p)
|
if (async_command_editing_p)
|
||||||
{
|
{
|
||||||
/* Turn on editing by using readline. */
|
/* Turn on editing by using readline. */
|
||||||
call_readline = gdb_rl_callback_read_char_wrapper;
|
ui->call_readline = gdb_rl_callback_read_char_wrapper;
|
||||||
input_handler = command_line_handler;
|
ui->input_handler = command_line_handler;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Turn off editing by using gdb_readline_no_editing_callback. */
|
/* Turn off editing by using gdb_readline_no_editing_callback. */
|
||||||
gdb_rl_callback_handler_remove ();
|
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
|
/* Set up the command handler as well, in case we are called as
|
||||||
first thing from .gdbinit. */
|
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);
|
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. */
|
construct a whole line of input from partial input. */
|
||||||
|
|
||||||
static struct buffer *
|
static struct buffer *
|
||||||
get_command_line_buffer (void)
|
get_command_line_buffer (void)
|
||||||
{
|
{
|
||||||
static struct buffer line_buffer;
|
return ¤t_ui->line_buffer;
|
||||||
static int line_buffer_initialized;
|
|
||||||
|
|
||||||
if (!line_buffer_initialized)
|
|
||||||
{
|
|
||||||
buffer_init (&line_buffer);
|
|
||||||
line_buffer_initialized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &line_buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When there is an event ready on the stdin file descriptor, instead
|
/* When there is an event ready on the stdin file descriptor, instead
|
||||||
@ -478,6 +457,8 @@ get_command_line_buffer (void)
|
|||||||
void
|
void
|
||||||
stdin_event_handler (int error, gdb_client_data client_data)
|
stdin_event_handler (int error, gdb_client_data client_data)
|
||||||
{
|
{
|
||||||
|
struct ui *ui = current_ui;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
printf_unfiltered (_("error detected on stdin\n"));
|
printf_unfiltered (_("error detected on stdin\n"));
|
||||||
@ -499,7 +480,7 @@ stdin_event_handler (int error, gdb_client_data client_data)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
call_stdin_event_handler_again_p = 0;
|
call_stdin_event_handler_again_p = 0;
|
||||||
(*call_readline) (client_data);
|
ui->call_readline (client_data);
|
||||||
} while (call_stdin_event_handler_again_p != 0);
|
} while (call_stdin_event_handler_again_p != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -756,6 +737,7 @@ gdb_readline_no_editing_callback (gdb_client_data client_data)
|
|||||||
char *result;
|
char *result;
|
||||||
struct buffer line_buffer;
|
struct buffer line_buffer;
|
||||||
static int done_once = 0;
|
static int done_once = 0;
|
||||||
|
struct ui *ui = current_ui;
|
||||||
|
|
||||||
buffer_init (&line_buffer);
|
buffer_init (&line_buffer);
|
||||||
|
|
||||||
@ -795,7 +777,7 @@ gdb_readline_no_editing_callback (gdb_client_data client_data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
xfree (buffer_finish (&line_buffer));
|
xfree (buffer_finish (&line_buffer));
|
||||||
(*input_handler) (0);
|
ui->input_handler (NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +794,7 @@ gdb_readline_no_editing_callback (gdb_client_data client_data)
|
|||||||
|
|
||||||
buffer_grow_char (&line_buffer, '\0');
|
buffer_grow_char (&line_buffer, '\0');
|
||||||
result = buffer_finish (&line_buffer);
|
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
|
void
|
||||||
gdb_setup_readline (void)
|
gdb_setup_readline (void)
|
||||||
{
|
{
|
||||||
|
struct ui *ui = current_ui;
|
||||||
|
|
||||||
/* This function is a noop for the sync case. The assumption is
|
/* 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
|
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
|
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,
|
/* When a character is detected on instream by select or poll,
|
||||||
readline will be invoked via this callback function. */
|
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
|
else
|
||||||
{
|
{
|
||||||
async_command_editing_p = 0;
|
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
|
/* When readline has read an end-of-line character, it passes the
|
||||||
complete line to gdb for processing; command_line_handler is the
|
complete line to gdb for processing; command_line_handler is the
|
||||||
function that does this. */
|
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. */
|
/* Tell readline to use the same input stream that gdb uses. */
|
||||||
rl_instream = instream;
|
rl_instream = instream;
|
||||||
|
@ -57,8 +57,6 @@ extern void async_enable_stdin (void);
|
|||||||
extern int async_command_editing_p;
|
extern int async_command_editing_p;
|
||||||
extern int exec_done_display_p;
|
extern int exec_done_display_p;
|
||||||
extern struct prompts the_prompts;
|
extern struct prompts the_prompts;
|
||||||
extern void (*call_readline) (void *);
|
|
||||||
extern void (*input_handler) (char *);
|
|
||||||
extern int input_fd;
|
extern int input_fd;
|
||||||
extern void (*after_char_processing_hook) (void);
|
extern void (*after_char_processing_hook) (void);
|
||||||
extern int call_stdin_event_handler_again_p;
|
extern int call_stdin_event_handler_again_p;
|
||||||
|
@ -175,6 +175,7 @@ static int
|
|||||||
mi_interpreter_resume (void *data)
|
mi_interpreter_resume (void *data)
|
||||||
{
|
{
|
||||||
struct mi_interp *mi = (struct mi_interp *) 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
|
/* As per hack note in mi_interpreter_init, swap in the output
|
||||||
channels... */
|
channels... */
|
||||||
@ -182,8 +183,8 @@ mi_interpreter_resume (void *data)
|
|||||||
|
|
||||||
/* These overwrite some of the initialization done in
|
/* These overwrite some of the initialization done in
|
||||||
_intialize_event_loop. */
|
_intialize_event_loop. */
|
||||||
call_readline = gdb_readline_no_editing_callback;
|
ui->call_readline = gdb_readline_no_editing_callback;
|
||||||
input_handler = mi_execute_command_input_handler;
|
ui->input_handler = mi_execute_command_input_handler;
|
||||||
async_command_editing_p = 0;
|
async_command_editing_p = 0;
|
||||||
/* FIXME: This is a total hack for now. PB's use of the MI
|
/* 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
|
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
|
static void
|
||||||
gdb_readline_wrapper_cleanup (void *arg)
|
gdb_readline_wrapper_cleanup (void *arg)
|
||||||
{
|
{
|
||||||
|
struct ui *ui = current_ui;
|
||||||
struct gdb_readline_wrapper_cleanup *cleanup
|
struct gdb_readline_wrapper_cleanup *cleanup
|
||||||
= (struct gdb_readline_wrapper_cleanup *) arg;
|
= (struct gdb_readline_wrapper_cleanup *) arg;
|
||||||
|
|
||||||
rl_already_prompted = cleanup->already_prompted_orig;
|
rl_already_prompted = cleanup->already_prompted_orig;
|
||||||
|
|
||||||
gdb_assert (input_handler == gdb_readline_wrapper_line);
|
gdb_assert (ui->input_handler == gdb_readline_wrapper_line);
|
||||||
input_handler = cleanup->handler_orig;
|
ui->input_handler = cleanup->handler_orig;
|
||||||
|
|
||||||
/* Don't restore our input handler in readline yet. That would make
|
/* Don't restore our input handler in readline yet. That would make
|
||||||
readline prep the terminal (putting it in raw mode), while the
|
readline prep the terminal (putting it in raw mode), while the
|
||||||
@ -826,13 +827,14 @@ gdb_readline_wrapper_cleanup (void *arg)
|
|||||||
char *
|
char *
|
||||||
gdb_readline_wrapper (const char *prompt)
|
gdb_readline_wrapper (const char *prompt)
|
||||||
{
|
{
|
||||||
|
struct ui *ui = current_ui;
|
||||||
struct cleanup *back_to;
|
struct cleanup *back_to;
|
||||||
struct gdb_readline_wrapper_cleanup *cleanup;
|
struct gdb_readline_wrapper_cleanup *cleanup;
|
||||||
char *retval;
|
char *retval;
|
||||||
|
|
||||||
cleanup = XNEW (struct gdb_readline_wrapper_cleanup);
|
cleanup = XNEW (struct gdb_readline_wrapper_cleanup);
|
||||||
cleanup->handler_orig = input_handler;
|
cleanup->handler_orig = ui->input_handler;
|
||||||
input_handler = gdb_readline_wrapper_line;
|
ui->input_handler = gdb_readline_wrapper_line;
|
||||||
|
|
||||||
cleanup->already_prompted_orig = rl_already_prompted;
|
cleanup->already_prompted_orig = rl_already_prompted;
|
||||||
|
|
||||||
|
33
gdb/top.h
33
gdb/top.h
@ -20,7 +20,38 @@
|
|||||||
#ifndef TOP_H
|
#ifndef TOP_H
|
||||||
#define 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. */
|
/* From top.c. */
|
||||||
extern char *saved_command_line;
|
extern char *saved_command_line;
|
||||||
|
Reference in New Issue
Block a user