+/* When the element is non-zero, no MI notifications will be emitted in
+ response to the corresponding observers. */
+
+struct mi_suppress_notification mi_suppress_notification =
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ };
+
+/* Emit notification on changing a traceframe. */
+
+static void
+mi_traceframe_changed (int tfnum, int tpnum)
+{
+ if (mi_suppress_notification.traceframe)
+ return;
+
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+ struct cleanup *old_chain;
+
+ if (mi == NULL)
+ continue;
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
+ if (tfnum >= 0)
+ fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
+ "num=\"%d\",tracepoint=\"%d\"\n",
+ tfnum, tpnum);
+ else
+ fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
+
+ gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/* Emit notification on creating a trace state variable. */
+
+static void
+mi_tsv_created (const struct trace_state_variable *tsv)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+ struct cleanup *old_chain;
+
+ if (mi == NULL)
+ continue;
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
+ fprintf_unfiltered (mi->event_channel, "tsv-created,"
+ "name=\"%s\",initial=\"%s\"\n",
+ tsv->name, plongest (tsv->initial_value));
+
+ gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/* Emit notification on deleting a trace state variable. */
+
+static void
+mi_tsv_deleted (const struct trace_state_variable *tsv)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+ struct cleanup *old_chain;
+
+ if (mi == NULL)
+ continue;
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
+ if (tsv != NULL)
+ fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
+ "name=\"%s\"\n", tsv->name);
+ else
+ fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
+
+ gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/* Emit notification on modifying a trace state variable. */
+
+static void
+mi_tsv_modified (const struct trace_state_variable *tsv)
+{
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+ struct ui_out *mi_uiout;
+ struct cleanup *old_chain;
+
+ if (mi == NULL)
+ continue;
+
+ mi_uiout = interp_ui_out (top_level_interpreter ());
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
+ fprintf_unfiltered (mi->event_channel,
+ "tsv-modified");
+
+ mi_uiout->redirect (mi->event_channel);
+
+ mi_uiout->field_string ("name", tsv->name);
+ mi_uiout->field_string ("initial",
+ plongest (tsv->initial_value));
+ if (tsv->value_known)
+ mi_uiout->field_string ("current", plongest (tsv->value));
+
+ mi_uiout->redirect (NULL);
+
+ gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/* Emit notification about a created breakpoint. */
+
+static void
+mi_breakpoint_created (struct breakpoint *b)
+{
+ if (mi_suppress_notification.breakpoint)
+ return;
+
+ if (b->number <= 0)
+ return;
+
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+ struct ui_out *mi_uiout;
+ struct cleanup *old_chain;
+
+ if (mi == NULL)
+ continue;
+
+ mi_uiout = interp_ui_out (top_level_interpreter ());
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
+ fprintf_unfiltered (mi->event_channel,
+ "breakpoint-created");
+ /* We want the output from gdb_breakpoint_query to go to
+ mi->event_channel. One approach would be to just call
+ gdb_breakpoint_query, and then use mi_out_put to send the current
+ content of mi_outout into mi->event_channel. However, that will
+ break if anything is output to mi_uiout prior to calling the
+ breakpoint_created notifications. So, we use
+ ui_out_redirect. */
+ mi_uiout->redirect (mi->event_channel);
+ TRY
+ {
+ gdb_breakpoint_query (mi_uiout, b->number, NULL);
+ }
+ CATCH (e, RETURN_MASK_ERROR)
+ {
+ }
+ END_CATCH
+
+ mi_uiout->redirect (NULL);
+
+ gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/* Emit notification about deleted breakpoint. */
+
+static void
+mi_breakpoint_deleted (struct breakpoint *b)
+{
+ if (mi_suppress_notification.breakpoint)
+ return;
+
+ if (b->number <= 0)
+ return;
+
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+ struct cleanup *old_chain;
+
+ if (mi == NULL)
+ continue;
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+
+ fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
+ b->number);
+
+ gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
+ }
+}
+
+/* Emit notification about modified breakpoint. */
+
+static void
+mi_breakpoint_modified (struct breakpoint *b)
+{
+ if (mi_suppress_notification.breakpoint)
+ return;
+
+ if (b->number <= 0)
+ return;
+
+ SWITCH_THRU_ALL_UIS ()
+ {
+ struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
+ struct cleanup *old_chain;
+
+ if (mi == NULL)
+ continue;
+
+ old_chain = make_cleanup_restore_target_terminal ();
+ target_terminal_ours_for_output ();
+ fprintf_unfiltered (mi->event_channel,
+ "breakpoint-modified");
+ /* We want the output from gdb_breakpoint_query to go to
+ mi->event_channel. One approach would be to just call
+ gdb_breakpoint_query, and then use mi_out_put to send the current
+ content of mi_outout into mi->event_channel. However, that will
+ break if anything is output to mi_uiout prior to calling the
+ breakpoint_created notifications. So, we use
+ ui_out_redirect. */
+ mi->mi_uiout->redirect (mi->event_channel);
+ TRY
+ {
+ gdb_breakpoint_query (mi->mi_uiout, b->number, NULL);
+ }
+ CATCH (e, RETURN_MASK_ERROR)
+ {
+ }
+ END_CATCH
+
+ mi->mi_uiout->redirect (NULL);
+
+ gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
+ }
+}
+