static void mi_solib_loaded (struct so_list *solib);
static void mi_solib_unloaded (struct so_list *solib);
static void mi_about_to_proceed (void);
+static void mi_traceframe_changed (int tfnum, int tpnum);
+static void mi_tsv_created (const char *name, LONGEST value);
+static void mi_tsv_deleted (const char *name);
static void mi_breakpoint_created (struct breakpoint *b);
static void mi_breakpoint_deleted (struct breakpoint *b);
static void mi_breakpoint_modified (struct breakpoint *b);
+static void mi_command_param_changed (const char *param, const char *value);
static int report_initial_inferior (struct inferior *inf, void *closure);
observer_attach_solib_loaded (mi_solib_loaded);
observer_attach_solib_unloaded (mi_solib_unloaded);
observer_attach_about_to_proceed (mi_about_to_proceed);
+ observer_attach_traceframe_changed (mi_traceframe_changed);
+ observer_attach_tsv_created (mi_tsv_created);
+ observer_attach_tsv_deleted (mi_tsv_deleted);
observer_attach_breakpoint_created (mi_breakpoint_created);
observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
observer_attach_breakpoint_modified (mi_breakpoint_modified);
+ observer_attach_command_param_changed (mi_command_param_changed);
/* The initial inferior is created before this function is
called, so we need to report it explicitly. Use iteration in
mi_proceeded = 1;
}
-/* When non-zero, no MI notifications will be emitted in
- response to breakpoint change observers. */
+/* When the element is non-zero, no MI notifications will be emitted in
+ response to the corresponding observers. */
-int mi_suppress_breakpoint_notifications = 0;
+struct mi_suppress_notification mi_suppress_notification =
+ {
+ 0,
+ 0,
+ 0,
+ };
+
+/* Emit notification on changing a traceframe. */
+
+static void
+mi_traceframe_changed (int tfnum, int tpnum)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+
+ if (mi_suppress_notification.traceframe)
+ return;
+
+ target_terminal_ours ();
+
+ 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);
+}
+
+/* Emit notification on creating a trace state variable. */
+
+static void
+mi_tsv_created (const char *name, LONGEST value)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+
+ target_terminal_ours ();
+
+ fprintf_unfiltered (mi->event_channel, "tsv-created,"
+ "name=\"%s\",value=\"%s\"\n",
+ name, plongest (value));
+
+ gdb_flush (mi->event_channel);
+}
+
+/* Emit notification on deleting a trace state variable. */
+
+static void
+mi_tsv_deleted (const char *name)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+
+ target_terminal_ours ();
+
+ if (name != NULL)
+ fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
+ "name=\"%s\"\n", name);
+ else
+ fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
+
+ gdb_flush (mi->event_channel);
+}
/* Emit notification about a created breakpoint. */
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
volatile struct gdb_exception e;
- if (mi_suppress_breakpoint_notifications)
+ if (mi_suppress_notification.breakpoint)
return;
if (b->number <= 0)
{
struct mi_interp *mi = top_level_interpreter_data ();
- if (mi_suppress_breakpoint_notifications)
+ if (mi_suppress_notification.breakpoint)
return;
if (b->number <= 0)
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
volatile struct gdb_exception e;
- if (mi_suppress_breakpoint_notifications)
+ if (mi_suppress_notification.breakpoint)
return;
if (b->number <= 0)
gdb_flush (mi->event_channel);
}
+/* Emit notification about the command parameter change. */
+
+static void
+mi_command_param_changed (const char *param, const char *value)
+{
+ struct mi_interp *mi = top_level_interpreter_data ();
+ struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
+
+ if (mi_suppress_notification.cmd_param_changed)
+ return;
+
+ target_terminal_ours ();
+
+ fprintf_unfiltered (mi->event_channel,
+ "cmd-param-changed");
+
+ ui_out_redirect (mi_uiout, mi->event_channel);
+
+ ui_out_field_string (mi_uiout, "param", param);
+ ui_out_field_string (mi_uiout, "value", value);
+
+ ui_out_redirect (mi_uiout, NULL);
+
+ gdb_flush (mi->event_channel);
+}
+
static int
report_initial_inferior (struct inferior *inf, void *closure)
{
return mi->uiout;
}
+/* Save the original value of raw_stdout here when logging, so we can
+ restore correctly when done. */
+
+static struct ui_file *saved_raw_stdout;
+
+/* Do MI-specific logging actions; save raw_stdout, and change all
+ the consoles to use the supplied ui-file(s). */
+
+static int
+mi_set_logging (struct interp *interp, int start_log,
+ struct ui_file *out, struct ui_file *logfile)
+{
+ struct mi_interp *mi = interp_data (interp);
+
+ if (!mi)
+ return 0;
+
+ if (start_log)
+ {
+ /* The tee created already is based on gdb_stdout, which for MI
+ is a console and so we end up in an infinite loop of console
+ writing to ui_file writing to console etc. So discard the
+ existing tee (it hasn't been used yet, and MI won't ever use
+ it), and create one based on raw_stdout instead. */
+ if (logfile)
+ {
+ ui_file_delete (out);
+ out = tee_file_new (raw_stdout, 0, logfile, 0);
+ }
+
+ saved_raw_stdout = raw_stdout;
+ raw_stdout = out;
+ }
+ else
+ {
+ raw_stdout = saved_raw_stdout;
+ saved_raw_stdout = NULL;
+ }
+
+ mi_console_set_raw (mi->out, raw_stdout);
+ mi_console_set_raw (mi->err, raw_stdout);
+ mi_console_set_raw (mi->log, raw_stdout);
+ mi_console_set_raw (mi->targ, raw_stdout);
+ mi_console_set_raw (mi->event_channel, raw_stdout);
+
+ return 1;
+}
+
extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
void
mi_interpreter_suspend, /* suspend_proc */
mi_interpreter_exec, /* exec_proc */
mi_interpreter_prompt_p, /* prompt_proc_p */
- mi_ui_out /* ui_out_proc */
+ mi_ui_out, /* ui_out_proc */
+ mi_set_logging /* set_logging_proc */
};
/* The various interpreter levels. */