Make the interpreters be per UI

Make each UI have its own interpreter list, top level interpreter,
current interpreter, etc.  The "interpreter_async" global is not
really specific to an struct interp (it crosses interpreter-exec ...),
so I moved it to "struct ui" directly, while the other globals were
left hidden in interps.c, opaque to the rest of GDB.

gdb/ChangeLog:
2016-06-21  Pedro Alves  <palves@redhat.com>

	* breakpoint.c (bpstat_do_actions_1): Access the current UI's
	async field instead of the interpreter_async global.
	* cli/cli-script.c (execute_user_command, while_command)
	(if_command, script_from_file): Likewise.
	* compile/compile.c: Include top.h instead of interps.h.
	(compile_file_command, compile_code_command)
	(compile_print_command): Access the current UI's async field
	instead of the interpreter_async global.
	* guile/guile.c: Include top.h instead of interps.h.
	(guile_repl_command, guile_command, gdbscm_execute_gdb_command):
	Access the current UI's async field instead of the
	interpreter_async global.
	* guile/scm-ports.c: Include top.h instead of interps.h.
	(ioscm_with_output_to_port_worker): Access the current UI's async
	field instead of the interpreter_async global.
	* inf-loop.c (inferior_event_handler): Likewise.
	* infcall.c (run_inferior_call): Likewise.
	* infrun.c (reinstall_readline_callback_handler_cleanup)
	(fetch_inferior_event): Likewise.
	* interps.c (interpreter_async): Delete.
	(struct ui_interp_info): New.
	(get_current_interp_info): New function.
	(interp_list, current_interpreter, top_level_interpreter_ptr):
	Delete.
	(interp_add, interp_set, interp_lookup, interp_ui_out)
	(current_interp_set_logging, interp_set_temp)
	(current_interp_named_p): Adjust to per-UI interpreters.
	(command_interpreter): Delete.
	(command_interp, current_interp_command_loop, interp_quiet_p)
	(interp_exec, interpreter_exec_cmd, interpreter_completer)
	(top_level_interpreter, top_level_interpreter_data): Adjust to
	per-UI interpreters.
	* interps.h (interpreter_async): Delete.
	* main.c (captured_command_loop): Access the current UI's async
	field instead of the interpreter_async global.
	* python/python.c (python_interactive_command, python_command)
	(execute_gdb_command): Likewise.
	* top.c (maybe_wait_sync_command_done, execute_command_to_string):
	Access the current UI's async field instead of the
	interpreter_async global.
	* top.h (struct tl_interp_info): Forward declare.
	(struct ui) <interp_info, async>: New fields.
This commit is contained in:
Pedro Alves 2016-06-21 01:11:45 +01:00
parent 79aa2fe86f
commit cb81451067
15 changed files with 197 additions and 107 deletions

View file

