]> Git Repo - binutils.git/blob - gdb/cli/cli-logging.c
gdb: remove SYMBOL_CLASS macro, add getter
[binutils.git] / gdb / cli / cli-logging.c
1 /* Command-line output logging for GDB, the GNU debugger.
2
3    Copyright (C) 2003-2022 Free Software Foundation, Inc.
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
9    the Free Software Foundation; either version 3 of the License, or
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
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "gdbcmd.h"
22 #include "ui-out.h"
23 #include "interps.h"
24 #include "cli/cli-style.h"
25 #include "cli/cli-decode.h"
26
27 static std::string saved_filename;
28
29 static std::string logging_filename = "gdb.txt";
30 static void
31 show_logging_filename (struct ui_file *file, int from_tty,
32                        struct cmd_list_element *c, const char *value)
33 {
34   fprintf_filtered (file, _("The current logfile is \"%ps\".\n"),
35                     styled_string (file_name_style.style (), value));
36 }
37
38 static bool logging_overwrite;
39
40 static void
41 maybe_warn_already_logging ()
42 {
43   if (!saved_filename.empty ())
44     warning (_("Currently logging to %s.  Turn the logging off and on to "
45                "make the new setting effective."), saved_filename.c_str ());
46 }
47
48 static void
49 set_logging_overwrite (const char *args,
50                        int from_tty, struct cmd_list_element *c)
51 {
52   maybe_warn_already_logging ();
53 }
54
55 static void
56 show_logging_overwrite (struct ui_file *file, int from_tty,
57                         struct cmd_list_element *c, const char *value)
58 {
59   if (logging_overwrite)
60     fprintf_filtered (file, _("on: Logging overwrites the log file.\n"));
61   else
62     fprintf_filtered (file, _("off: Logging appends to the log file.\n"));
63 }
64
65 /* Value as configured by the user.  */
66 static bool logging_redirect;
67 static bool debug_redirect;
68
69 static void
70 set_logging_redirect (const char *args,
71                       int from_tty, struct cmd_list_element *c)
72 {
73   maybe_warn_already_logging ();
74 }
75
76 static void
77 show_logging_redirect (struct ui_file *file, int from_tty,
78                        struct cmd_list_element *c, const char *value)
79 {
80   if (logging_redirect)
81     fprintf_filtered(file, _("on: Output will go only to the log file.\n"));
82   else
83     fprintf_filtered
84       (file,
85        _("off: Output will go to both the screen and the log file.\n"));
86 }
87
88 static void
89 show_logging_debug_redirect (struct ui_file *file, int from_tty,
90                        struct cmd_list_element *c, const char *value)
91 {
92   if (debug_redirect)
93     fprintf_filtered(file,
94                      _("on: Debug output will go only to the log file.\n"));
95   else
96     fprintf_filtered
97       (file,
98        _("off: Debug output will go to both the screen and the log file.\n"));
99 }
100
101 /* If we've pushed output files, close them and pop them.  */
102 static void
103 pop_output_files (void)
104 {
105   current_interp_set_logging (NULL, false, false);
106
107   /* Stay consistent with handle_redirections.  */
108   if (!current_uiout->is_mi_like_p ())
109     current_uiout->redirect (NULL);
110 }
111
112 /* This is a helper for the `set logging' command.  */
113 static void
114 handle_redirections (int from_tty)
115 {
116   if (!saved_filename.empty ())
117     {
118       printf_filtered ("Already logging to %s.\n",
119                        saved_filename.c_str ());
120       return;
121     }
122
123   stdio_file_up log (new no_terminal_escape_file ());
124   if (!log->open (logging_filename.c_str (), logging_overwrite ? "w" : "a"))
125     perror_with_name (_("set logging"));
126
127   /* Redirects everything to gdb_stdout while this is running.  */
128   if (from_tty)
129     {
130       if (!logging_redirect)
131         printf_filtered ("Copying output to %s.\n",
132                          logging_filename.c_str ());
133       else
134         printf_filtered ("Redirecting output to %s.\n",
135                          logging_filename.c_str ());
136
137       if (!debug_redirect)
138         printf_filtered ("Copying debug output to %s.\n",
139                          logging_filename.c_str ());
140       else
141         printf_filtered ("Redirecting debug output to %s.\n",
142                          logging_filename.c_str ());
143     }
144
145   saved_filename = logging_filename;
146
147   /* Let the interpreter do anything it needs.  */
148   current_interp_set_logging (std::move (log), logging_redirect,
149                               debug_redirect);
150
151   /* Redirect the current ui-out object's output to the log.  Use
152      gdb_stdout, not log, since the interpreter may have created a tee
153      that wraps the log.  Don't do the redirect for MI, it confuses
154      MI's ui-out scheme.  Note that we may get here with MI as current
155      interpreter, but with the current ui_out as a CLI ui_out, with
156      '-interpreter-exec console "set logging on"'.  */
157   if (!current_uiout->is_mi_like_p ())
158     current_uiout->redirect (gdb_stdout);
159 }
160
161 static void
162 set_logging_on (const char *args, int from_tty)
163 {
164   const char *rest = args;
165
166   if (rest && *rest)
167     logging_filename = rest;
168
169   handle_redirections (from_tty);
170 }
171
172 static void 
173 set_logging_off (const char *args, int from_tty)
174 {
175   if (saved_filename.empty ())
176     return;
177
178   pop_output_files ();
179   if (from_tty)
180     printf_filtered ("Done logging to %s.\n",
181                      saved_filename.c_str ());
182   saved_filename.clear ();
183 }
184
185 static bool logging_enabled;
186
187 static void
188 set_logging_enabled (const char *args,
189                      int from_tty, struct cmd_list_element *c)
190 {
191   if (logging_enabled)
192     set_logging_on (args, from_tty);
193   else
194     set_logging_off (args, from_tty);
195 }
196
197 static void
198 show_logging_enabled (struct ui_file *file, int from_tty,
199                        struct cmd_list_element *c, const char *value)
200 {
201   if (logging_enabled)
202     fprintf_unfiltered (file, _("on: Logging is enabled.\n"));
203   else
204     fprintf_unfiltered (file, _("off: Logging is disabled.\n"));
205 }
206
207 void _initialize_cli_logging ();
208 void
209 _initialize_cli_logging ()
210 {
211   static struct cmd_list_element *set_logging_cmdlist, *show_logging_cmdlist;
212
213   /* Set/show logging.  */
214   add_setshow_prefix_cmd ("logging", class_support,
215                           _("Set logging options."),
216                           _("Show logging options."),
217                           &set_logging_cmdlist, &show_logging_cmdlist,
218                           &setlist, &showlist);
219
220   /* Set/show logging overwrite.  */
221   add_setshow_boolean_cmd ("overwrite", class_support, &logging_overwrite, _("\
222 Set whether logging overwrites or appends to the log file."), _("\
223 Show whether logging overwrites or appends to the log file."), _("\
224 If set, logging overwrites the log file."),
225                            set_logging_overwrite,
226                            show_logging_overwrite,
227                            &set_logging_cmdlist, &show_logging_cmdlist);
228
229   /* Set/show logging redirect.  */
230   add_setshow_boolean_cmd ("redirect", class_support, &logging_redirect, _("\
231 Set the logging output mode."), _("\
232 Show the logging output mode."), _("\
233 If redirect is off, output will go to both the screen and the log file.\n\
234 If redirect is on, output will go only to the log file."),
235                            set_logging_redirect,
236                            show_logging_redirect,
237                            &set_logging_cmdlist, &show_logging_cmdlist);
238
239   /* Set/show logging debugredirect.  */
240   add_setshow_boolean_cmd ("debugredirect", class_support,
241                            &debug_redirect, _("\
242 Set the logging debug output mode."), _("\
243 Show the logging debug output mode."), _("\
244 If debug redirect is off, debug will go to both the screen and the log file.\n\
245 If debug redirect is on, debug will go only to the log file."),
246                            set_logging_redirect,
247                            show_logging_debug_redirect,
248                            &set_logging_cmdlist, &show_logging_cmdlist);
249
250   /* Set/show logging file.  */
251   add_setshow_filename_cmd ("file", class_support, &logging_filename, _("\
252 Set the current logfile."), _("\
253 Show the current logfile."), _("\
254 The logfile is used when directing GDB's output."),
255                             NULL,
256                             show_logging_filename,
257                             &set_logging_cmdlist, &show_logging_cmdlist);
258
259   /* Set/show logging enabled.  */
260   set_show_commands setshow_logging_enabled_cmds
261     = add_setshow_boolean_cmd ("enabled", class_support, &logging_enabled,
262                                _("Enable logging."),
263                                _("Show whether logging is enabled."),
264                                _("When on, enable logging."),
265                                set_logging_enabled,
266                                show_logging_enabled,
267                                &set_logging_cmdlist, &show_logging_cmdlist);
268
269   /* Set logging on, deprecated alias.  */
270   cmd_list_element *set_logging_on_cmd
271     = add_alias_cmd ("on", setshow_logging_enabled_cmds.set, class_support,
272                      false, &set_logging_cmdlist);
273   deprecate_cmd (set_logging_on_cmd, "set logging enabled on");
274   set_logging_on_cmd->default_args = "on";
275
276   /* Set logging off, deprecated alias.  */
277   cmd_list_element *set_logging_off_cmd
278     = add_alias_cmd ("off", setshow_logging_enabled_cmds.set, class_support,
279                      false, &set_logging_cmdlist);
280   deprecate_cmd (set_logging_off_cmd, "set logging enabled off");
281   set_logging_off_cmd->default_args = "off";
282 }
This page took 0.041124 seconds and 4 git commands to generate.