From 92bcb5f949b1d1f14df079bbe9fd3941c1e09919 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 23 May 2014 11:37:12 +0100 Subject: [PATCH] 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 * 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) : 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 * observer.texi (sync_execution_done, command_error): New subjects. --- gdb/ChangeLog | 29 +++++++++++++++++++++++++++++ gdb/cli/cli-interp.c | 31 ++++++++++++++++++++----------- gdb/doc/ChangeLog | 5 +++++ gdb/doc/observer.texi | 8 ++++++++ gdb/event-loop.c | 6 ++---- gdb/event-top.c | 5 ----- gdb/inf-loop.c | 3 ++- gdb/infrun.c | 2 +- gdb/interps.c | 30 ++++-------------------------- gdb/interps.h | 5 +---- gdb/mi/mi-interp.c | 9 --------- gdb/tui/tui-interp.c | 32 ++++++++++++++++++++------------ 12 files changed, 92 insertions(+), 73 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4ea78b9ba71..f270c618d1b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,32 @@ +2014-05-29 Pedro Alves + + * 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) : 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 PR gdb/13860 diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c index d3badcd265a..dc09b24bb16 100644 --- a/gdb/cli/cli-interp.c +++ b/gdb/cli/cli-interp.c @@ -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 */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 7608a329f59..f0e58045d68 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2014-05-29 Pedro Alves + + * observer.texi (sync_execution_done, command_error): New + subjects. + 2014-05-29 Pedro Alves PR gdb/13860 diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi index ee43fc515a7..27575870ad3 100644 --- a/gdb/doc/observer.texi +++ b/gdb/doc/observer.texi @@ -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 diff --git a/gdb/event-loop.c b/gdb/event-loop.c index 7939739b53a..5999c9734f6 100644 --- a/gdb/event-loop.c +++ b/gdb/event-loop.c @@ -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 diff --git a/gdb/event-top.c b/gdb/event-top.c index f690bc6c504..833f49db08b 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -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 diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c index f5293ae8622..247e9d68706 100644 --- a/gdb/inf-loop.c +++ b/gdb/inf-loop.c @@ -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; diff --git a/gdb/infrun.c b/gdb/infrun.c index 0b45c2d6980..9086cd2fb7f 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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 diff --git a/gdb/interps.c b/gdb/interps.c index f6b941c2d7f..5a93095b60e 100644 --- a/gdb/interps.c +++ b/gdb/interps.c @@ -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; diff --git a/gdb/interps.h b/gdb/interps.h index 13edf42bf82..197fa55be03 100644 --- a/gdb/interps.h +++ b/gdb/interps.h @@ -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 diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index e8e30e2a363..e1dd97f668f 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -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 */ diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c index cd111489668..147a42434cf 100644 --- a/gdb/tui/tui-interp.c +++ b/gdb/tui/tui-interp.c @@ -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 -- 2.30.2