Make current_ui_out be per UI
[deliverable/binutils-gdb.git] / gdb / cli / cli-interp.c
index 1003cc73bb1d146f6d11569c695c5a3f29e4886d..2d200738b0a58de5668af86a3059444b8abf9b90 100644 (file)
@@ -1,6 +1,6 @@
 /* CLI Definitions for GDB, the GNU debugger.
 
-   Copyright (C) 2002-2013 Free Software Foundation, Inc.
+   Copyright (C) 2002-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "ui-out.h"
 #include "cli-out.h"
 #include "top.h"               /* for "execute_command" */
-#include "gdb_string.h"
-#include "exceptions.h"
+#include "infrun.h"
+#include "observer.h"
 
-struct ui_out *cli_uiout;
+/* The console interpreter.  */
+struct cli_interp
+{
+  /* The ui_out for the console interpreter.  */
+  struct ui_out *cli_uiout;
+};
+
+/* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
+   and returns NULL otherwise.  */
 
-/* These are the ui_out and the interpreter for the console
-   interpreter.  */
+static struct cli_interp *
+as_cli_interp (struct interp *interp)
+{
+  if (strcmp (interp_name (interp), INTERP_CONSOLE) == 0)
+    return (struct cli_interp *) interp_data (interp);
+  return NULL;
+}
 
 /* Longjmp-safe wrapper for "execute_command".  */
 static struct gdb_exception safe_execute_command (struct ui_out *uiout,
                                                  char *command, 
                                                  int from_tty);
+
+/* Observers for several run control events.  If the interpreter is
+   quiet (i.e., another interpreter is being run with
+   interpreter-exec), print nothing.  */
+
+/* Observer for the normal_stop notification.  */
+
+static void
+cli_on_normal_stop (struct bpstats *bs, int print_frame)
+{
+  struct switch_thru_all_uis state;
+
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+      if (cli == NULL)
+       continue;
+
+      if (print_frame)
+       print_stop_event (cli->cli_uiout);
+    }
+}
+
+/* Observer for the signal_received notification.  */
+
+static void
+cli_on_signal_received (enum gdb_signal siggnal)
+{
+  struct switch_thru_all_uis state;
+
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+      if (cli == NULL)
+       continue;
+
+      print_signal_received_reason (cli->cli_uiout, siggnal);
+    }
+}
+
+/* Observer for the end_stepping_range notification.  */
+
+static void
+cli_on_end_stepping_range (void)
+{
+  struct switch_thru_all_uis state;
+
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+      if (cli == NULL)
+       continue;
+
+      print_end_stepping_range_reason (cli->cli_uiout);
+    }
+}
+
+/* Observer for the signalled notification.  */
+
+static void
+cli_on_signal_exited (enum gdb_signal siggnal)
+{
+  struct switch_thru_all_uis state;
+
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+      if (cli == NULL)
+       continue;
+
+      print_signal_exited_reason (cli->cli_uiout, siggnal);
+    }
+}
+
+/* Observer for the exited notification.  */
+
+static void
+cli_on_exited (int exitstatus)
+{
+  struct switch_thru_all_uis state;
+
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+      if (cli == NULL)
+       continue;
+
+      print_exited_reason (cli->cli_uiout, exitstatus);
+    }
+}
+
+/* Observer for the no_history notification.  */
+
+static void
+cli_on_no_history (void)
+{
+  struct switch_thru_all_uis state;
+
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+      if (cli == NULL)
+       continue;
+
+      print_no_history_reason (cli->cli_uiout);
+    }
+}
+
+/* Observer for the sync_execution_done notification.  */
+
+static void
+cli_on_sync_execution_done (void)
+{
+  struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+  if (cli == NULL)
+    return;
+
+  display_gdb_prompt (NULL);
+}
+
+/* Observer for the command_error notification.  */
+
+static void
+cli_on_command_error (void)
+{
+  struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+  if (cli == NULL)
+    return;
+
+  display_gdb_prompt (NULL);
+}
+
 /* These implement the cli out interpreter: */
 
 static void *
 cli_interpreter_init (struct interp *self, int top_level)
 {
-  return NULL;
+  return interp_data (self);
 }
 
 static int
 cli_interpreter_resume (void *data)
 {
+  struct cli_interp *cli = (struct cli_interp *) data;
   struct ui_file *stream;
 
   /*sync_execution = 1; */
@@ -54,17 +208,17 @@ cli_interpreter_resume (void *data)
      previously writing to gdb_stdout, then set it to the new
      gdb_stdout afterwards.  */
 
-  stream = cli_out_set_stream (cli_uiout, gdb_stdout);
+  stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
   if (stream != gdb_stdout)
     {
-      cli_out_set_stream (cli_uiout, stream);
+      cli_out_set_stream (cli->cli_uiout, stream);
       stream = NULL;
     }
 
   gdb_setup_readline ();
 
   if (stream != NULL)
-    cli_out_set_stream (cli_uiout, gdb_stdout);
+    cli_out_set_stream (cli->cli_uiout, gdb_stdout);
 
   return 1;
 }
