+
+/* See cli-interp.h.
+
+ Breakpoint hits should always be mirrored to a console. Deciding
+ what to mirror to a console wrt to breakpoints and random stops
+ gets messy real fast. E.g., say "s" trips on a breakpoint. We'd
+ clearly want to mirror the event to the console in this case. But
+ what about more complicated cases like "s&; thread n; s&", and one
+ of those steps spawning a new thread, and that thread hitting a
+ breakpoint? It's impossible in general to track whether the thread
+ had any relation to the commands that had been executed. So we
+ just simplify and always mirror breakpoints and random events to
+ all consoles.
+
+ OTOH, we should print the source line to the console when stepping
+ or other similar commands, iff the step was started by that console
+ (or in MI's case, by a console command), but not if it was started
+ with MI's -exec-step or similar. */
+
+int
+should_print_stop_to_console (struct interp *console_interp,
+ struct thread_info *tp)
+{
+ if ((bpstat_what (tp->control.stop_bpstat).main_action
+ == BPSTAT_WHAT_STOP_NOISY)
+ || tp->thread_fsm == NULL
+ || tp->thread_fsm->command_interp == console_interp
+ || !thread_fsm_finished_p (tp->thread_fsm))
+ return 1;
+ return 0;
+}
+
+/* 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)
+{
+ if (!print_frame)
+ return;
+
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct interp *interp = top_level_interpreter ();
+ struct cli_interp *cli = as_cli_interp (interp);
+ struct thread_info *thread;
+
+ if (cli == NULL)
+ continue;
+
+ thread = inferior_thread ();
+ if (should_print_stop_to_console (interp, thread))
+ print_stop_event (cli->cli_uiout);
+ }
+}
+
+/* Observer for the signal_received notification. */
+
+static void
+cli_on_signal_received (enum gdb_signal siggnal)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ 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)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ 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)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ 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)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ 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)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ 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);
+}
+
+/* Observer for the user_selected_context_changed notification. */
+
+static void
+cli_on_user_selected_context_changed (user_selected_what selection)
+{
+ struct thread_info *tp;
+
+ /* This event is suppressed. */
+ if (cli_suppress_notification.user_selected_context)
+ return;
+
+ tp = find_thread_ptid (inferior_ptid);
+
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
+
+ if (cli == NULL)
+ continue;
+
+ if (selection & USER_SELECTED_INFERIOR)
+ print_selected_inferior (cli->cli_uiout);
+
+ if (tp != NULL
+ && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
+ print_selected_thread_frame (cli->cli_uiout, selection);
+ }
+}
+
+/* pre_command_loop implementation. */
+
+void
+cli_interpreter_pre_command_loop (struct interp *self)
+{
+ display_gdb_prompt (0);
+}
+