summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-01-24 02:08:52 +0000
committerPedro Alves <palves@redhat.com>2017-01-25 19:41:36 +0000
commitdd57ff788d8abc0a58a4efdb19eca43b8b0ee6b1 (patch)
tree2ed657169881888d3dc677407d44904421c6538d
parent448e579f75fb8afcb8eed3c90670bf86e4231741 (diff)
downloadbinutils-gdb-users/palves/ui_file_v3.tar.gz
Move tee building down to set_loggingusers/palves/ui_file_v3
-rw-r--r--gdb/cli/cli-interp.c65
-rw-r--r--gdb/cli/cli-interp.h3
-rw-r--r--gdb/cli/cli-logging.c73
-rw-r--r--gdb/interps.c13
-rw-r--r--gdb/interps.h16
-rw-r--r--gdb/mi/mi-interp.c30
-rw-r--r--gdb/tui/tui-interp.c2
7 files changed, 107 insertions, 95 deletions
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index 8802a5ae27b..f962589d13f 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -373,6 +373,69 @@ cli_ui_out (struct interp *self)
return cli->cli_uiout;
}
+/* These hold the pushed copies of the gdb output files.
+ If NULL then nothing has yet been pushed. */
+struct saved_output_files
+{
+ struct ui_file *out;
+ struct ui_file *err;
+ struct ui_file *log;
+ struct ui_file *targ;
+ struct ui_file *targerr;
+};
+static struct saved_output_files saved_output;
+
+void
+cli_set_logging (struct interp *interp,
+ ui_file_up logfile, bool logging_redirect)
+{
+ if (logfile != NULL)
+ {
+ /* A raw pointer since ownership is transferred to
+ gdb_stdout. */
+ ui_file *output;
+
+ if (logging_redirect)
+ output = logfile.release ();
+ else
+ {
+ /* Note the tee takes ownership of the log file. */
+ output = new tee_file (gdb_stdout, false, logfile.get (), true);
+ logfile.release ();
+ }
+
+ saved_output.out = gdb_stdout;
+ saved_output.err = gdb_stderr;
+ saved_output.log = gdb_stdlog;
+ saved_output.targ = gdb_stdtarg;
+ saved_output.targerr = gdb_stdtargerr;
+
+ gdb_stdout = output;
+ gdb_stdlog = output;
+ gdb_stderr = output;
+ gdb_stdtarg = output;
+ gdb_stdtargerr = output;
+ }
+ else
+ {
+ /* Only delete one of the files -- they are all set to the same
+ value. */
+ delete gdb_stdout;
+
+ gdb_stdout = saved_output.out;
+ gdb_stderr = saved_output.err;
+ gdb_stdlog = saved_output.log;
+ 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;
+ }
+}
+
/* The CLI interpreter's vtable. */
static const struct interp_procs cli_interp_procs = {
@@ -381,7 +444,7 @@ static const struct interp_procs cli_interp_procs = {
cli_interpreter_suspend, /* suspend_proc */
cli_interpreter_exec, /* exec_proc */
cli_ui_out, /* ui_out_proc */
- NULL, /* set_logging_proc */
+ cli_set_logging, /* set_logging_proc */
cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
};
diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
index ef86372ae15..59915699f3a 100644
--- a/gdb/cli/cli-interp.h
+++ b/gdb/cli/cli-interp.h
@@ -20,6 +20,9 @@
struct interp;
+extern void cli_set_logging (struct interp *interp,
+ ui_file_up logfile, bool logging_redirect);
+
extern int cli_interpreter_supports_command_editing (struct interp *interp);
extern void cli_interpreter_pre_command_loop (struct interp *self);
diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index 033676e7cb8..3c7896ffc42 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -22,17 +22,6 @@
#include "ui-out.h"
#include "interps.h"
-/* These hold the pushed copies of the gdb output files.
- If NULL then nothing has yet been pushed. */
-struct saved_output_files
-{
- struct ui_file *out;
- struct ui_file *err;
- struct ui_file *log;
- struct ui_file *targ;
- struct ui_file *targerr;
-};
-static struct saved_output_files saved_output;
static char *saved_filename;
static char *logging_filename;
@@ -90,24 +79,7 @@ show_logging_redirect (struct ui_file *file, int from_tty,
static void
pop_output_files (void)
{
- if (current_interp_set_logging (0, NULL, NULL) == 0)
- {
- /* Only delete one of the files -- they are all set to the same
- value. */
- delete gdb_stdout;
-
- gdb_stdout = saved_output.out;
- gdb_stderr = saved_output.err;
- gdb_stdlog = saved_output.log;
- 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;
+ current_interp_set_logging (NULL, false);
/* Stay consistent with handle_redirections. */
if (!current_uiout->is_mi_like_p ())
@@ -118,9 +90,6 @@ pop_output_files (void)
static void
handle_redirections (int from_tty)
{
- ui_file_up output;
- ui_file_up no_redirect_file;
-
if (saved_filename != NULL)
{
fprintf_unfiltered (gdb_stdout, "Already logging to %s.\n",
@@ -133,45 +102,27 @@ handle_redirections (int from_tty)
perror_with_name (_("set logging"));
/* Redirects everything to gdb_stdout while this is running. */
- if (!logging_redirect)
+ if (from_tty)
{
- no_redirect_file = std::move (log);
- output.reset (new tee_file (gdb_stdout, 0, no_redirect_file.get (), 0));
-
- if (from_tty)
+ if (!logging_redirect)
fprintf_unfiltered (gdb_stdout, "Copying output to %s.\n",
logging_filename);
- }
- else
- {
- output = std::move (log);
-
- if (from_tty)
+ else
fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n",
logging_filename);
}
saved_filename = xstrdup (logging_filename);
- saved_output.out = gdb_stdout;
- saved_output.err = gdb_stderr;
- saved_output.log = gdb_stdlog;
- saved_output.targ = gdb_stdtarg;
- saved_output.targerr = gdb_stdtargerr;
/* Let the interpreter do anything it needs. */
- if (current_interp_set_logging (1, output.get (),
- no_redirect_file.get ()) == 0)
- {
- gdb_stdout = output.get ();
- gdb_stdlog = output.get ();
- gdb_stderr = output.get ();
- gdb_stdtarg = output.get ();
- gdb_stdtargerr = output.get ();
- }
-
- output.release ();
-
- /* Don't do the redirect for MI, it confuses MI's ui-out scheme. */
+ current_interp_set_logging (std::move (log), logging_redirect);
+
+ /* Redirect the current ui-out object's output to the log. Use
+ gdb_stdout, not log, since the interpreter may have created a tee
+ that wraps the log. Don't do the redirect for MI, it confuses
+ MI's ui-out scheme. Note that we may get here with MI as current
+ interpreter, but with the current ui_out as a CLI ui_out, with
+ '-interpreter-exec console "set logging on"'. */
if (!current_uiout->is_mi_like_p ())
current_uiout->redirect (gdb_stdout);
}
diff --git a/gdb/interps.c b/gdb/interps.c
index a2b7ffe9446..06e7ccfc8ab 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -346,18 +346,15 @@ interp_ui_out (struct interp *interp)
return interp->procs->ui_out_proc (interp);
}
-int
-current_interp_set_logging (int start_log, struct ui_file *out,
- struct ui_file *logfile)
+void
+current_interp_set_logging (ui_file_up logfile,
+ bool logging_redirect)
{
struct ui_interp_info *ui_interp = get_current_interp_info ();
struct interp *interp = ui_interp->current_interpreter;
- if (interp == NULL
- || interp->procs->set_logging_proc == NULL)
- return 0;
-
- return interp->procs->set_logging_proc (interp, start_log, out, logfile);
+ return interp->procs->set_logging_proc (interp, std::move (logfile),
+ logging_redirect);
}
/* Temporarily overrides the current interpreter. */
diff --git a/gdb/interps.h b/gdb/interps.h
index 5ec2b05d8b5..af8c27f0868 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -49,9 +49,9 @@ typedef struct gdb_exception (interp_exec_ftype) (void *data,
typedef void (interp_pre_command_loop_ftype) (struct interp *self);
typedef struct ui_out *(interp_ui_out_ftype) (struct interp *self);
-typedef int (interp_set_logging_ftype) (struct interp *self, int start_log,
- struct ui_file *out,
- struct ui_file *logfile);
+typedef void (interp_set_logging_ftype) (struct interp *self,
+ ui_file_up logfile,
+ bool logging_redirect);
typedef int (interp_supports_command_editing_ftype) (struct interp *self);
@@ -109,13 +109,13 @@ extern int current_interp_named_p (const char *name);
/* Call this function to give the current interpreter an opportunity
to do any special handling of streams when logging is enabled or
- disabled. START_LOG is 1 when logging is starting, 0 when it ends,
- and OUT is the stream for the log file; it will be NULL when
- logging is ending. LOGFILE is non-NULL if the output streams
+ disabled. START_LOG is true when logging is starting, false when
+ it ends. LOGFILE is the stream for the log file; it's NULL when
+ logging is ending. LOGGING_REDIRECT is false if the output streams
are to be tees, with the log file as one of the outputs. */
-extern int current_interp_set_logging (int start_log, struct ui_file *out,
- struct ui_file *logfile);
+extern void current_interp_set_logging (ui_file_up logfile,
+ bool logging_redirect);
/* Returns opaque data associated with the top-level interpreter. */
extern void *top_level_interpreter_data (void);
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index f167a535bca..c5be3c42987 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1373,26 +1373,25 @@ mi_ui_out (struct interp *interp)
/* 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)
+static void
+mi_set_logging (struct interp *interp,
+ ui_file_up logfile, bool logging_redirect)
{
struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
- if (!mi)
- return 0;
+ gdb_assert (mi != NULL);
- if (start_log)
+ if (logfile != NULL)
{
- /* 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 *out;
+
+ if (logging_redirect)
+ out = logfile.release ();
+ else
{
- delete out;
- out = new tee_file (mi->raw_stdout, false, logfile, false);
+ /* Note the tee takes ownership of the log file. */
+ out = new tee_file (mi->raw_stdout, false, logfile.get (), true);
+ logfile.release ();
}
mi->saved_raw_stdout = mi->raw_stdout;
@@ -1400,6 +1399,7 @@ mi_set_logging (struct interp *interp, int start_log,
}
else
{
+ delete mi->raw_stdout;
mi->raw_stdout = mi->saved_raw_stdout;
mi->saved_raw_stdout = NULL;
}
@@ -1409,8 +1409,6 @@ mi_set_logging (struct interp *interp, int start_log,
mi->log->set_raw (mi->raw_stdout);
mi->targ->set_raw (mi->raw_stdout);
mi->event_channel->set_raw (mi->raw_stdout);
-
- return 1;
}
/* The MI interpreter's vtable. */
diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c
index 7893904fcbc..e2c0605b506 100644
--- a/gdb/tui/tui-interp.c
+++ b/gdb/tui/tui-interp.c
@@ -302,7 +302,7 @@ static const struct interp_procs tui_interp_procs = {
tui_suspend,
tui_exec,
tui_ui_out,
- NULL,
+ cli_set_logging,
cli_interpreter_pre_command_loop,
cli_interpreter_supports_command_editing,
};