Bump version to 12.0.50.DATE-git.
[binutils-gdb.git] / gdb / cli / cli-interp.c
blob31fe934bdfff6792b556e59938de5a076450f05d
1 /* CLI Definitions for GDB, the GNU debugger.
3 Copyright (C) 2002-2021 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
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"
33 cli_interp_base::cli_interp_base (const char *name)
34 : interp (name)
37 cli_interp_base::~cli_interp_base ()
40 /* The console interpreter. */
42 class cli_interp final : public cli_interp_base
44 public:
45 explicit cli_interp (const char *name);
46 ~cli_interp ();
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;
54 /* The ui_out for the console interpreter. */
55 cli_ui_out *cli_uiout;
58 cli_interp::cli_interp (const char *name)
59 : cli_interp_base (name)
61 /* Create a default uiout builder for the CLI. */
62 this->cli_uiout = cli_out_new (gdb_stdout);
65 cli_interp::~cli_interp ()
67 delete cli_uiout;
70 /* Suppress notification struct. */
71 struct cli_suppress_notification cli_suppress_notification =
73 0 /* user_selected_context_changed */
76 /* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
77 and returns NULL otherwise. */
79 static struct cli_interp *
80 as_cli_interp (struct interp *interp)
82 return dynamic_cast<cli_interp *> (interp);
85 /* Longjmp-safe wrapper for "execute_command". */
86 static struct gdb_exception safe_execute_command (struct ui_out *uiout,
87 const char *command,
88 int from_tty);
90 /* See cli-interp.h.
92 Breakpoint hits should always be mirrored to a console. Deciding
93 what to mirror to a console wrt to breakpoints and random stops
94 gets messy real fast. E.g., say "s" trips on a breakpoint. We'd
95 clearly want to mirror the event to the console in this case. But
96 what about more complicated cases like "s&; thread n; s&", and one
97 of those steps spawning a new thread, and that thread hitting a
98 breakpoint? It's impossible in general to track whether the thread
99 had any relation to the commands that had been executed. So we
100 just simplify and always mirror breakpoints and random events to
101 all consoles.
103 OTOH, we should print the source line to the console when stepping
104 or other similar commands, iff the step was started by that console
105 (or in MI's case, by a console command), but not if it was started
106 with MI's -exec-step or similar. */
109 should_print_stop_to_console (struct interp *console_interp,
110 struct thread_info *tp)
112 if ((bpstat_what (tp->control.stop_bpstat).main_action
113 == BPSTAT_WHAT_STOP_NOISY)
114 || tp->thread_fsm == NULL
115 || tp->thread_fsm->command_interp == console_interp
116 || !tp->thread_fsm->finished_p ())
117 return 1;
118 return 0;
121 /* Observers for several run control events. If the interpreter is
122 quiet (i.e., another interpreter is being run with
123 interpreter-exec), print nothing. */
125 /* Observer for the normal_stop notification. */
127 static void
128 cli_on_normal_stop (struct bpstats *bs, int print_frame)
130 if (!print_frame)
131 return;
133 SWITCH_THRU_ALL_UIS ()
135 struct interp *interp = top_level_interpreter ();
136 struct cli_interp *cli = as_cli_interp (interp);
137 struct thread_info *thread;
139 if (cli == NULL)
140 continue;
142 thread = inferior_thread ();
143 if (should_print_stop_to_console (interp, thread))
144 print_stop_event (cli->cli_uiout);
148 /* Observer for the signal_received notification. */
150 static void
151 cli_on_signal_received (enum gdb_signal siggnal)
153 SWITCH_THRU_ALL_UIS ()
155 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
157 if (cli == NULL)
158 continue;
160 print_signal_received_reason (cli->cli_uiout, siggnal);
164 /* Observer for the end_stepping_range notification. */
166 static void
167 cli_on_end_stepping_range (void)
169 SWITCH_THRU_ALL_UIS ()
171 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
173 if (cli == NULL)
174 continue;
176 print_end_stepping_range_reason (cli->cli_uiout);
180 /* Observer for the signalled notification. */
182 static void
183 cli_on_signal_exited (enum gdb_signal siggnal)
185 SWITCH_THRU_ALL_UIS ()
187 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
189 if (cli == NULL)
190 continue;
192 print_signal_exited_reason (cli->cli_uiout, siggnal);
196 /* Observer for the exited notification. */
198 static void
199 cli_on_exited (int exitstatus)
201 SWITCH_THRU_ALL_UIS ()
203 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
205 if (cli == NULL)
206 continue;
208 print_exited_reason (cli->cli_uiout, exitstatus);
212 /* Observer for the no_history notification. */
214 static void
215 cli_on_no_history (void)
217 SWITCH_THRU_ALL_UIS ()
219 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
221 if (cli == NULL)
222 continue;
224 print_no_history_reason (cli->cli_uiout);
228 /* Observer for the sync_execution_done notification. */
230 static void
231 cli_on_sync_execution_done (void)
233 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
235 if (cli == NULL)
236 return;
238 display_gdb_prompt (NULL);
241 /* Observer for the command_error notification. */
243 static void
244 cli_on_command_error (void)
246 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
248 if (cli == NULL)
249 return;
251 display_gdb_prompt (NULL);
254 /* Observer for the user_selected_context_changed notification. */
256 static void
257 cli_on_user_selected_context_changed (user_selected_what selection)
259 /* This event is suppressed. */
260 if (cli_suppress_notification.user_selected_context)
261 return;
263 thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : NULL;
265 SWITCH_THRU_ALL_UIS ()
267 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
269 if (cli == NULL)
270 continue;
272 if (selection & USER_SELECTED_INFERIOR)
273 print_selected_inferior (cli->cli_uiout);
275 if (tp != NULL
276 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
277 print_selected_thread_frame (cli->cli_uiout, selection);
281 /* pre_command_loop implementation. */
283 void
284 cli_interp_base::pre_command_loop ()
286 display_gdb_prompt (0);
289 /* These implement the cli out interpreter: */
291 void
292 cli_interp::init (bool top_level)
296 void
297 cli_interp::resume ()
299 struct ui *ui = current_ui;
300 struct cli_interp *cli = this;
301 struct ui_file *stream;
303 /*sync_execution = 1; */
305 /* gdb_setup_readline will change gdb_stdout. If the CLI was
306 previously writing to gdb_stdout, then set it to the new
307 gdb_stdout afterwards. */
309 stream = cli->cli_uiout->set_stream (gdb_stdout);
310 if (stream != gdb_stdout)
312 cli->cli_uiout->set_stream (stream);
313 stream = NULL;
316 gdb_setup_readline (1);
318 ui->input_handler = command_line_handler;
320 if (stream != NULL)
321 cli->cli_uiout->set_stream (gdb_stdout);
324 void
325 cli_interp::suspend ()
327 gdb_disable_readline ();
330 gdb_exception
331 cli_interp::exec (const char *command_str)
333 struct cli_interp *cli = this;
334 struct ui_file *old_stream;
335 struct gdb_exception result;
337 /* gdb_stdout could change between the time cli_uiout was
338 initialized and now. Since we're probably using a different
339 interpreter which has a new ui_file for gdb_stdout, use that one
340 instead of the default.
342 It is important that it gets reset everytime, since the user
343 could set gdb to use a different interpreter. */
344 old_stream = cli->cli_uiout->set_stream (gdb_stdout);
345 result = safe_execute_command (cli->cli_uiout, command_str, 1);
346 cli->cli_uiout->set_stream (old_stream);
347 return result;
350 bool
351 cli_interp_base::supports_command_editing ()
353 return true;
356 static struct gdb_exception
357 safe_execute_command (struct ui_out *command_uiout, const char *command,
358 int from_tty)
360 struct gdb_exception e;
362 /* Save and override the global ``struct ui_out'' builder. */
363 scoped_restore saved_uiout = make_scoped_restore (&current_uiout,
364 command_uiout);
368 execute_command (command, from_tty);
370 catch (gdb_exception &exception)
372 e = std::move (exception);
375 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
376 caller should print the exception. */
377 exception_print (gdb_stderr, e);
378 return e;
381 ui_out *
382 cli_interp::interp_ui_out ()
384 struct cli_interp *cli = (struct cli_interp *) this;
386 return cli->cli_uiout;
389 /* These hold the pushed copies of the gdb output files.
390 If NULL then nothing has yet been pushed. */
391 struct saved_output_files
393 ui_file *out;
394 ui_file *err;
395 ui_file *log;
396 ui_file *targ;
397 ui_file *targerr;
398 ui_file *file_to_delete;
400 static saved_output_files saved_output;
402 /* See cli-interp.h. */
404 void
405 cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect,
406 bool debug_redirect)
408 if (logfile != nullptr)
410 saved_output.out = gdb_stdout;
411 saved_output.err = gdb_stderr;
412 saved_output.log = gdb_stdlog;
413 saved_output.targ = gdb_stdtarg;
414 saved_output.targerr = gdb_stdtargerr;
416 /* If something is being redirected, then grab logfile. */
417 ui_file *logfile_p = nullptr;
418 if (logging_redirect || debug_redirect)
420 logfile_p = logfile.get ();
421 saved_output.file_to_delete = logfile_p;
424 /* If something is not being redirected, then a tee containing both the
425 logfile and stdout. */
426 ui_file *tee = nullptr;
427 if (!logging_redirect || !debug_redirect)
429 tee = new tee_file (gdb_stdout, std::move (logfile));
430 saved_output.file_to_delete = tee;
433 /* Make sure that the call to logfile's dtor does not delete the
434 underlying pointer if we still keep a reference to it. If
435 logfile_p is not referenced as the file_to_delete, then either
436 the logfile is not used (no redirection) and it should be
437 deleted, or a tee took ownership of the pointer. */
438 if (logfile_p != nullptr && saved_output.file_to_delete == logfile_p)
439 logfile.release ();
441 gdb_stdout = logging_redirect ? logfile_p : tee;
442 gdb_stdlog = debug_redirect ? logfile_p : tee;
443 gdb_stderr = logging_redirect ? logfile_p : tee;
444 gdb_stdtarg = logging_redirect ? logfile_p : tee;
445 gdb_stdtargerr = logging_redirect ? logfile_p : tee;
447 else
449 /* Delete the correct file. If it's the tee then the logfile will also
450 be deleted. */
451 delete saved_output.file_to_delete;
453 gdb_stdout = saved_output.out;
454 gdb_stderr = saved_output.err;
455 gdb_stdlog = saved_output.log;
456 gdb_stdtarg = saved_output.targ;
457 gdb_stdtargerr = saved_output.targerr;
459 saved_output.out = nullptr;
460 saved_output.err = nullptr;
461 saved_output.log = nullptr;
462 saved_output.targ = nullptr;
463 saved_output.targerr = nullptr;
464 saved_output.file_to_delete = nullptr;
468 /* Factory for CLI interpreters. */
470 static struct interp *
471 cli_interp_factory (const char *name)
473 return new cli_interp (name);
476 /* Standard gdb initialization hook. */
478 void _initialize_cli_interp ();
479 void
480 _initialize_cli_interp ()
482 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
484 /* If changing this, remember to update tui-interp.c as well. */
485 gdb::observers::normal_stop.attach (cli_on_normal_stop, "cli-interp");
486 gdb::observers::end_stepping_range.attach (cli_on_end_stepping_range,
487 "cli-interp");
488 gdb::observers::signal_received.attach (cli_on_signal_received, "cli-interp");
489 gdb::observers::signal_exited.attach (cli_on_signal_exited, "cli-interp");
490 gdb::observers::exited.attach (cli_on_exited, "cli-interp");
491 gdb::observers::no_history.attach (cli_on_no_history, "cli-interp");
492 gdb::observers::sync_execution_done.attach (cli_on_sync_execution_done,
493 "cli-interp");
494 gdb::observers::command_error.attach (cli_on_command_error, "cli-interp");
495 gdb::observers::user_selected_context_changed.attach
496 (cli_on_user_selected_context_changed, "cli-interp");