@@ -76,25 +230,17 @@ 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)
 {
+  struct cli_interp *cli = (struct cli_interp *) data;
   struct ui_file *old_stream;
   struct gdb_exception result;
 
   /* FIXME: cagney/2003-02-01: Need to const char *propogate
      safe_execute_command.  */
-  char *str = strcpy (alloca (strlen (command_str) + 1), command_str);
+  char *str = (char *) alloca (strlen (command_str) + 1);
+  strcpy (str, command_str);
 
   /* gdb_stdout could change between the time cli_uiout was
      initialized and now.  Since we're probably using a different
@@ -103,26 +249,31 @@ cli_interpreter_exec (void *data, const char *command_str)
 
      It is important that it gets reset everytime, since the user
      could set gdb to use a different interpreter.  */
-  old_stream = cli_out_set_stream (cli_uiout, gdb_stdout);
-  result = safe_execute_command (cli_uiout, str, 1);
-  cli_out_set_stream (cli_uiout, old_stream);
+  old_stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
+  result = safe_execute_command (cli->cli_uiout, str, 1);
+  cli_out_set_stream (cli->cli_uiout, old_stream);
   return result;
 }
 
 static struct gdb_exception
 safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
 {
-  volatile struct gdb_exception e;
+  struct gdb_exception e = exception_none;
   struct ui_out *saved_uiout;
 
   /* Save and override the global ``struct ui_out'' builder.  */
   saved_uiout = current_uiout;
   current_uiout = command_uiout;
 
-  TRY_CATCH (e, RETURN_MASK_ALL)
+  TRY
     {
       execute_command (command, from_tty);
     }
+  CATCH (exception, RETURN_MASK_ALL)
+    {
+      e = exception;
+    }
+  END_CATCH
 
   /* Restore the global builder.  */
   current_uiout = saved_uiout;
@@ -136,7 +287,34 @@ safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
 static struct ui_out *
 cli_ui_out (struct interp *self)
 {
-  return cli_uiout;
+  struct cli_interp *cli = (struct cli_interp *) interp_data (self);
+
+  return cli->cli_uiout;
+}
+
+/* The CLI interpreter's vtable.  */
+
+static const struct interp_procs cli_interp_procs = {
+  cli_interpreter_init,                /* init_proc */
+  cli_interpreter_resume,      /* resume_proc */
+  cli_interpreter_suspend,     /* suspend_proc */
+  cli_interpreter_exec,                /* exec_proc */
+  cli_ui_out,                  /* ui_out_proc */
+  NULL,                        /* set_logging_proc */
+  cli_command_loop             /* command_loop_proc */
+};
+
+/* Factory for CLI interpreters.  */
+
+static struct interp *
+cli_interp_factory (const char *name)
+{
+  struct cli_interp *cli = XNEW (struct cli_interp);
+
+  /* Create a default uiout builder for the CLI.  */
+  cli->cli_uiout = cli_out_new (gdb_stdout);
+
+  return interp_new (name, &cli_interp_procs, cli);
 }
 
 /* Standard gdb initialization hook.  */
@@ -145,19 +323,15 @@ extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
 void
 _initialize_cli_interp (void)
 {
-  static const struct interp_procs procs = {
-    cli_interpreter_init,      /* init_proc */
-    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 */
-  };
-  struct interp *cli_interp;
-
-  /* Create a default uiout builder for the CLI.  */
-  cli_uiout = cli_out_new (gdb_stdout);
-  cli_interp = interp_new (INTERP_CONSOLE, &procs);
-
-  interp_add (cli_interp);
+  interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
+
+  /* If changing this, remember to update tui-interp.c as well.  */
+  observer_attach_normal_stop (cli_on_normal_stop);
+  observer_attach_end_stepping_range (cli_on_end_stepping_range);
+  observer_attach_signal_received (cli_on_signal_received);
+  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);
 }
This page took 0.047435 seconds and 4 git commands to generate.