/* CLI Definitions for GDB, the GNU debugger.
- Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ Copyright (C) 2002-2020 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 "event-top.h"
#include "infrun.h"
-#include "observer.h"
+#include "observable.h"
#include "gdbthread.h"
#include "thread-fsm.h"
+#include "inferior.h"
cli_interp_base::cli_interp_base (const char *name)
: interp (name)
{
public:
explicit cli_interp (const char *name);
+ ~cli_interp ();
void init (bool top_level) override;
void resume () override;
this->cli_uiout = cli_out_new (gdb_stdout);
}
+cli_interp::~cli_interp ()
+{
+ delete cli_uiout;
+}
+
/* Suppress notification struct. */
struct cli_suppress_notification cli_suppress_notification =
{
static struct cli_interp *
as_cli_interp (struct interp *interp)
{
- if (strcmp (interp_name (interp), INTERP_CONSOLE) == 0)
- return (struct cli_interp *) interp;
- return NULL;
+ return dynamic_cast<cli_interp *> (interp);
}
/* Longjmp-safe wrapper for "execute_command". */
== BPSTAT_WHAT_STOP_NOISY)
|| tp->thread_fsm == NULL
|| tp->thread_fsm->command_interp == console_interp
- || !thread_fsm_finished_p (tp->thread_fsm))
+ || !tp->thread_fsm->finished_p ())
return 1;
return 0;
}
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);
+ thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : NULL;
SWITCH_THRU_ALL_UIS ()
{
safe_execute_command (struct ui_out *command_uiout, const char *command,
int from_tty)
{
- struct gdb_exception e = exception_none;
- struct ui_out *saved_uiout;
+ struct gdb_exception e;
/* Save and override the global ``struct ui_out'' builder. */
- saved_uiout = current_uiout;
- current_uiout = command_uiout;
+ scoped_restore saved_uiout = make_scoped_restore (¤t_uiout,
+ command_uiout);
- TRY
+ try
{
execute_command (command, from_tty);
}
- CATCH (exception, RETURN_MASK_ALL)
+ catch (gdb_exception &exception)
{
- e = exception;
+ e = std::move (exception);
}
- END_CATCH
-
- /* Restore the global builder. */
- current_uiout = saved_uiout;
/* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
caller should print the exception. */
ui_file *log;
ui_file *targ;
ui_file *targerr;
+ ui_file *file_to_delete;
};
static saved_output_files saved_output;
/* See cli-interp.h. */
void
-cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
+cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect,
+ bool debug_redirect)
{
- if (logfile != NULL)
+ if (logfile != nullptr)
{
saved_output.out = gdb_stdout;
saved_output.err = gdb_stderr;
saved_output.targ = gdb_stdtarg;
saved_output.targerr = gdb_stdtargerr;
- /* A raw pointer since ownership is transferred to
- gdb_stdout. */
- ui_file *output = make_logging_output (gdb_stdout,
- std::move (logfile),
- logging_redirect);
- gdb_stdout = output;
- gdb_stdlog = output;
- gdb_stderr = output;
- gdb_stdtarg = output;
- gdb_stdtargerr = output;
+ /* If something is being redirected, then grab logfile. */
+ ui_file *logfile_p = nullptr;
+ if (logging_redirect || debug_redirect)
+ {
+ logfile_p = logfile.get ();
+ saved_output.file_to_delete = logfile_p;
+ }
+
+ /* If something is not being redirected, then a tee containing both the
+ logfile and stdout. */
+ ui_file *tee = nullptr;
+ if (!logging_redirect || !debug_redirect)
+ {
+ tee = new tee_file (gdb_stdout, std::move (logfile));
+ saved_output.file_to_delete = tee;
+ }
+
+ gdb_stdout = logging_redirect ? logfile_p : tee;
+ gdb_stdlog = debug_redirect ? logfile_p : tee;
+ gdb_stderr = logging_redirect ? logfile_p : tee;
+ gdb_stdtarg = logging_redirect ? logfile_p : tee;
+ gdb_stdtargerr = logging_redirect ? logfile_p : tee;
}
else
{
- /* Only delete one of the files -- they are all set to the same
- value. */
- delete gdb_stdout;
+ /* Delete the correct file. If it's the tee then the logfile will also
+ be deleted. */
+ delete saved_output.file_to_delete;
gdb_stdout = saved_output.out;
gdb_stderr = saved_output.err;
gdb_stdtarg = saved_output.targ;
gdb_stdtargerr = saved_output.targerr;
- saved_output.out = NULL;
- saved_output.err = NULL;
- saved_output.log = NULL;
- saved_output.targ = NULL;
- saved_output.targerr = NULL;
+ saved_output.out = nullptr;
+ saved_output.err = nullptr;
+ saved_output.log = nullptr;
+ saved_output.targ = nullptr;
+ saved_output.targerr = nullptr;
+ saved_output.file_to_delete = nullptr;
}
}
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);
- observer_attach_user_selected_context_changed
+ gdb::observers::normal_stop.attach (cli_on_normal_stop);
+ gdb::observers::end_stepping_range.attach (cli_on_end_stepping_range);
+ gdb::observers::signal_received.attach (cli_on_signal_received);
+ gdb::observers::signal_exited.attach (cli_on_signal_exited);
+ gdb::observers::exited.attach (cli_on_exited);
+ gdb::observers::no_history.attach (cli_on_no_history);
+ gdb::observers::sync_execution_done.attach (cli_on_sync_execution_done);
+ gdb::observers::command_error.attach (cli_on_command_error);
+ gdb::observers::user_selected_context_changed.attach
(cli_on_user_selected_context_changed);
}