+/* Return the MI interpreter, if it is active -- either because it's
+ the top-level interpreter or the interpreter executing the current
+ command. Returns NULL if the MI interpreter is not being used. */
+
+static struct interp *
+find_mi_interpreter (void)
+{
+ struct interp *interp;
+
+ interp = top_level_interpreter ();
+ if (ui_out_is_mi_like_p (interp_ui_out (interp)))
+ return interp;
+
+ interp = command_interp ();
+ if (ui_out_is_mi_like_p (interp_ui_out (interp)))
+ return interp;
+
+ return NULL;
+}
+
+/* Return the MI_INTERP structure of the active MI interpreter.
+ Returns NULL if MI is not active. */
+
+static struct mi_interp *
+mi_interp_data (void)
+{
+ struct interp *interp = find_mi_interpreter ();
+
+ if (interp != NULL)
+ return interp_data (interp);
+ return NULL;
+}
+
+/* Observers for several run control events that print why the
+ inferior has stopped to both the the MI event channel and to the MI
+ console. If the MI interpreter is not active, print nothing. */
+
+/* Observer for the signal_received notification. */
+
+static void
+mi_on_signal_received (enum gdb_signal siggnal)
+{
+ struct mi_interp *mi = mi_interp_data ();
+
+ if (mi == NULL)
+ return;
+
+ print_signal_received_reason (mi->mi_uiout, siggnal);
+ print_signal_received_reason (mi->cli_uiout, siggnal);
+}
+
+/* Observer for the end_stepping_range notification. */
+
+static void
+mi_on_end_stepping_range (void)
+{
+ struct mi_interp *mi = mi_interp_data ();
+
+ if (mi == NULL)
+ return;
+
+ print_end_stepping_range_reason (mi->mi_uiout);
+ print_end_stepping_range_reason (mi->cli_uiout);
+}
+
+/* Observer for the signal_exited notification. */
+
+static void
+mi_on_signal_exited (enum gdb_signal siggnal)
+{
+ struct mi_interp *mi = mi_interp_data ();
+
+ if (mi == NULL)
+ return;
+
+ print_signal_exited_reason (mi->mi_uiout, siggnal);
+ print_signal_exited_reason (mi->cli_uiout, siggnal);
+}
+
+/* Observer for the exited notification. */
+
+static void
+mi_on_exited (int exitstatus)
+{
+ struct mi_interp *mi = mi_interp_data ();
+
+ if (mi == NULL)
+ return;
+
+ print_exited_reason (mi->mi_uiout, exitstatus);
+ print_exited_reason (mi->cli_uiout, exitstatus);
+}
+
+/* Observer for the no_history notification. */
+
+static void
+mi_on_no_history (void)
+{
+ struct mi_interp *mi = mi_interp_data ();
+
+ if (mi == NULL)
+ return;
+
+ print_no_history_reason (mi->mi_uiout);
+ print_no_history_reason (mi->cli_uiout);
+}
+