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