xref: /openbsd-src/gnu/usr.bin/binutils/gdb/cli/cli-logging.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Command-line output logging for GDB, the GNU debugger.
2b725ae77Skettenis 
3*11efff7fSkettenis    Copyright 2003, 2004 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "gdbcmd.h"
24b725ae77Skettenis #include "ui-out.h"
25b725ae77Skettenis 
26b725ae77Skettenis #include "gdb_string.h"
27b725ae77Skettenis 
28b725ae77Skettenis /* These hold the pushed copies of the gdb output files.
29b725ae77Skettenis    If NULL then nothing has yet been pushed.  */
30b725ae77Skettenis struct saved_output_files
31b725ae77Skettenis {
32b725ae77Skettenis   struct ui_file *out;
33b725ae77Skettenis   struct ui_file *err;
34b725ae77Skettenis   struct ui_file *log;
35b725ae77Skettenis   struct ui_file *targ;
36b725ae77Skettenis };
37b725ae77Skettenis static struct saved_output_files saved_output;
38b725ae77Skettenis static char *saved_filename;
39b725ae77Skettenis 
40b725ae77Skettenis static char *logging_filename;
41b725ae77Skettenis int logging_overwrite, logging_redirect;
42b725ae77Skettenis 
43b725ae77Skettenis /* If we've pushed output files, close them and pop them.  */
44b725ae77Skettenis static void
pop_output_files(void)45b725ae77Skettenis pop_output_files (void)
46b725ae77Skettenis {
47b725ae77Skettenis   /* Only delete one of the files -- they are all set to the same
48b725ae77Skettenis      value.  */
49b725ae77Skettenis   ui_file_delete (gdb_stdout);
50b725ae77Skettenis   gdb_stdout = saved_output.out;
51b725ae77Skettenis   gdb_stderr = saved_output.err;
52b725ae77Skettenis   gdb_stdlog = saved_output.log;
53b725ae77Skettenis   gdb_stdtarg = saved_output.targ;
54b725ae77Skettenis   saved_output.out = NULL;
55b725ae77Skettenis   saved_output.err = NULL;
56b725ae77Skettenis   saved_output.log = NULL;
57b725ae77Skettenis   saved_output.targ = NULL;
58b725ae77Skettenis 
59b725ae77Skettenis   ui_out_redirect (uiout, NULL);
60b725ae77Skettenis }
61b725ae77Skettenis 
62b725ae77Skettenis /* This is a helper for the `set logging' command.  */
63b725ae77Skettenis static void
handle_redirections(int from_tty)64b725ae77Skettenis handle_redirections (int from_tty)
65b725ae77Skettenis {
66b725ae77Skettenis   struct ui_file *output;
67b725ae77Skettenis 
68b725ae77Skettenis   if (saved_filename != NULL)
69b725ae77Skettenis     {
70b725ae77Skettenis       fprintf_unfiltered (gdb_stdout, "Already logging to %s.\n",
71b725ae77Skettenis 			  saved_filename);
72b725ae77Skettenis       return;
73b725ae77Skettenis     }
74b725ae77Skettenis 
75b725ae77Skettenis   output = gdb_fopen (logging_filename, logging_overwrite ? "w" : "a");
76b725ae77Skettenis   if (output == NULL)
77b725ae77Skettenis     perror_with_name ("set logging");
78b725ae77Skettenis 
79b725ae77Skettenis   /* Redirects everything to gdb_stdout while this is running.  */
80b725ae77Skettenis   if (!logging_redirect)
81b725ae77Skettenis     {
82b725ae77Skettenis       output = tee_file_new (gdb_stdout, 0, output, 1);
83b725ae77Skettenis       if (output == NULL)
84b725ae77Skettenis 	perror_with_name ("set logging");
85b725ae77Skettenis       if (from_tty)
86b725ae77Skettenis 	fprintf_unfiltered (gdb_stdout, "Copying output to %s.\n",
87b725ae77Skettenis 			    logging_filename);
88b725ae77Skettenis     }
89b725ae77Skettenis   else if (from_tty)
90b725ae77Skettenis     fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n",
91b725ae77Skettenis 			logging_filename);
92b725ae77Skettenis 
93b725ae77Skettenis   saved_filename = xstrdup (logging_filename);
94b725ae77Skettenis   saved_output.out = gdb_stdout;
95b725ae77Skettenis   saved_output.err = gdb_stderr;
96b725ae77Skettenis   saved_output.log = gdb_stdlog;
97b725ae77Skettenis   saved_output.targ = gdb_stdtarg;
98b725ae77Skettenis 
99b725ae77Skettenis   gdb_stdout = output;
100b725ae77Skettenis   gdb_stderr = output;
101b725ae77Skettenis   gdb_stdlog = output;
102b725ae77Skettenis   gdb_stdtarg = output;
103b725ae77Skettenis 
104b725ae77Skettenis   if (ui_out_redirect (uiout, gdb_stdout) < 0)
105b725ae77Skettenis     warning ("Current output protocol does not support redirection");
106b725ae77Skettenis }
107b725ae77Skettenis 
108b725ae77Skettenis static void
set_logging_on(char * args,int from_tty)109b725ae77Skettenis set_logging_on (char *args, int from_tty)
110b725ae77Skettenis {
111b725ae77Skettenis   char *rest = args;
112b725ae77Skettenis   if (rest && *rest)
113b725ae77Skettenis     {
114b725ae77Skettenis       xfree (logging_filename);
115b725ae77Skettenis       logging_filename = xstrdup (rest);
116b725ae77Skettenis     }
117b725ae77Skettenis   handle_redirections (from_tty);
118b725ae77Skettenis }
119b725ae77Skettenis 
120b725ae77Skettenis static void
set_logging_off(char * args,int from_tty)121b725ae77Skettenis set_logging_off (char *args, int from_tty)
122b725ae77Skettenis {
123b725ae77Skettenis   if (saved_filename == NULL)
124b725ae77Skettenis     return;
125b725ae77Skettenis 
126b725ae77Skettenis   pop_output_files ();
127b725ae77Skettenis   if (from_tty)
128b725ae77Skettenis     fprintf_unfiltered (gdb_stdout, "Done logging to %s.\n", saved_filename);
129b725ae77Skettenis   xfree (saved_filename);
130b725ae77Skettenis   saved_filename = NULL;
131b725ae77Skettenis }
132b725ae77Skettenis 
133b725ae77Skettenis static void
set_logging_command(char * args,int from_tty)134b725ae77Skettenis set_logging_command (char *args, int from_tty)
135b725ae77Skettenis {
136b725ae77Skettenis   printf_unfiltered ("\"set logging\" lets you log output to a file.\n");
137b725ae77Skettenis   printf_unfiltered ("Usage: set logging on [FILENAME]\n");
138b725ae77Skettenis   printf_unfiltered ("       set logging off\n");
139b725ae77Skettenis   printf_unfiltered ("       set logging file FILENAME\n");
140b725ae77Skettenis   printf_unfiltered ("       set logging overwrite [on|off]\n");
141b725ae77Skettenis   printf_unfiltered ("       set logging redirect [on|off]\n");
142b725ae77Skettenis }
143b725ae77Skettenis 
144b725ae77Skettenis void
show_logging_command(char * args,int from_tty)145b725ae77Skettenis show_logging_command (char *args, int from_tty)
146b725ae77Skettenis {
147b725ae77Skettenis   if (saved_filename)
148b725ae77Skettenis     printf_unfiltered ("Currently logging to \"%s\".\n", saved_filename);
149b725ae77Skettenis   if (saved_filename == NULL
150b725ae77Skettenis       || strcmp (logging_filename, saved_filename) != 0)
151b725ae77Skettenis     printf_unfiltered ("Future logs will be written to %s.\n",
152b725ae77Skettenis 		       logging_filename);
153b725ae77Skettenis 
154b725ae77Skettenis   if (logging_overwrite)
155b725ae77Skettenis     printf_unfiltered ("Logs will overwrite the log file.\n");
156b725ae77Skettenis   else
157b725ae77Skettenis     printf_unfiltered ("Logs will be appended to the log file.\n");
158b725ae77Skettenis 
159b725ae77Skettenis   if (logging_redirect)
160b725ae77Skettenis     printf_unfiltered ("Output will be sent only to the log file.\n");
161b725ae77Skettenis   else
162b725ae77Skettenis     printf_unfiltered ("Output will be logged and displayed.\n");
163b725ae77Skettenis }
164b725ae77Skettenis 
165b725ae77Skettenis void
_initialize_cli_logging(void)166b725ae77Skettenis _initialize_cli_logging (void)
167b725ae77Skettenis {
168b725ae77Skettenis   static struct cmd_list_element *set_logging_cmdlist, *show_logging_cmdlist;
169b725ae77Skettenis 
170b725ae77Skettenis 
171b725ae77Skettenis   add_prefix_cmd ("logging", class_support, set_logging_command,
172b725ae77Skettenis 		  "Set logging options", &set_logging_cmdlist,
173b725ae77Skettenis 		  "set logging ", 0, &setlist);
174b725ae77Skettenis   add_prefix_cmd ("logging", class_support, show_logging_command,
175b725ae77Skettenis 		  "Show logging options", &show_logging_cmdlist,
176b725ae77Skettenis 		  "show logging ", 0, &showlist);
177*11efff7fSkettenis   add_setshow_boolean_cmd ("overwrite", class_support, &logging_overwrite, "\
178*11efff7fSkettenis Set whether logging overwrites or appends to the log file.", "\
179*11efff7fSkettenis Show whether logging overwrites or appends to the log file.", "\
180*11efff7fSkettenis If set, logging overrides the log file.", "\
181*11efff7fSkettenis Whether logging overwrites or appends to the log file is %s.",
182b725ae77Skettenis 			   NULL, NULL, &set_logging_cmdlist, &show_logging_cmdlist);
183*11efff7fSkettenis   add_setshow_boolean_cmd ("redirect", class_support, &logging_redirect, "\
184*11efff7fSkettenis Set the logging output mode.", "\
185*11efff7fSkettenis Show the logging output mode.", "\
186*11efff7fSkettenis If redirect is off, output will go to both the screen and the log file.\n\
187*11efff7fSkettenis If redirect is on, output will go only to the log file.", "\
188*11efff7fSkettenis The logging output mode is %s.",
189b725ae77Skettenis 			   NULL, NULL, &set_logging_cmdlist, &show_logging_cmdlist);
190*11efff7fSkettenis   add_setshow_filename_cmd ("file", class_support, &logging_filename, "\
191*11efff7fSkettenis Set the current logfile.", "\
192*11efff7fSkettenis Show the current logfile.", "\
193*11efff7fSkettenis The logfile is used when directing GDB's output.", "\
194*11efff7fSkettenis The current logfile is %s.",
195*11efff7fSkettenis 			    NULL, NULL,
196*11efff7fSkettenis 			    &set_logging_cmdlist, &show_logging_cmdlist);
197b725ae77Skettenis   add_cmd ("on", class_support, set_logging_on,
198b725ae77Skettenis 	   "Enable logging.", &set_logging_cmdlist);
199b725ae77Skettenis   add_cmd ("off", class_support, set_logging_off,
200b725ae77Skettenis 	   "Disable logging.", &set_logging_cmdlist);
201b725ae77Skettenis 
202b725ae77Skettenis   logging_filename = xstrdup ("gdb.txt");
203b725ae77Skettenis }
204