mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
Make display_gdb_prompt CLI-only.
Enabling target-async by default will require implementing sync execution on top of an async target, much like foreground command are implemented on the CLI in async mode. In order to do that, we will need better control of when to print the MI prompt. Currently the interp->display_prompt_p hook is all we have, and MI just always returns false, meaning, make display_gdb_prompt a no-op. We'll need to be able to know to print the MI prompt in some of the conditions that display_gdb_prompt is called from the core, but not all. This is all a litte twisted currently. As we can see, display_gdb_prompt is really CLI specific, so make the console interpreters (console/tui) themselves call it. To be able to do that, and add a few different observers that the interpreters can use to distinguish when or why the the prompt is being printed: #1 - one called whenever a command is cancelled due to an error. #2 - another for when a foreground command just finished. In both cases, CLI wants to print the prompt, while MI doesn't. MI will want to print the prompt in the second case when in a special MI mode. The display_gdb_prompt call in interp_set made me pause. The comment there reads: /* Finally, put up the new prompt to show that we are indeed here. Also, display_gdb_prompt for the console does some readline magic which is needed for the console interpreter, at least... */ But, that looks very much like a no-op to me currently: - the MI interpreter always return false in the prompt hook, meaning actually display no prompt. - the interpreter used at that point is still quiet. And the console/tui interpreters return false in the prompt hook if they're quiet, meaning actually display no prompt. The only remaining possible use would then be the readline magic. But whatever that might have been, it's not reacheable today either, because display_gdb_prompt returns early, before touching readline if the interpreter returns false in the display_prompt_p hook. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_interpreter_display_prompt_p): Delete. (_initialize_cli_interp): Adjust. * event-loop.c: Include "observer.h". (start_event_loop): Notify 'command_error' observers instead of calling display_gdb_prompt. Remove FIXME comment. * event-top.c (display_gdb_prompt): Remove call into the interpreters. * inf-loop.c: Include "observer.h". (inferior_event_handler): Notify 'command_error' observers instead of calling display_gdb_prompt. * infrun.c (fetch_inferior_event): Notify 'sync_execution_done' observers instead of calling display_gdb_prompt. * interps.c (interp_set): Don't call display_gdb_prompt. (current_interp_display_prompt_p): Delete. * interps.h (interp_prompt_p): Delete declaration. (interp_prompt_p_ftype): Delete. (struct interp_procs) <prompt_proc_p>: Delete field. (current_interp_display_prompt_p): Delete declaration. * mi-interp.c (mi_interpreter_prompt_p): Delete. (_initialize_mi_interp): Adjust. * tui-interp.c (tui_init): Install 'sync_execution_done' and 'command_error' observers. (tui_on_sync_execution_done, tui_on_command_error): New functions. (tui_display_prompt_p): Delete. (_initialize_tui_interp): Adjust. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> * observer.texi (sync_execution_done, command_error): New subjects.
This commit is contained in:
parent
fd664c9176
commit
92bcb5f949
@ -1,3 +1,32 @@
|
||||
2014-05-29 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* cli/cli-interp.c (cli_interpreter_display_prompt_p): Delete.
|
||||
(_initialize_cli_interp): Adjust.
|
||||
* event-loop.c: Include "observer.h".
|
||||
(start_event_loop): Notify 'command_error' observers instead of
|
||||
calling display_gdb_prompt. Remove FIXME comment.
|
||||
* event-top.c (display_gdb_prompt): Remove call into the
|
||||
interpreters.
|
||||
* inf-loop.c: Include "observer.h".
|
||||
(inferior_event_handler): Notify 'command_error' observers instead
|
||||
of calling display_gdb_prompt.
|
||||
* infrun.c (fetch_inferior_event): Notify 'sync_execution_done'
|
||||
observers instead of calling display_gdb_prompt.
|
||||
* interps.c (interp_set): Don't call display_gdb_prompt.
|
||||
(current_interp_display_prompt_p): Delete.
|
||||
* interps.h (interp_prompt_p): Delete declaration.
|
||||
(interp_prompt_p_ftype): Delete.
|
||||
(struct interp_procs) <prompt_proc_p>: Delete field.
|
||||
(current_interp_display_prompt_p): Delete declaration.
|
||||
* mi-interp.c (mi_interpreter_prompt_p): Delete.
|
||||
(_initialize_mi_interp): Adjust.
|
||||
* tui-interp.c (tui_init): Install 'sync_execution_done' and
|
||||
'command_error' observers.
|
||||
(tui_on_sync_execution_done, tui_on_command_error): New
|
||||
functions.
|
||||
(tui_display_prompt_p): Delete.
|
||||
(_initialize_tui_interp): Adjust.
|
||||
|
||||
2014-05-29 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/13860
|
||||
|
@ -87,6 +87,24 @@ cli_on_no_history (void)
|
||||
print_no_history_reason (cli_uiout);
|
||||
}
|
||||
|
||||
/* Observer for the sync_execution_done notification. */
|
||||
|
||||
static void
|
||||
cli_on_sync_execution_done (void)
|
||||
{
|
||||
if (!interp_quiet_p (cli_interp))
|
||||
display_gdb_prompt (NULL);
|
||||
}
|
||||
|
||||
/* Observer for the command_error notification. */
|
||||
|
||||
static void
|
||||
cli_on_command_error (void)
|
||||
{
|
||||
if (!interp_quiet_p (cli_interp))
|
||||
display_gdb_prompt (NULL);
|
||||
}
|
||||
|
||||
/* These implement the cli out interpreter: */
|
||||
|
||||
static void *
|
||||
@ -98,6 +116,8 @@ cli_interpreter_init (struct interp *self, int top_level)
|
||||
observer_attach_signal_exited (cli_on_signal_exited);
|
||||
observer_attach_exited (cli_on_exited);
|
||||
observer_attach_no_history (cli_on_no_history);
|
||||
observer_attach_sync_execution_done (cli_on_sync_execution_done);
|
||||
observer_attach_command_error (cli_on_command_error);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -135,16 +155,6 @@ cli_interpreter_suspend (void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Don't display the prompt if we are set quiet. */
|
||||
static int
|
||||
cli_interpreter_display_prompt_p (void *data)
|
||||
{
|
||||
if (interp_quiet_p (NULL))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct gdb_exception
|
||||
cli_interpreter_exec (void *data, const char *command_str)
|
||||
{
|
||||
@ -209,7 +219,6 @@ _initialize_cli_interp (void)
|
||||
cli_interpreter_resume, /* resume_proc */
|
||||
cli_interpreter_suspend, /* suspend_proc */
|
||||
cli_interpreter_exec, /* exec_proc */
|
||||
cli_interpreter_display_prompt_p, /* prompt_proc_p */
|
||||
cli_ui_out, /* ui_out_proc */
|
||||
NULL, /* set_logging_proc */
|
||||
cli_command_loop /* command_loop_proc */
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-05-29 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* observer.texi (sync_execution_done, command_error): New
|
||||
subjects.
|
||||
|
||||
2014-05-29 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/13860
|
||||
|
@ -114,6 +114,14 @@ The inferior program is finished.
|
||||
Reverse execution: target ran out of history info.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void sync_execution_done (void)
|
||||
A synchronous command finished.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void command_error (void)
|
||||
An error was caught while executing a command.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void target_changed (struct target_ops *@var{target})
|
||||
The target's register contents have changed.
|
||||
@end deftypefun
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "exceptions.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_select.h"
|
||||
#include "observer.h"
|
||||
|
||||
/* Tell create_file_handler what events we are interested in.
|
||||
This is used by the select version of the event loop. */
|
||||
@ -441,10 +442,7 @@ start_event_loop (void)
|
||||
/* If we long-jumped out of do_one_event, we probably didn't
|
||||
get around to resetting the prompt, which leaves readline
|
||||
in a messed-up state. Reset it here. */
|
||||
/* FIXME: this should really be a call to a hook that is
|
||||
interface specific, because interfaces can display the
|
||||
prompt in their own way. */
|
||||
display_gdb_prompt (0);
|
||||
observer_notify_command_error ();
|
||||
/* This call looks bizarre, but it is required. If the user
|
||||
entered a command that caused an error,
|
||||
after_char_processing_hook won't be called from
|
||||
|
@ -243,11 +243,6 @@ display_gdb_prompt (char *new_prompt)
|
||||
/* Reset the nesting depth used when trace-commands is set. */
|
||||
reset_command_nest_depth ();
|
||||
|
||||
/* Each interpreter has its own rules on displaying the command
|
||||
prompt. */
|
||||
if (!current_interp_display_prompt_p ())
|
||||
return;
|
||||
|
||||
old_chain = make_cleanup (free_current_contents, &actual_gdb_prompt);
|
||||
|
||||
/* Do not call the python hook on an explicit prompt change as
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "continuations.h"
|
||||
#include "interps.h"
|
||||
#include "top.h"
|
||||
#include "observer.h"
|
||||
|
||||
static int fetch_inferior_event_wrapper (gdb_client_data client_data);
|
||||
|
||||
@ -58,7 +59,7 @@ inferior_event_handler (enum inferior_event_type event_type,
|
||||
do_all_intermediate_continuations (1);
|
||||
do_all_continuations (1);
|
||||
async_enable_stdin ();
|
||||
display_gdb_prompt (0);
|
||||
observer_notify_command_error ();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2950,7 +2950,7 @@ fetch_inferior_event (void *client_data)
|
||||
restore the prompt (a synchronous execution command has finished,
|
||||
and we're ready for input). */
|
||||
if (interpreter_async && was_sync && !sync_execution)
|
||||
display_gdb_prompt (0);
|
||||
observer_notify_sync_execution_done ();
|
||||
|
||||
if (cmd_done
|
||||
&& !was_sync
|
||||
|
@ -204,19 +204,11 @@ interp_set (struct interp *interp, int top_level)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Finally, put up the new prompt to show that we are indeed here.
|
||||
Also, display_gdb_prompt for the console does some readline magic
|
||||
which is needed for the console interpreter, at least... */
|
||||
|
||||
if (!first_time)
|
||||
if (!first_time && !interp_quiet_p (interp))
|
||||
{
|
||||
if (!interp_quiet_p (interp))
|
||||
{
|
||||
xsnprintf (buffer, sizeof (buffer),
|
||||
"Switching to interpreter \"%.24s\".\n", interp->name);
|
||||
ui_out_text (current_uiout, buffer);
|
||||
}
|
||||
display_gdb_prompt (NULL);
|
||||
xsnprintf (buffer, sizeof (buffer),
|
||||
"Switching to interpreter \"%.24s\".\n", interp->name);
|
||||
ui_out_text (current_uiout, buffer);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -304,20 +296,6 @@ current_interp_named_p (const char *interp_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is called in display_gdb_prompt. If the proc returns a zero
|
||||
value, display_gdb_prompt will return without displaying the
|
||||
prompt. */
|
||||
int
|
||||
current_interp_display_prompt_p (void)
|
||||
{
|
||||
if (current_interpreter == NULL
|
||||
|| current_interpreter->procs->prompt_proc_p == NULL)
|
||||
return 0;
|
||||
else
|
||||
return current_interpreter->procs->prompt_proc_p (current_interpreter->
|
||||
data);
|
||||
}
|
||||
|
||||
/* The interpreter that is active while `interp_exec' is active, NULL
|
||||
at all other times. */
|
||||
static struct interp *command_interpreter;
|
||||
|
@ -29,7 +29,6 @@ struct interp;
|
||||
|
||||
extern int interp_resume (struct interp *interp);
|
||||
extern int interp_suspend (struct interp *interp);
|
||||
extern int interp_prompt_p (struct interp *interp);
|
||||
extern struct gdb_exception interp_exec (struct interp *interp,
|
||||
const char *command);
|
||||
extern int interp_quiet_p (struct interp *interp);
|
||||
@ -37,7 +36,6 @@ extern int interp_quiet_p (struct interp *interp);
|
||||
typedef void *(interp_init_ftype) (struct interp *self, int top_level);
|
||||
typedef int (interp_resume_ftype) (void *data);
|
||||
typedef int (interp_suspend_ftype) (void *data);
|
||||
typedef int (interp_prompt_p_ftype) (void *data);
|
||||
typedef struct gdb_exception (interp_exec_ftype) (void *data,
|
||||
const char *command);
|
||||
typedef void (interp_command_loop_ftype) (void *data);
|
||||
@ -53,7 +51,6 @@ struct interp_procs
|
||||
interp_resume_ftype *resume_proc;
|
||||
interp_suspend_ftype *suspend_proc;
|
||||
interp_exec_ftype *exec_proc;
|
||||
interp_prompt_p_ftype *prompt_proc_p;
|
||||
|
||||
/* Returns the ui_out currently used to collect results for this
|
||||
interpreter. It can be a formatter for stdout, as is the case
|
||||
@ -79,7 +76,7 @@ extern const char *interp_name (struct interp *interp);
|
||||
extern struct interp *interp_set_temp (const char *name);
|
||||
|
||||
extern int current_interp_named_p (const char *name);
|
||||
extern int current_interp_display_prompt_p (void);
|
||||
|
||||
extern void current_interp_command_loop (void);
|
||||
|
||||
/* Call this function to give the current interpreter an opportunity
|
||||
|
@ -223,14 +223,6 @@ mi_interpreter_exec (void *data, const char *command)
|
||||
return exception_none;
|
||||
}
|
||||
|
||||
/* Never display the default GDB prompt in MI case. */
|
||||
|
||||
static int
|
||||
mi_interpreter_prompt_p (void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
mi_cmd_interpreter_exec (char *command, char **argv, int argc)
|
||||
{
|
||||
@ -1142,7 +1134,6 @@ _initialize_mi_interp (void)
|
||||
mi_interpreter_resume, /* resume_proc */
|
||||
mi_interpreter_suspend, /* suspend_proc */
|
||||
mi_interpreter_exec, /* exec_proc */
|
||||
mi_interpreter_prompt_p, /* prompt_proc_p */
|
||||
mi_ui_out, /* ui_out_proc */
|
||||
mi_set_logging, /* set_logging_proc */
|
||||
mi_command_loop /* command_loop_proc */
|
||||
|
@ -104,6 +104,24 @@ tui_on_no_history (void)
|
||||
print_no_history_reason (tui_ui_out (tui_interp));
|
||||
}
|
||||
|
||||
/* Observer for the sync_execution_done notification. */
|
||||
|
||||
static void
|
||||
tui_on_sync_execution_done (void)
|
||||
{
|
||||
if (!interp_quiet_p (tui_interp))
|
||||
display_gdb_prompt (NULL);
|
||||
}
|
||||
|
||||
/* Observer for the command_error notification. */
|
||||
|
||||
static void
|
||||
tui_on_command_error (void)
|
||||
{
|
||||
if (!interp_quiet_p (tui_interp))
|
||||
display_gdb_prompt (NULL);
|
||||
}
|
||||
|
||||
/* These implement the TUI interpreter. */
|
||||
|
||||
static void *
|
||||
@ -127,6 +145,8 @@ tui_init (struct interp *self, int top_level)
|
||||
observer_attach_signal_exited (tui_on_signal_exited);
|
||||
observer_attach_exited (tui_on_exited);
|
||||
observer_attach_no_history (tui_on_no_history);
|
||||
observer_attach_sync_execution_done (tui_on_sync_execution_done);
|
||||
observer_attach_command_error (tui_on_command_error);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -177,17 +197,6 @@ tui_suspend (void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Display the prompt if we are silent. */
|
||||
|
||||
static int
|
||||
tui_display_prompt_p (void *data)
|
||||
{
|
||||
if (interp_quiet_p (NULL))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ui_out *
|
||||
tui_ui_out (struct interp *self)
|
||||
{
|
||||
@ -214,7 +223,6 @@ _initialize_tui_interp (void)
|
||||
tui_resume,
|
||||
tui_suspend,
|
||||
tui_exec,
|
||||
tui_display_prompt_p,
|
||||
tui_ui_out,
|
||||
NULL,
|
||||
cli_command_loop
|
||||
|
Loading…
Reference in New Issue
Block a user