SCORE: Replace regset_alloc() invocation by a static regset structure.
[deliverable/binutils-gdb.git] / gdb / cli / cli-logging.c
CommitLineData
0fac0b41
DJ
1/* Command-line output logging for GDB, the GNU debugger.
2
ecd75fc8 3 Copyright (C) 2003-2014 Free Software Foundation, Inc.
0fac0b41
DJ
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
0fac0b41
DJ
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0fac0b41
DJ
19
20#include "defs.h"
21#include "gdbcmd.h"
22#include "ui-out.h"
37ce89eb 23#include "interps.h"
58b61394 24#include "gdb_assert.h"
0fac0b41 25
0e9f083f 26#include <string.h>
0fac0b41
DJ
27
28/* These hold the pushed copies of the gdb output files.
29 If NULL then nothing has yet been pushed. */
30struct saved_output_files
31{
32 struct ui_file *out;
33 struct ui_file *err;
34 struct ui_file *log;
35 struct ui_file *targ;
8d4d924b 36 struct ui_file *targerr;
0fac0b41
DJ
37};
38static struct saved_output_files saved_output;
39static char *saved_filename;
40
41static char *logging_filename;
920d2a44
AC
42static void
43show_logging_filename (struct ui_file *file, int from_tty,
44 struct cmd_list_element *c, const char *value)
45{
46 fprintf_filtered (file, _("The current logfile is \"%s\".\n"),
47 value);
48}
49
44be957e 50static int logging_overwrite;
58b61394
JK
51
52static void
53set_logging_overwrite (char *args, int from_tty, struct cmd_list_element *c)
54{
55 if (saved_filename)
56 warning (_("Currently logging to %s. Turn the logging off and on to "
57 "make the new setting effective."), saved_filename);
58}
59
920d2a44
AC
60static void
61show_logging_overwrite (struct ui_file *file, int from_tty,
62 struct cmd_list_element *c, const char *value)
63{
9a2b4c1b
MS
64 fprintf_filtered (file,
65 _("Whether logging overwrites or "
66 "appends to the log file is %s.\n"),
920d2a44
AC
67 value);
68}
69
58b61394 70/* Value as configured by the user. */
44be957e 71static int logging_redirect;
58b61394 72
ebcd3b23
MS
73/* The on-disk file in use if logging is currently active together
74 with redirection turned off (and therefore using tee_file_new).
75 For active logging with redirection the on-disk file is directly in
76 GDB_STDOUT and this variable is NULL. */
58b61394
JK
77static struct ui_file *logging_no_redirect_file;
78
79static void
80set_logging_redirect (char *args, int from_tty, struct cmd_list_element *c)
81{
e12fefc8 82 struct cleanup *cleanups;
58b61394 83 struct ui_file *output, *new_logging_no_redirect_file;
79a45e25 84 struct ui_out *uiout = current_uiout;
58b61394
JK
85
86 if (saved_filename == NULL
87 || (logging_redirect != 0 && logging_no_redirect_file == NULL)
88 || (logging_redirect == 0 && logging_no_redirect_file != NULL))
89 return;
90
e12fefc8
TT
91 cleanups = make_cleanup (null_cleanup, NULL);
92
58b61394
JK
93 if (logging_redirect != 0)
94 {
95 gdb_assert (logging_no_redirect_file != NULL);
96
ebcd3b23
MS
97 /* ui_out_redirect still has not been called for next
98 gdb_stdout. */
e12fefc8 99 make_cleanup_ui_file_delete (gdb_stdout);
58b61394
JK
100
101 output = logging_no_redirect_file;
102 new_logging_no_redirect_file = NULL;
103
104 if (from_tty)
105 fprintf_unfiltered (saved_output.out, "Redirecting output to %s.\n",
106 logging_filename);
107 }
108 else
109 {
110 gdb_assert (logging_no_redirect_file == NULL);
111 output = tee_file_new (saved_output.out, 0, gdb_stdout, 0);
112 if (output == NULL)
113 perror_with_name (_("set logging"));
114 new_logging_no_redirect_file = gdb_stdout;
115
116 if (from_tty)
117 fprintf_unfiltered (saved_output.out, "Copying output to %s.\n",
118 logging_filename);
119 }
120
37ce89eb
SS
121 /* Give the current interpreter a chance to do anything special that
122 it might need for logging, such as updating other channels. */
123 if (current_interp_set_logging (1, output, NULL) == 0)
124 {
125 gdb_stdout = output;
126 gdb_stdlog = output;
127 gdb_stderr = output;
128 gdb_stdtarg = output;
129 gdb_stdtargerr = output;
130 }
131
58b61394
JK
132 logging_no_redirect_file = new_logging_no_redirect_file;
133
ebcd3b23
MS
134 /* There is a former output pushed on the ui_out_redirect stack. We
135 want to replace it by OUTPUT so we must pop the former value
136 first. We should either do both the pop and push or to do
137 neither of it. At least do not try to push OUTPUT if the pop
138 already failed. */
14dba4b4
JK
139
140 if (ui_out_redirect (uiout, NULL) < 0
141 || ui_out_redirect (uiout, output) < 0)
58b61394
JK
142 warning (_("Current output protocol does not support redirection"));
143
e12fefc8 144 do_cleanups (cleanups);
58b61394
JK
145}
146
920d2a44
AC
147static void
148show_logging_redirect (struct ui_file *file, int from_tty,
149 struct cmd_list_element *c, const char *value)
150{
151 fprintf_filtered (file, _("The logging output mode is %s.\n"), value);
152}
0fac0b41
DJ
153
154/* If we've pushed output files, close them and pop them. */
155static void
83a8ccca 156pop_output_files (void)
0fac0b41 157{
58b61394
JK
158 if (logging_no_redirect_file)
159 {
160 ui_file_delete (logging_no_redirect_file);
161 logging_no_redirect_file = NULL;
162 }
37ce89eb
SS
163
164 if (current_interp_set_logging (0, NULL, NULL) == 0)
165 {
166 /* Only delete one of the files -- they are all set to the same
167 value. */
168 ui_file_delete (gdb_stdout);
169
170 gdb_stdout = saved_output.out;
171 gdb_stderr = saved_output.err;
172 gdb_stdlog = saved_output.log;
173 gdb_stdtarg = saved_output.targ;
174 gdb_stdtargerr = saved_output.targ;
175 }
176
0fac0b41
DJ
177 saved_output.out = NULL;
178 saved_output.err = NULL;
179 saved_output.log = NULL;
180 saved_output.targ = NULL;
8d4d924b 181 saved_output.targerr = NULL;
0fac0b41 182
79a45e25 183 ui_out_redirect (current_uiout, NULL);
0fac0b41
DJ
184}
185
186/* This is a helper for the `set logging' command. */
187static void
188handle_redirections (int from_tty)
189{
724b958c 190 struct cleanup *cleanups;
0fac0b41 191 struct ui_file *output;
37ce89eb 192 struct ui_file *no_redirect_file = NULL;
0fac0b41
DJ
193
194 if (saved_filename != NULL)
195 {
196 fprintf_unfiltered (gdb_stdout, "Already logging to %s.\n",
197 saved_filename);
198 return;
199 }
200
201 output = gdb_fopen (logging_filename, logging_overwrite ? "w" : "a");
202 if (output == NULL)
e2e0b3e5 203 perror_with_name (_("set logging"));
724b958c 204 cleanups = make_cleanup_ui_file_delete (output);
0fac0b41
DJ
205
206 /* Redirects everything to gdb_stdout while this is running. */
207 if (!logging_redirect)
208 {
37ce89eb 209 no_redirect_file = output;
58b61394
JK
210
211 output = tee_file_new (gdb_stdout, 0, no_redirect_file, 0);
0fac0b41 212 if (output == NULL)
e2e0b3e5 213 perror_with_name (_("set logging"));
58b61394 214 make_cleanup_ui_file_delete (output);
0fac0b41
DJ
215 if (from_tty)
216 fprintf_unfiltered (gdb_stdout, "Copying output to %s.\n",
217 logging_filename);
58b61394
JK
218 logging_no_redirect_file = no_redirect_file;
219 }
220 else
221 {
222 gdb_assert (logging_no_redirect_file == NULL);
223
224 if (from_tty)
225 fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n",
226 logging_filename);
0fac0b41 227 }
0fac0b41 228
724b958c
TT
229 discard_cleanups (cleanups);
230
0fac0b41
DJ
231 saved_filename = xstrdup (logging_filename);
232 saved_output.out = gdb_stdout;
233 saved_output.err = gdb_stderr;
234 saved_output.log = gdb_stdlog;
235 saved_output.targ = gdb_stdtarg;
8d4d924b 236 saved_output.targerr = gdb_stdtargerr;
0fac0b41 237
37ce89eb
SS
238 /* Let the interpreter do anything it needs. */
239 if (current_interp_set_logging (1, output, no_redirect_file) == 0)
240 {
241 gdb_stdout = output;
242 gdb_stdlog = output;
243 gdb_stderr = output;
244 gdb_stdtarg = output;
245 gdb_stdtargerr = output;
246 }
0fac0b41 247
37ce89eb
SS
248 /* Don't do the redirect for MI, it confuses MI's ui-out scheme. */
249 if (!ui_out_is_mi_like_p (current_uiout))
250 {
251 if (ui_out_redirect (current_uiout, output) < 0)
252 warning (_("Current output protocol does not support redirection"));
253 }
0fac0b41
DJ
254}
255
256static void
257set_logging_on (char *args, int from_tty)
258{
259 char *rest = args;
cdb27c12 260
0fac0b41
DJ
261 if (rest && *rest)
262 {
263 xfree (logging_filename);
264 logging_filename = xstrdup (rest);
265 }
266 handle_redirections (from_tty);
267}
268
269static void
270set_logging_off (char *args, int from_tty)
271{
272 if (saved_filename == NULL)
273 return;
274
275 pop_output_files ();
276 if (from_tty)
277 fprintf_unfiltered (gdb_stdout, "Done logging to %s.\n", saved_filename);
278 xfree (saved_filename);
279 saved_filename = NULL;
280}
281
282static void
283set_logging_command (char *args, int from_tty)
284{
9a2b4c1b
MS
285 printf_unfiltered (_("\"set logging\" lets you log output to a file.\n"
286 "Usage: set logging on [FILENAME]\n"
287 " set logging off\n"
288 " set logging file FILENAME\n"
289 " set logging overwrite [on|off]\n"
290 " set logging redirect [on|off]\n"));
0fac0b41
DJ
291}
292
2c0b251b 293static void
0fac0b41
DJ
294show_logging_command (char *args, int from_tty)
295{
296 if (saved_filename)
a3f17187 297 printf_unfiltered (_("Currently logging to \"%s\".\n"), saved_filename);
0fac0b41
DJ
298 if (saved_filename == NULL
299 || strcmp (logging_filename, saved_filename) != 0)
a3f17187 300 printf_unfiltered (_("Future logs will be written to %s.\n"),
0fac0b41
DJ
301 logging_filename);
302
303 if (logging_overwrite)
a3f17187 304 printf_unfiltered (_("Logs will overwrite the log file.\n"));
0fac0b41 305 else
a3f17187 306 printf_unfiltered (_("Logs will be appended to the log file.\n"));
0fac0b41 307
58b61394
JK
308 if (saved_filename)
309 {
310 if (logging_redirect)
311 printf_unfiltered (_("Output is being sent only to the log file.\n"));
312 else
313 printf_unfiltered (_("Output is being logged and displayed.\n"));
314 }
0fac0b41 315 else
58b61394
JK
316 {
317 if (logging_redirect)
318 printf_unfiltered (_("Output will be sent only to the log file.\n"));
319 else
320 printf_unfiltered (_("Output will be logged and displayed.\n"));
321 }
0fac0b41
DJ
322}
323
2c0b251b
PA
324/* Provide a prototype to silence -Wmissing-prototypes. */
325extern initialize_file_ftype _initialize_cli_logging;
326
0fac0b41
DJ
327void
328_initialize_cli_logging (void)
329{
330 static struct cmd_list_element *set_logging_cmdlist, *show_logging_cmdlist;
331
0fac0b41 332 add_prefix_cmd ("logging", class_support, set_logging_command,
1bedd215 333 _("Set logging options"), &set_logging_cmdlist,
0fac0b41
DJ
334 "set logging ", 0, &setlist);
335 add_prefix_cmd ("logging", class_support, show_logging_command,
1bedd215 336 _("Show logging options"), &show_logging_cmdlist,
0fac0b41 337 "show logging ", 0, &showlist);
7915a72c
AC
338 add_setshow_boolean_cmd ("overwrite", class_support, &logging_overwrite, _("\
339Set whether logging overwrites or appends to the log file."), _("\
340Show whether logging overwrites or appends to the log file."), _("\
341If set, logging overrides the log file."),
58b61394 342 set_logging_overwrite,
920d2a44 343 show_logging_overwrite,
2c5b56ce 344 &set_logging_cmdlist, &show_logging_cmdlist);
7915a72c
AC
345 add_setshow_boolean_cmd ("redirect", class_support, &logging_redirect, _("\
346Set the logging output mode."), _("\
347Show the logging output mode."), _("\
3b64bf98 348If redirect is off, output will go to both the screen and the log file.\n\
7915a72c 349If redirect is on, output will go only to the log file."),
58b61394 350 set_logging_redirect,
920d2a44 351 show_logging_redirect,
2c5b56ce 352 &set_logging_cmdlist, &show_logging_cmdlist);
7915a72c
AC
353 add_setshow_filename_cmd ("file", class_support, &logging_filename, _("\
354Set the current logfile."), _("\
355Show the current logfile."), _("\
356The logfile is used when directing GDB's output."),
2c5b56ce 357 NULL,
920d2a44 358 show_logging_filename,
b3f42336 359 &set_logging_cmdlist, &show_logging_cmdlist);
0fac0b41 360 add_cmd ("on", class_support, set_logging_on,
1a966eab 361 _("Enable logging."), &set_logging_cmdlist);
0fac0b41 362 add_cmd ("off", class_support, set_logging_off,
1a966eab 363 _("Disable logging."), &set_logging_cmdlist);
0fac0b41
DJ
364
365 logging_filename = xstrdup ("gdb.txt");
366}
This page took 0.705234 seconds and 4 git commands to generate.