Make display_gdb_prompt CLI-only.
authorPedro Alves <palves@redhat.com>
Fri, 23 May 2014 10:37:12 +0000 (11:37 +0100)
committerPedro Alves <palves@redhat.com>
Thu, 29 May 2014 12:47:09 +0000 (13:47 +0100)
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.

12 files changed:
gdb/ChangeLog
gdb/cli/cli-interp.c
gdb/doc/ChangeLog
gdb/doc/observer.texi
gdb/event-loop.c
gdb/event-top.c
gdb/inf-loop.c
gdb/infrun.c
gdb/interps.c
gdb/interps.h
gdb/mi/mi-interp.c
gdb/tui/tui-interp.c

index 4ea78b9ba71276e13dc9affc3acf99803a2db18a..f270c618d1b45a0e82c70cae7ed0f1cd4a2ab747 100644 (file)
@@ -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
index d3badcd265a5e91c1ba2b07429b778cfcea15cc2..dc09b24bb1664c8e2e2397bdc58f69e0c2a03a06 100644 (file)
@@ -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 */
index 7608a329f59f349a28bd328c9bd3927a470e8bb5..f0e58045d68e391411b87ab7c982538c5d5c6e02 100644 (file)
@@ -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
index ee43fc515a7e21a60583db94978265b27b6b004a..27575870ad303626ad9a79333b4a6da5e4683af6 100644 (file)
@@ -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
index 7939739b53ae0117d334b8000853c103ddaa6e66..5999c9734f6cdb901f46ae84aff57daaeed24196 100644 (file)
@@ -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
index f690bc6c504e94b438e9d1cc410f88a31c69cba1..833f49db08b568c735b68e1f244d6fe00b303eec 100644 (file)
@@ -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
index f5293ae8622b25c8b84076c5e61bd907f7f82aa0..247e9d68706a7525692e0d2648d0cc83b14f4328 100644 (file)
@@ -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;
 
index 0b45c2d6980be1c905c0e7ff4ec5764222a7e1d3..9086cd2fb7fae20c6b1b70a6d376469cb1d2f148 100644 (file)
@@ -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
index f6b941c2d7fb4345e91fcdd1a9b820418a2d5288..5a93095b60ecaa047f9123c7acd353bbfa71e80e 100644 (file)
@@ -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;
index 13edf42bf8236f9277a11f1b6fa3a3df5737ef9c..197fa55be03128b310b265584585053ab2f19095 100644 (file)
@@ -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
index e8e30e2a363e76105e905be431d792740f8d1739..e1dd97f668f2851918a004e7865e51450d0b4649 100644 (file)
@@ -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 */
index cd111489668f01efb8ca3edbed5afe72cc3c05c1..147a42434cf4a6453bcf6beb81c526ad130d9f77 100644 (file)
@@ -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