@ -1,3 +1,48 @@
2016-06-21 Pedro Alves <palves@redhat.com>
* breakpoint.c (bpstat_do_actions_1): Access the current UI's
async field instead of the interpreter_async global.
* cli/cli-script.c (execute_user_command, while_command)
(if_command, script_from_file): Likewise.
* compile/compile.c: Include top.h instead of interps.h.
(compile_file_command, compile_code_command)
(compile_print_command): Access the current UI's async field
instead of the interpreter_async global.
* guile/guile.c: Include top.h instead of interps.h.
(guile_repl_command, guile_command, gdbscm_execute_gdb_command):
Access the current UI's async field instead of the
interpreter_async global.
* guile/scm-ports.c: Include top.h instead of interps.h.
(ioscm_with_output_to_port_worker): Access the current UI's async
field instead of the interpreter_async global.
* inf-loop.c (inferior_event_handler): Likewise.
* infcall.c (run_inferior_call): Likewise.
* infrun.c (reinstall_readline_callback_handler_cleanup)
(fetch_inferior_event): Likewise.
* interps.c (interpreter_async): Delete.
(struct ui_interp_info): New.
(get_current_interp_info): New function.
(interp_list, current_interpreter, top_level_interpreter_ptr):
Delete.
(interp_add, interp_set, interp_lookup, interp_ui_out)
(current_interp_set_logging, interp_set_temp)
(current_interp_named_p): Adjust to per-UI interpreters.
(command_interpreter): Delete.
(command_interp, current_interp_command_loop, interp_quiet_p)
(interp_exec, interpreter_exec_cmd, interpreter_completer)
(top_level_interpreter, top_level_interpreter_data): Adjust to
per-UI interpreters.
* interps.h (interpreter_async): Delete.
* main.c (captured_command_loop): Access the current UI's async
field instead of the interpreter_async global.
* python/python.c (python_interactive_command, python_command)
(execute_gdb_command): Likewise.
* top.c (maybe_wait_sync_command_done, execute_command_to_string):
Access the current UI's async field instead of the
interpreter_async global.
* top.h (struct tl_interp_info): Forward declare.
(struct ui) <interp_info, async>: New fields.
2016-06-21 Pedro Alves <palves@redhat.com> 2016-06-21 Pedro Alves <palves@redhat.com>
* main.c (gdb_stdout, gdb_stderr, gdb_stdlog, gdb_stdin): Delete * main.c (gdb_stdout, gdb_stderr, gdb_stdlog, gdb_stdin): Delete

View file

