ODR warning for "enum string_repr_result"
[binutils-gdb.git] / gdb / cli / cli-interp.c
1 /* CLI Definitions for GDB, the GNU debugger.
2
3 Copyright (C) 2002-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 "cli-interp.h"
22 #include "interps.h"
23 #include "event-top.h"
24 #include "ui-out.h"
25 #include "cli-out.h"
26 #include "top.h" /* for "execute_command" */
27 #include "infrun.h"
28 #include "observable.h"
29 #include "gdbthread.h"
30 #include "thread-fsm.h"
31 #include "inferior.h"
32
33 cli_interp_base::cli_interp_base (const char *name)
34 : interp (name)
35 {}
36
37 cli_interp_base::~cli_interp_base ()
38 {}
39
40 /* The console interpreter. */
41
42 class cli_interp final : public cli_interp_base
43 {
44 public:
45 explicit cli_interp (const char *name);
46 ~cli_interp ();
47
48 void init (bool top_level) override;
49 void resume () override;
50 void suspend () override;
51 gdb_exception exec (const char *command_str) override;
52 ui_out *interp_ui_out () override;
53
54 /* The ui_out for the console interpreter. */
55 cli_ui_out *cli_uiout;
56 };
57
58 cli_interp::cli_interp (const char *name)
59 : cli_interp_base (name)
60 {
61 /* Create a default uiout builder for the CLI. */
62 this->cli_uiout = cli_out_new (gdb_stdout);
63 }
64
65 cli_interp::~cli_interp ()
66 {
67 delete cli_uiout;
68 }
69
70 /* Suppress notification struct. */
71 struct cli_suppress_notification cli_suppress_notification;
72
73 /* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
74 and returns NULL otherwise. */
75
76 static struct cli_interp *
77 as_cli_interp (struct interp *interp)
78 {
79 return dynamic_cast<cli_interp *> (interp);
80 }
81
82 /* Longjmp-safe wrapper for "execute_command". */
83 static struct gdb_exception safe_execute_command (struct ui_out *uiout,
84 const char *command,
85 int from_tty);
86
87 /* See cli-interp.h.
88
89 Breakpoint hits should always be mirrored to a console. Deciding
90 what to mirror to a console wrt to breakpoints and random stops
91 gets messy real fast. E.g., say "s" trips on a breakpoint. We'd
92 clearly want to mirror the event to the console in this case. But
93 what about more complicated cases like "s&; thread n; s&", and one
94 of those steps spawning a new thread, and that thread hitting a
95 breakpoint? It's impossible in general to track whether the thread
96 had any relation to the commands that had been executed. So we
97 just simplify and always mirror breakpoints and random events to
98 all consoles.
99
100 OTOH, we should print the source line to the console when stepping
101 or other similar commands, iff the step was started by that console
102 (or in MI's case, by a console command), but not if it was started
103 with MI's -exec-step or similar. */
104
105 int
106 should_print_stop_to_console (struct interp *console_interp,
107 struct thread_info *tp)
108 {
109 if ((bpstat_what (tp->control.stop_bpstat).main_action
110 == BPSTAT_WHAT_STOP_NOISY)
111 || tp->thread_fsm () == nullptr
112 || tp->thread_fsm ()->command_interp == console_interp
113 || !tp->thread_fsm ()->finished_p ())
114 return 1;
115 return 0;
116 }
117
118 /* Observers for several run control events. If the interpreter is
119 quiet (i.e., another interpreter is being run with
120 interpreter-exec), print nothing. */
121
122 /* Observer for the normal_stop notification. */
123
124 static void
125 cli_on_normal_stop (struct bpstat *bs, int print_frame)
126 {
127 if (!print_frame)
128 return;
129
130 /* This event is suppressed. */
131 if (cli_suppress_notification.normal_stop)
132 return;
133
134 SWITCH_THRU_ALL_UIS ()
135 {
136 struct interp *interp = top_level_interpreter ();
137 struct cli_interp *cli = as_cli_interp (interp);
138 struct thread_info *thread;
139
140 if (cli == NULL)
141 continue;
142
143 thread = inferior_thread ();
144 if (should_print_stop_to_console (interp, thread))
145 print_stop_event (cli->cli_uiout);
146 }
147 }
148
149 /* Observer for the signal_received notification. */
150
151 static void
152 cli_on_signal_received (enum gdb_signal siggnal)
153 {
154 SWITCH_THRU_ALL_UIS ()
155 {
156 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
157
158 if (cli == NULL)
159 continue;
160
161 print_signal_received_reason (cli->cli_uiout, siggnal);
162 }
163 }
164
165 /* Observer for the end_stepping_range notification. */
166
167 static void
168 cli_on_end_stepping_range (void)
169 {
170 SWITCH_THRU_ALL_UIS ()
171 {
172 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
173
174 if (cli == NULL)
175 continue;
176
177 print_end_stepping_range_reason (cli->cli_uiout);
178 }
179 }
180
181 /* Observer for the signalled notification. */
182
183 static void
184 cli_on_signal_exited (enum gdb_signal siggnal)
185 {
186 SWITCH_THRU_ALL_UIS ()
187 {
188 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
189
190 if (cli == NULL)
191 continue;
192
193 print_signal_exited_reason (cli->cli_uiout, siggnal);
194 }
195 }
196
197 /* Observer for the exited notification. */
198
199 static void
200 cli_on_exited (int exitstatus)
201 {
202 SWITCH_THRU_ALL_UIS ()
203 {
204 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
205
206 if (cli == NULL)
207 continue;
208
209 print_exited_reason (cli->cli_uiout, exitstatus);
210 }
211 }
212
213 /* Observer for the no_history notification. */
214
215 static void
216 cli_on_no_history (void)
217 {
218 SWITCH_THRU_ALL_UIS ()
219 {
220 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
221
222 if (cli == NULL)
223 continue;
224
225 print_no_history_reason (cli->cli_uiout);
226 }
227 }
228
229 /* Observer for the sync_execution_done notification. */
230
231 static void
232 cli_on_sync_execution_done (void)
233 {
234 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
235
236 if (cli == NULL)
237 return;
238
239 display_gdb_prompt (NULL);
240 }
241
242 /* Observer for the command_error notification. */
243
244 static void
245 cli_on_command_error (void)
246 {
247 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
248
249 if (cli == NULL)
250 return;
251
252 display_gdb_prompt (NULL);
253 }
254
255 /* Observer for the user_selected_context_changed notification. */
256
257 static void
258 cli_on_user_selected_context_changed (user_selected_what selection)
259 {
260 /* This event is suppressed. */
261 if (cli_suppress_notification.user_selected_context)
262 return;
263
264 thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : NULL;
265
266 SWITCH_THRU_ALL_UIS ()
267 {
268 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
269
270 if (cli == NULL)
271 continue;
272
273 if (selection & USER_SELECTED_INFERIOR)
274 print_selected_inferior (cli->cli_uiout);
275
276 if (tp != NULL
277 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
278 print_selected_thread_frame (cli->cli_uiout, selection);
279 }
280 }
281
282 /* pre_command_loop implementation. */
283
284 void
285 cli_interp_base::pre_command_loop ()
286 {
287 display_gdb_prompt (0);
288 }
289
290 /* These implement the cli out interpreter: */
291
292 void
293 cli_interp::init (bool top_level)
294 {
295 }
296
297 void
298 cli_interp::resume ()
299 {
300 struct ui *ui = current_ui;
301 struct cli_interp *cli = this;
302 struct ui_file *stream;
303
304 /*sync_execution = 1; */
305
306 /* gdb_setup_readline will change gdb_stdout. If the CLI was
307 previously writing to gdb_stdout, then set it to the new
308 gdb_stdout afterwards. */
309
310 stream = cli->cli_uiout->set_stream (gdb_stdout);
311 if (stream != gdb_stdout)
312 {
313 cli->cli_uiout->set_stream (stream);
314 stream = NULL;
315 }
316
317 gdb_setup_readline (1);
318
319 ui->input_handler = command_line_handler;
320
321 if (stream != NULL)
322 cli->cli_uiout->set_stream (gdb_stdout);
323 }
324
325 void
326 cli_interp::suspend ()
327 {
328 gdb_disable_readline ();
329 }
330
331 gdb_exception
332 cli_interp::exec (const char *command_str)
333 {
334 struct cli_interp *cli = this;
335 struct ui_file *old_stream;
336 struct gdb_exception result;
337
338 /* gdb_stdout could change between the time cli_uiout was
339 initialized and now. Since we're probably using a different
340 interpreter which has a new ui_file for gdb_stdout, use that one
341 instead of the default.
342
343 It is important that it gets reset everytime, since the user
344 could set gdb to use a different interpreter. */
345 old_stream = cli->cli_uiout->set_stream (gdb_stdout);
346 result = safe_execute_command (cli->cli_uiout, command_str, 1);
347 cli->cli_uiout->set_stream (old_stream);
348 return result;
349 }
350
351 bool
352 cli_interp_base::supports_command_editing ()
353 {
354 return true;
355 }
356
357 static struct gdb_exception
358 safe_execute_command (struct ui_out *command_uiout, const char *command,
359 int from_tty)
360 {
361 struct gdb_exception e;
362
363 /* Save and override the global ``struct ui_out'' builder. */
364 scoped_restore saved_uiout = make_scoped_restore (&current_uiout,
365 command_uiout);
366
367 try
368 {
369 execute_command (command, from_tty);
370 }
371 catch (gdb_exception &exception)
372 {
373 e = std::move (exception);
374 }
375
376 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
377 caller should print the exception. */
378 exception_print (gdb_stderr, e);
379 return e;
380 }
381
382 ui_out *
383 cli_interp::interp_ui_out ()
384 {
385 struct cli_interp *cli = (struct cli_interp *) this;
386
387 return cli->cli_uiout;
388 }
389
390 /* These hold the pushed copies of the gdb output files.
391 If NULL then nothing has yet been pushed. */
392 struct saved_output_files
393 {
394 ui_file *out;
395 ui_file *err;
396 ui_file *log;
397 ui_file *targ;
398 ui_file *targerr;
399 ui_file_up file_to_delete;
400 ui_file_up log_to_delete;
401 };
402 static std::unique_ptr<saved_output_files> saved_output;
403
404 /* See cli-interp.h. */
405
406 void
407 cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect,
408 bool debug_redirect)
409 {
410 if (logfile != nullptr)
411 {
412 saved_output.reset (new saved_output_files);
413 saved_output->out = gdb_stdout;
414 saved_output->err = gdb_stderr;
415 saved_output->log = gdb_stdlog;
416 saved_output->targ = gdb_stdtarg;
417 saved_output->targerr = gdb_stdtargerr;
418
419 /* If something is not being redirected, then a tee containing both the
420 logfile and stdout. */
421 ui_file *logfile_p = logfile.get ();
422 ui_file *tee = nullptr;
423 if (!logging_redirect || !debug_redirect)
424 {
425 tee = new tee_file (gdb_stdout, std::move (logfile));
426 saved_output->file_to_delete.reset (tee);
427 }
428 else
429 saved_output->file_to_delete = std::move (logfile);
430
431 saved_output->log_to_delete.reset
432 (new timestamped_file (debug_redirect ? logfile_p : tee));
433
434 gdb_stdout = logging_redirect ? logfile_p : tee;
435 gdb_stdlog = saved_output->log_to_delete.get ();
436 gdb_stderr = logging_redirect ? logfile_p : tee;
437 gdb_stdtarg = logging_redirect ? logfile_p : tee;
438 gdb_stdtargerr = logging_redirect ? logfile_p : tee;
439 }
440 else
441 {
442 gdb_stdout = saved_output->out;
443 gdb_stderr = saved_output->err;
444 gdb_stdlog = saved_output->log;
445 gdb_stdtarg = saved_output->targ;
446 gdb_stdtargerr = saved_output->targerr;
447
448 saved_output.reset (nullptr);
449 }
450 }
451
452 /* Factory for CLI interpreters. */
453
454 static struct interp *
455 cli_interp_factory (const char *name)
456 {
457 return new cli_interp (name);
458 }
459
460 /* Standard gdb initialization hook. */
461
462 void _initialize_cli_interp ();
463 void
464 _initialize_cli_interp ()
465 {
466 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
467
468 /* If changing this, remember to update tui-interp.c as well. */
469 gdb::observers::normal_stop.attach (cli_on_normal_stop, "cli-interp");
470 gdb::observers::end_stepping_range.attach (cli_on_end_stepping_range,
471 "cli-interp");
472 gdb::observers::signal_received.attach (cli_on_signal_received, "cli-interp");
473 gdb::observers::signal_exited.attach (cli_on_signal_exited, "cli-interp");
474 gdb::observers::exited.attach (cli_on_exited, "cli-interp");
475 gdb::observers::no_history.attach (cli_on_no_history, "cli-interp");
476 gdb::observers::sync_execution_done.attach (cli_on_sync_execution_done,
477 "cli-interp");
478 gdb::observers::command_error.attach (cli_on_command_error, "cli-interp");
479 gdb::observers::user_selected_context_changed.attach
480 (cli_on_user_selected_context_changed, "cli-interp");
481 }