@ -4726,7 +4726,7 @@ bpstat_do_actions_1 (bpstat *bsp)
if (breakpoint_proceeded) if (breakpoint_proceeded)
{ {
if (interpreter_async) if (current_ui->async)
/* If we are in async mode, then the target might be still /* If we are in async mode, then the target might be still
running, not stopped at any breakpoint, so nothing for running, not stopped at any breakpoint, so nothing for
us to do here -- just return to the event loop. */ us to do here -- just return to the event loop. */

View file

@ -379,8 +379,8 @@ execute_user_command (struct cmd_list_element *c, char *args)
not confused with Insight. */ not confused with Insight. */
in_user_command = 1; in_user_command = 1;
make_cleanup_restore_integer (&interpreter_async); make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
command_nest_depth++; command_nest_depth++;
while (cmdlines) while (cmdlines)
@ -661,8 +661,8 @@ while_command (char *arg, int from_tty)
if (command == NULL) if (command == NULL)
return; return;
old_chain = make_cleanup_restore_integer (&interpreter_async); old_chain = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
execute_control_command_untraced (command); execute_control_command_untraced (command);
free_command_lines (&command); free_command_lines (&command);
@ -685,8 +685,8 @@ if_command (char *arg, int from_tty)
if (command == NULL) if (command == NULL)
return; return;
old_chain = make_cleanup_restore_integer (&interpreter_async); old_chain = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
execute_control_command_untraced (command); execute_control_command_untraced (command);
free_command_lines (&command); free_command_lines (&command);
@ -1688,8 +1688,8 @@ script_from_file (FILE *stream, const char *file)
source_line_number = 0; source_line_number = 0;
source_file_name = file; source_file_name = file;
make_cleanup_restore_integer (&interpreter_async); make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
{ {

View file

@ -18,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h" #include "defs.h"
#include "interps.h" #include "top.h"
#include "ui-out.h" #include "ui-out.h"
#include "command.h" #include "command.h"
#include "cli/cli-script.h" #include "cli/cli-script.h"
@ -91,8 +91,8 @@ compile_file_command (char *arg, int from_tty)
char *buffer; char *buffer;
struct cleanup *cleanup; struct cleanup *cleanup;
cleanup = make_cleanup_restore_integer (&interpreter_async); cleanup = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
/* Check the user did not just <enter> after command. */ /* Check the user did not just <enter> after command. */
if (arg == NULL) if (arg == NULL)
@ -133,8 +133,8 @@ compile_code_command (char *arg, int from_tty)
struct cleanup *cleanup; struct cleanup *cleanup;
enum compile_i_scope_types scope = COMPILE_I_SIMPLE_SCOPE; enum compile_i_scope_types scope = COMPILE_I_SIMPLE_SCOPE;
cleanup = make_cleanup_restore_integer (&interpreter_async); cleanup = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
if (arg != NULL && check_raw_argument (&arg)) if (arg != NULL && check_raw_argument (&arg))
{ {
@ -187,8 +187,8 @@ compile_print_command (char *arg_param, int from_tty)
enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE; enum compile_i_scope_types scope = COMPILE_I_PRINT_ADDRESS_SCOPE;
struct format_data fmt; struct format_data fmt;
cleanup = make_cleanup_restore_integer (&interpreter_async); cleanup = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
/* Passing &FMT as SCOPE_DATA is safe as do_module_cleanup will not /* Passing &FMT as SCOPE_DATA is safe as do_module_cleanup will not
touch the stale pointer if compile_object_run has already quit. */ touch the stale pointer if compile_object_run has already quit. */

View file

@ -27,7 +27,7 @@
#include "cli/cli-utils.h" #include "cli/cli-utils.h"
#include "command.h" #include "command.h"
#include "gdbcmd.h" #include "gdbcmd.h"
#include "interps.h" #include "top.h"
#include "extension-priv.h" #include "extension-priv.h"
#include "utils.h" #include "utils.h"
#include "version.h" #include "version.h"
@ -165,8 +165,8 @@ guile_repl_command (char *arg, int from_tty)
{ {
struct cleanup *cleanup; struct cleanup *cleanup;
cleanup = make_cleanup_restore_integer (&interpreter_async); cleanup = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
arg = skip_spaces (arg); arg = skip_spaces (arg);
@ -198,8 +198,8 @@ guile_command (char *arg, int from_tty)
{ {
struct cleanup *cleanup; struct cleanup *cleanup;
cleanup = make_cleanup_restore_integer (&interpreter_async); cleanup = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
arg = skip_spaces (arg); arg = skip_spaces (arg);
@ -328,8 +328,8 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest)
{ {
struct cleanup *inner_cleanups; struct cleanup *inner_cleanups;
inner_cleanups = make_cleanup_restore_integer (&interpreter_async); inner_cleanups = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
prevent_dont_repeat (); prevent_dont_repeat ();
if (to_string) if (to_string)

View file

@ -23,7 +23,7 @@
#include "defs.h" #include "defs.h"
#include "gdb_select.h" #include "gdb_select.h"
#include "interps.h" #include "top.h"
#include "target.h" #include "target.h"
#include "guile-internal.h" #include "guile-internal.h"
@ -517,8 +517,8 @@ ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
cleanups = set_batch_flag_and_make_cleanup_restore_page_info (); cleanups = set_batch_flag_and_make_cleanup_restore_page_info ();
make_cleanup_restore_integer (&interpreter_async); make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
port_file = ioscm_file_port_new (port); port_file = ioscm_file_port_new (port);

View file

@ -61,7 +61,7 @@ inferior_event_handler (enum inferior_event_type event_type,
/* When running a command list (from a user command, say), these /* When running a command list (from a user command, say), these
are only run when the command list is all done. */ are only run when the command list is all done. */
if (interpreter_async) if (current_ui->async)
{ {
check_frame_language_change (); check_frame_language_change ();

View file

@ -560,13 +560,13 @@ run_inferior_call (struct call_thread_fsm *sm,
ptid_t call_thread_ptid = call_thread->ptid; ptid_t call_thread_ptid = call_thread->ptid;
int saved_sync_execution = sync_execution; int saved_sync_execution = sync_execution;
int was_running = call_thread->state == THREAD_RUNNING; int was_running = call_thread->state == THREAD_RUNNING;
int saved_interpreter_async = interpreter_async; int saved_ui_async = current_ui->async;
/* Infcalls run synchronously, in the foreground. */ /* Infcalls run synchronously, in the foreground. */
sync_execution = 1; sync_execution = 1;
/* So that we don't print the prompt prematurely in /* So that we don't print the prompt prematurely in
fetch_inferior_event. */ fetch_inferior_event. */
interpreter_async = 0; current_ui->async = 0;
call_thread->control.in_infcall = 1; call_thread->control.in_infcall = 1;
@ -601,7 +601,7 @@ run_inferior_call (struct call_thread_fsm *sm,
again here. In other cases, stdin will be re-enabled by again here. In other cases, stdin will be re-enabled by
inferior_event_handler, when an exception is thrown. */ inferior_event_handler, when an exception is thrown. */
sync_execution = saved_sync_execution; sync_execution = saved_sync_execution;
interpreter_async = saved_interpreter_async; current_ui->async = saved_ui_async;
/* At this point the current thread may have changed. Refresh /* At this point the current thread may have changed. Refresh
CALL_THREAD as it could be invalid if its thread has exited. */ CALL_THREAD as it could be invalid if its thread has exited. */

View file

@ -3802,7 +3802,7 @@ wait_for_inferior (void)
static void static void
reinstall_readline_callback_handler_cleanup (void *arg) reinstall_readline_callback_handler_cleanup (void *arg)
{ {
if (!interpreter_async) if (!current_ui->async)
{ {
/* We're not going back to the top level event loop yet. Don't /* We're not going back to the top level event loop yet. Don't
install the readline callback, as it'd prep the terminal, install the readline callback, as it'd prep the terminal,
@ -3989,7 +3989,7 @@ fetch_inferior_event (void *client_data)
/* If the inferior was in sync execution mode, and now isn't, /* If the inferior was in sync execution mode, and now isn't,
restore the prompt (a synchronous execution command has finished, restore the prompt (a synchronous execution command has finished,
and we're ready for input). */ and we're ready for input). */
if (interpreter_async && was_sync && !sync_execution) if (current_ui->async && was_sync && !sync_execution)
observer_notify_sync_execution_done (); observer_notify_sync_execution_done ();
if (cmd_done if (cmd_done

View file

@ -39,11 +39,31 @@
#include "top.h" /* For command_loop. */ #include "top.h" /* For command_loop. */
#include "continuations.h" #include "continuations.h"
/* True if the current interpreter in is async mode. See interps.h /* Each UI has its own independent set of interpreters. */
for more details. This starts out disabled, until all the explicit
command line arguments (e.g., `gdb -ex "start" -ex "next"') are struct ui_interp_info
processed. */ {
int interpreter_async = 0; /* Each top level has its own independent set of interpreters. */
struct interp *interp_list;
struct interp *current_interpreter;
struct interp *top_level_interpreter;
/* The interpreter that is active while `interp_exec' is active, NULL
at all other times. */
struct interp *command_interpreter;
};
/* Get the current UI's ui_interp_info object. Never returns NULL. */
static struct ui_interp_info *
get_current_interp_info (void)
{
struct ui *ui = current_ui;
if (ui->interp_info == NULL)
ui->interp_info = XCNEW (struct ui_interp_info);
return ui->interp_info;
}
struct interp struct interp
{ {
@ -71,12 +91,6 @@ struct interp
void _initialize_interpreter (void); void _initialize_interpreter (void);
/* Variables local to this file: */
static struct interp *interp_list = NULL;
static struct interp *current_interpreter = NULL;
static struct interp *top_level_interpreter_ptr = NULL;
/* interp_new - This allocates space for a new interpreter, /* interp_new - This allocates space for a new interpreter,
fills the fields from the inputs, and returns a pointer to the fills the fields from the inputs, and returns a pointer to the
interpreter. */ interpreter. */
@ -104,10 +118,12 @@ interp_new (const char *name, const struct interp_procs *procs)
void void
interp_add (struct interp *interp) interp_add (struct interp *interp)
{ {
struct ui_interp_info *ui_interp = get_current_interp_info ();
gdb_assert (interp_lookup (interp->name) == NULL); gdb_assert (interp_lookup (interp->name) == NULL);
interp->next = interp_list; interp->next = ui_interp->interp_list;
interp_list = interp; ui_interp->interp_list = interp;
} }
/* This sets the current interpreter to be INTERP. If INTERP has not /* This sets the current interpreter to be INTERP. If INTERP has not
@ -127,24 +143,24 @@ interp_add (struct interp *interp)
int int
interp_set (struct interp *interp, int top_level) interp_set (struct interp *interp, int top_level)
{ {
struct interp *old_interp = current_interpreter; struct ui_interp_info *ui_interp = get_current_interp_info ();
struct interp *old_interp = ui_interp->current_interpreter;
int first_time = 0; int first_time = 0;
char buffer[64]; char buffer[64];
/* If we already have an interpreter, then trying to /* If we already have an interpreter, then trying to
set top level interpreter is kinda pointless. */ set top level interpreter is kinda pointless. */
gdb_assert (!top_level || !current_interpreter); gdb_assert (!top_level || !ui_interp->current_interpreter);
gdb_assert (!top_level || !top_level_interpreter_ptr); gdb_assert (!top_level || !ui_interp->top_level_interpreter);
if (current_interpreter != NULL) if (old_interp != NULL)
{ {
ui_out_flush (current_uiout); ui_out_flush (current_uiout);
if (current_interpreter->procs->suspend_proc if (old_interp->procs->suspend_proc
&& !current_interpreter->procs->suspend_proc (current_interpreter-> && !old_interp->procs->suspend_proc (old_interp->data))
data))
{ {
error (_("Could not suspend interpreter \"%s\"."), error (_("Could not suspend interpreter \"%s\"."),
current_interpreter->name); old_interp->name);
} }
} }
else else
@ -152,18 +168,18 @@ interp_set (struct interp *interp, int top_level)
first_time = 1; first_time = 1;
} }
current_interpreter = interp; ui_interp->current_interpreter = interp;
if (top_level) if (top_level)
top_level_interpreter_ptr = interp; ui_interp->top_level_interpreter = interp;
/* We use interpreter_p for the "set interpreter" variable, so we need /* We use interpreter_p for the "set interpreter" variable, so we need
to make sure we have a malloc'ed copy for the set command to free. */ to make sure we have a malloc'ed copy for the set command to free. */
if (interpreter_p != NULL if (interpreter_p != NULL
&& strcmp (current_interpreter->name, interpreter_p) != 0) && strcmp (interp->name, interpreter_p) != 0)
{ {
xfree (interpreter_p); xfree (interpreter_p);
interpreter_p = xstrdup (current_interpreter->name); interpreter_p = xstrdup (interp->name);
} }
/* Run the init proc. If it fails, try to restore the old interp. */ /* Run the init proc. If it fails, try to restore the old interp. */
@ -209,12 +225,15 @@ interp_set (struct interp *interp, int top_level)
struct interp * struct interp *
interp_lookup (const char *name) interp_lookup (const char *name)
{ {
struct ui_interp_info *ui_interp = get_current_interp_info ();
struct interp *interp; struct interp *interp;
if (name == NULL || strlen (name) == 0) if (name == NULL || strlen (name) == 0)
return NULL; return NULL;
for (interp = interp_list; interp != NULL; interp = interp->next) for (interp = ui_interp->interp_list;
interp != NULL;
interp = interp->next)
{ {
if (strcmp (interp->name, name) == 0) if (strcmp (interp->name, name) == 0)
return interp; return interp;
@ -228,34 +247,37 @@ interp_lookup (const char *name)
struct ui_out * struct ui_out *
interp_ui_out (struct interp *interp) interp_ui_out (struct interp *interp)
{ {
if (interp != NULL) struct ui_interp_info *ui_interp = get_current_interp_info ();
return interp->procs->ui_out_proc (interp);
return current_interpreter->procs->ui_out_proc (current_interpreter); if (interp == NULL)
interp = ui_interp->current_interpreter;
return interp->procs->ui_out_proc (interp);
} }
int int
current_interp_set_logging (int start_log, struct ui_file *out, current_interp_set_logging (int start_log, struct ui_file *out,
struct ui_file *logfile) struct ui_file *logfile)
{ {
if (current_interpreter == NULL struct ui_interp_info *ui_interp = get_current_interp_info ();
|| current_interpreter->procs->set_logging_proc == NULL) struct interp *interp = ui_interp->current_interpreter;
if (interp == NULL
|| interp->procs->set_logging_proc == NULL)
return 0; return 0;
return current_interpreter->procs->set_logging_proc (current_interpreter, return interp->procs->set_logging_proc (interp, start_log, out, logfile);
start_log, out,
logfile);
} }
/* Temporarily overrides the current interpreter. */ /* Temporarily overrides the current interpreter. */
struct interp * struct interp *
interp_set_temp (const char *name) interp_set_temp (const char *name)
{ {
struct ui_interp_info *ui_interp = get_current_interp_info ();
struct interp *interp = interp_lookup (name); struct interp *interp = interp_lookup (name);
struct interp *old_interp = current_interpreter; struct interp *old_interp = ui_interp->current_interpreter;
if (interp) if (interp)
current_interpreter = interp; ui_interp->current_interpreter = interp;
return old_interp; return old_interp;
} }
@ -279,16 +301,15 @@ interp_name (struct interp *interp)
int int
current_interp_named_p (const char *interp_name) current_interp_named_p (const char *interp_name)
{ {
if (current_interpreter) struct ui_interp_info *ui_interp = get_current_interp_info ();
return (strcmp (current_interpreter->name, interp_name) == 0); struct interp *interp = ui_interp->current_interpreter;
if (interp != NULL)
return (strcmp (interp->name, interp_name) == 0);
return 0; return 0;
} }
/* The interpreter that is active while `interp_exec' is active, NULL
at all other times. */
static struct interp *command_interpreter;
/* The interpreter that was active when a command was executed. /* The interpreter that was active when a command was executed.
Normally that'd always be CURRENT_INTERPRETER, except that MI's Normally that'd always be CURRENT_INTERPRETER, except that MI's
-interpreter-exec command doesn't actually flip the current -interpreter-exec command doesn't actually flip the current
@ -302,28 +323,35 @@ static struct interp *command_interpreter;
struct interp * struct interp *
command_interp (void) command_interp (void)
{ {
if (command_interpreter != NULL) struct ui_interp_info *ui_interp = get_current_interp_info ();
return command_interpreter;
if (ui_interp->command_interpreter != NULL)
return ui_interp->command_interpreter;
else else
return current_interpreter; return ui_interp->current_interpreter;
} }
/* Run the current command interpreter's main loop. */ /* Run the current command interpreter's main loop. */
void void
current_interp_command_loop (void) current_interp_command_loop (void)
{ {
gdb_assert (current_interpreter != NULL); struct ui_interp_info *ui_interp = get_current_interp_info ();
struct interp *interp = ui_interp->current_interpreter;
current_interpreter->procs->command_loop_proc (current_interpreter->data); gdb_assert (ui_interp->current_interpreter != NULL);
interp->procs->command_loop_proc (interp->data);
} }
int int
interp_quiet_p (struct interp *interp) interp_quiet_p (struct interp *interp)
{ {
struct ui_interp_info *ui_interp = get_current_interp_info ();
if (interp != NULL) if (interp != NULL)
return interp->quiet_p; return interp->quiet_p;
else else
return current_interpreter->quiet_p; return ui_interp->current_interpreter->quiet_p;
} }
static int static int
@ -341,18 +369,20 @@ interp_set_quiet (struct interp *interp, int quiet)
struct gdb_exception struct gdb_exception
interp_exec (struct interp *interp, const char *command_str) interp_exec (struct interp *interp, const char *command_str)
{ {
struct ui_interp_info *ui_interp = get_current_interp_info ();
struct gdb_exception ex; struct gdb_exception ex;
struct interp *save_command_interp; struct interp *save_command_interp;
gdb_assert (interp->procs->exec_proc != NULL); gdb_assert (interp->procs->exec_proc != NULL);
/* See `command_interp' for why we do this. */ /* See `command_interp' for why we do this. */
save_command_interp = command_interpreter; save_command_interp = ui_interp->command_interpreter;
command_interpreter = interp; ui_interp->command_interpreter = interp;
ex = interp->procs->exec_proc (interp->data, command_str); ex = interp->procs->exec_proc (interp->data, command_str);
command_interpreter = save_command_interp; ui_interp->command_interpreter = save_command_interp;
return ex; return ex;
} }
@ -379,6 +409,7 @@ clear_interpreter_hooks (void)
static void static void
interpreter_exec_cmd (char *args, int from_tty) interpreter_exec_cmd (char *args, int from_tty)
{ {
struct ui_interp_info *ui_interp = get_current_interp_info ();
struct interp *old_interp, *interp_to_use; struct interp *old_interp, *interp_to_use;
char **prules = NULL; char **prules = NULL;
char **trule = NULL; char **trule = NULL;
@ -400,7 +431,7 @@ interpreter_exec_cmd (char *args, int from_tty)
if (nrules < 2) if (nrules < 2)
error (_("usage: interpreter-exec <interpreter> [ <command> ... ]")); error (_("usage: interpreter-exec <interpreter> [ <command> ... ]"));
old_interp = current_interpreter; old_interp = ui_interp->current_interpreter;
interp_to_use = interp_lookup (prules[0]); interp_to_use = interp_lookup (prules[0]);
if (interp_to_use == NULL) if (interp_to_use == NULL)
@ -438,12 +469,15 @@ static VEC (char_ptr) *
interpreter_completer (struct cmd_list_element *ignore, interpreter_completer (struct cmd_list_element *ignore,
const char *text, const char *word) const char *text, const char *word)
{ {
struct ui_interp_info *ui_interp = get_current_interp_info ();
int textlen; int textlen;
VEC (char_ptr) *matches = NULL; VEC (char_ptr) *matches = NULL;
struct interp *interp; struct interp *interp;
textlen = strlen (text); textlen = strlen (text);
for (interp = interp_list; interp != NULL; interp = interp->next) for (interp = ui_interp->interp_list;
interp != NULL;
interp = interp->next)
{ {
if (strncmp (interp->name, text, textlen) == 0) if (strncmp (interp->name, text, textlen) == 0)
{ {
@ -474,14 +508,19 @@ interpreter_completer (struct cmd_list_element *ignore,
struct interp * struct interp *
top_level_interpreter (void) top_level_interpreter (void)
{ {
return top_level_interpreter_ptr; struct ui_interp_info *ui_interp = get_current_interp_info ();
return ui_interp->top_level_interpreter;
} }
void * void *
top_level_interpreter_data (void) top_level_interpreter_data (void)
{ {
gdb_assert (top_level_interpreter_ptr); struct interp *interp;
return top_level_interpreter_ptr->data;
interp = top_level_interpreter ();
gdb_assert (interp != NULL);
return interp->data;
} }
/* This just adds the "interpreter-exec" command. */ /* This just adds the "interpreter-exec" command. */

View file

@ -93,15 +93,6 @@ extern struct interp *top_level_interpreter (void);
extern struct interp *command_interp (void); extern struct interp *command_interp (void);
/* True if the current interpreter is in async mode, false if in sync
mode. If in sync mode, running a synchronous execution command
(with execute_command, e.g, "next") will not return until the
command is finished. If in async mode, then running a synchronous
command returns right after resuming the target. Waiting for the
command's completion is later done on the top event loop (using
continuations). */
extern int interpreter_async;
extern void clear_interpreter_hooks (void); extern void clear_interpreter_hooks (void);
/* well-known interpreters */ /* well-known interpreters */

View file

@ -311,7 +311,7 @@ captured_command_loop (void *data)
{ {
/* Top-level execution commands can be run in the background from /* Top-level execution commands can be run in the background from
here on. */ here on. */
interpreter_async = 1; current_ui->async = 1;
current_interp_command_loop (); current_interp_command_loop ();
/* FIXME: cagney/1999-11-05: A correct command_loop() implementaton /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton

View file

@ -321,8 +321,8 @@ python_interactive_command (char *arg, int from_tty)
struct cleanup *cleanup; struct cleanup *cleanup;
int err; int err;
cleanup = make_cleanup_restore_integer (&interpreter_async); cleanup = make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
arg = skip_spaces (arg); arg = skip_spaces (arg);
@ -466,8 +466,8 @@ python_command (char *arg, int from_tty)
cleanup = ensure_python_env (get_current_arch (), current_language); cleanup = ensure_python_env (get_current_arch (), current_language);
make_cleanup_restore_integer (&interpreter_async); make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
arg = skip_spaces (arg); arg = skip_spaces (arg);
if (arg && *arg) if (arg && *arg)
@ -650,8 +650,8 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
struct cleanup *cleanup = make_cleanup (xfree, copy); struct cleanup *cleanup = make_cleanup (xfree, copy);
struct interp *interp; struct interp *interp;
make_cleanup_restore_integer (&interpreter_async); make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
make_cleanup_restore_ui_out (&current_uiout); make_cleanup_restore_ui_out (&current_uiout);
/* Use the console interpreter uiout to have the same print format /* Use the console interpreter uiout to have the same print format

View file

@ -407,7 +407,7 @@ maybe_wait_sync_command_done (int was_sync)
command's list, running command hooks or similars), and we command's list, running command hooks or similars), and we
just ran a synchronous command that started the target, wait just ran a synchronous command that started the target, wait
for that command to end. */ for that command to end. */
if (!interpreter_async && !was_sync && sync_execution) if (!current_ui->async && !was_sync && sync_execution)
wait_sync_command_done (); wait_sync_command_done ();
} }
@ -525,8 +525,8 @@ execute_command_to_string (char *p, int from_tty)
restoration callbacks. */ restoration callbacks. */
cleanup = set_batch_flag_and_make_cleanup_restore_page_info (); cleanup = set_batch_flag_and_make_cleanup_restore_page_info ();
make_cleanup_restore_integer (&interpreter_async); make_cleanup_restore_integer (&current_ui->async);
interpreter_async = 0; current_ui->async = 0;
str_file = mem_fileopen (); str_file = mem_fileopen ();

View file

@ -23,6 +23,8 @@
#include "buffer.h" #include "buffer.h"
#include "event-loop.h" #include "event-loop.h"
struct tl_interp_info;
/* All about a user interface instance. Each user interface has its /* All about a user interface instance. Each user interface has its
own I/O files/streams, readline state, its own top level own I/O files/streams, readline state, its own top level
interpreter (for the main UI, this is the interpreter specified interpreter (for the main UI, this is the interpreter specified
@ -50,6 +52,19 @@ struct ui
processing. */ processing. */
void (*input_handler) (char *); void (*input_handler) (char *);
/* Each UI has its own independent set of interpreters. */
struct ui_interp_info *interp_info;
/* True if the UI is in async mode, false if in sync mode. If in
sync mode, a synchronous execution command (e.g, "next") does not
return until the command is finished. If in async mode, then
running a synchronous command returns right after resuming the
target. Waiting for the command's completion is later done on
the top event loop. For the main UI, this starts out disabled,
until all the explicit command line arguments (e.g., `gdb -ex
"start" -ex "next"') are processed. */
int async;
/* The fields below that start with "m_" are "private". They're /* The fields below that start with "m_" are "private". They're
meant to be accessed through wrapper macros that make them look meant to be accessed through wrapper macros that make them look
like globals. */ like globals. */