1 /* CLI Definitions for GDB, the GNU debugger.
3 Copyright (C) 2002-2017 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/>. */
21 #include "cli-interp.h"
23 #include "event-top.h"
26 #include "top.h" /* for "execute_command" */
27 #include "event-top.h"
30 #include "gdbthread.h"
31 #include "thread-fsm.h"
33 /* The console interpreter. */
36 /* The ui_out for the console interpreter. */
37 cli_ui_out *cli_uiout;
40 /* Suppress notification struct. */
41 struct cli_suppress_notification cli_suppress_notification =
43 0 /* user_selected_context_changed */
46 /* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
47 and returns NULL otherwise. */
49 static struct cli_interp *
50 as_cli_interp (struct interp *interp)
52 if (strcmp (interp_name (interp), INTERP_CONSOLE) == 0)
53 return (struct cli_interp *) interp_data (interp);
57 /* Longjmp-safe wrapper for "execute_command". */
58 static struct gdb_exception safe_execute_command (struct ui_out *uiout,
64 Breakpoint hits should always be mirrored to a console. Deciding
65 what to mirror to a console wrt to breakpoints and random stops
66 gets messy real fast. E.g., say "s" trips on a breakpoint. We'd
67 clearly want to mirror the event to the console in this case. But
68 what about more complicated cases like "s&; thread n; s&", and one
69 of those steps spawning a new thread, and that thread hitting a
70 breakpoint? It's impossible in general to track whether the thread
71 had any relation to the commands that had been executed. So we
72 just simplify and always mirror breakpoints and random events to
75 OTOH, we should print the source line to the console when stepping
76 or other similar commands, iff the step was started by that console
77 (or in MI's case, by a console command), but not if it was started
78 with MI's -exec-step or similar. */
81 should_print_stop_to_console (struct interp *console_interp,
82 struct thread_info *tp)
84 if ((bpstat_what (tp->control.stop_bpstat).main_action
85 == BPSTAT_WHAT_STOP_NOISY)
86 || tp->thread_fsm == NULL
87 || tp->thread_fsm->command_interp == console_interp
88 || !thread_fsm_finished_p (tp->thread_fsm))
93 /* Observers for several run control events. If the interpreter is
94 quiet (i.e., another interpreter is being run with
95 interpreter-exec), print nothing. */
97 /* Observer for the normal_stop notification. */
100 cli_on_normal_stop (struct bpstats *bs, int print_frame)
105 SWITCH_THRU_ALL_UIS ()
107 struct interp *interp = top_level_interpreter ();
108 struct cli_interp *cli = as_cli_interp (interp);
109 struct thread_info *thread;
114 thread = inferior_thread ();
115 if (should_print_stop_to_console (interp, thread))
116 print_stop_event (cli->cli_uiout);
120 /* Observer for the signal_received notification. */
123 cli_on_signal_received (enum gdb_signal siggnal)
125 SWITCH_THRU_ALL_UIS ()
127 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
132 print_signal_received_reason (cli->cli_uiout, siggnal);
136 /* Observer for the end_stepping_range notification. */
139 cli_on_end_stepping_range (void)
141 SWITCH_THRU_ALL_UIS ()
143 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
148 print_end_stepping_range_reason (cli->cli_uiout);
152 /* Observer for the signalled notification. */
155 cli_on_signal_exited (enum gdb_signal siggnal)
157 SWITCH_THRU_ALL_UIS ()
159 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
164 print_signal_exited_reason (cli->cli_uiout, siggnal);
168 /* Observer for the exited notification. */
171 cli_on_exited (int exitstatus)
173 SWITCH_THRU_ALL_UIS ()
175 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
180 print_exited_reason (cli->cli_uiout, exitstatus);
184 /* Observer for the no_history notification. */
187 cli_on_no_history (void)
189 SWITCH_THRU_ALL_UIS ()
191 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
196 print_no_history_reason (cli->cli_uiout);
200 /* Observer for the sync_execution_done notification. */
203 cli_on_sync_execution_done (void)
205 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
210 display_gdb_prompt (NULL);
213 /* Observer for the command_error notification. */
216 cli_on_command_error (void)
218 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
223 display_gdb_prompt (NULL);
226 /* Observer for the user_selected_context_changed notification. */
229 cli_on_user_selected_context_changed (user_selected_what selection)
231 struct thread_info *tp;
233 /* This event is suppressed. */
234 if (cli_suppress_notification.user_selected_context)
237 tp = find_thread_ptid (inferior_ptid);
239 SWITCH_THRU_ALL_UIS ()
241 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
246 if (selection & USER_SELECTED_INFERIOR)
247 print_selected_inferior (cli->cli_uiout);
250 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
251 print_selected_thread_frame (cli->cli_uiout, selection);
255 /* pre_command_loop implementation. */
258 cli_interpreter_pre_command_loop (struct interp *self)
260 display_gdb_prompt (0);
263 /* These implement the cli out interpreter: */
266 cli_interpreter_init (struct interp *self, int top_level)
268 return interp_data (self);
272 cli_interpreter_resume (void *data)
274 struct ui *ui = current_ui;
275 struct cli_interp *cli = (struct cli_interp *) data;
276 struct ui_file *stream;
278 /*sync_execution = 1; */
280 /* gdb_setup_readline will change gdb_stdout. If the CLI was
281 previously writing to gdb_stdout, then set it to the new
282 gdb_stdout afterwards. */
284 stream = cli->cli_uiout->set_stream (gdb_stdout);
285 if (stream != gdb_stdout)
287 cli->cli_uiout->set_stream (stream);
291 gdb_setup_readline (1);
293 ui->input_handler = command_line_handler;
296 cli->cli_uiout->set_stream (gdb_stdout);
302 cli_interpreter_suspend (void *data)
304 gdb_disable_readline ();
308 static struct gdb_exception
309 cli_interpreter_exec (void *data, const char *command_str)
311 struct cli_interp *cli = (struct cli_interp *) data;
312 struct ui_file *old_stream;
313 struct gdb_exception result;
315 /* FIXME: cagney/2003-02-01: Need to const char *propogate
316 safe_execute_command. */
317 char *str = (char *) alloca (strlen (command_str) + 1);
318 strcpy (str, command_str);
320 /* gdb_stdout could change between the time cli_uiout was
321 initialized and now. Since we're probably using a different
322 interpreter which has a new ui_file for gdb_stdout, use that one
323 instead of the default.
325 It is important that it gets reset everytime, since the user
326 could set gdb to use a different interpreter. */
327 old_stream = cli->cli_uiout->set_stream (gdb_stdout);
328 result = safe_execute_command (cli->cli_uiout, str, 1);
329 cli->cli_uiout->set_stream (old_stream);
334 cli_interpreter_supports_command_editing (struct interp *interp)
339 static struct gdb_exception
340 safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
342 struct gdb_exception e = exception_none;
343 struct ui_out *saved_uiout;
345 /* Save and override the global ``struct ui_out'' builder. */
346 saved_uiout = current_uiout;
347 current_uiout = command_uiout;
351 execute_command (command, from_tty);
353 CATCH (exception, RETURN_MASK_ALL)
359 /* Restore the global builder. */
360 current_uiout = saved_uiout;
362 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
363 caller should print the exception. */
364 exception_print (gdb_stderr, e);
368 static struct ui_out *
369 cli_ui_out (struct interp *self)
371 struct cli_interp *cli = (struct cli_interp *) interp_data (self);
373 return cli->cli_uiout;
376 /* These hold the pushed copies of the gdb output files.
377 If NULL then nothing has yet been pushed. */
378 struct saved_output_files
386 static saved_output_files saved_output;
388 /* See cli-interp.h. */
391 cli_set_logging (struct interp *interp,
392 ui_file_up logfile, bool logging_redirect)
396 saved_output.out = gdb_stdout;
397 saved_output.err = gdb_stderr;
398 saved_output.log = gdb_stdlog;
399 saved_output.targ = gdb_stdtarg;
400 saved_output.targerr = gdb_stdtargerr;
402 /* A raw pointer since ownership is transferred to
404 ui_file *output = make_logging_output (gdb_stdout,
410 gdb_stdtarg = output;
411 gdb_stdtargerr = output;
415 /* Only delete one of the files -- they are all set to the same
419 gdb_stdout = saved_output.out;
420 gdb_stderr = saved_output.err;
421 gdb_stdlog = saved_output.log;
422 gdb_stdtarg = saved_output.targ;
423 gdb_stdtargerr = saved_output.targerr;
425 saved_output.out = NULL;
426 saved_output.err = NULL;
427 saved_output.log = NULL;
428 saved_output.targ = NULL;
429 saved_output.targerr = NULL;
433 /* The CLI interpreter's vtable. */
435 static const struct interp_procs cli_interp_procs = {
436 cli_interpreter_init, /* init_proc */
437 cli_interpreter_resume, /* resume_proc */
438 cli_interpreter_suspend, /* suspend_proc */
439 cli_interpreter_exec, /* exec_proc */
440 cli_ui_out, /* ui_out_proc */
441 cli_set_logging, /* set_logging_proc */
442 cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
443 cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
446 /* Factory for CLI interpreters. */
448 static struct interp *
449 cli_interp_factory (const char *name)
451 struct cli_interp *cli = XNEW (struct cli_interp);
453 /* Create a default uiout builder for the CLI. */
454 cli->cli_uiout = cli_out_new (gdb_stdout);
456 return interp_new (name, &cli_interp_procs, cli);
459 /* Standard gdb initialization hook. */
460 extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
463 _initialize_cli_interp (void)
465 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
467 /* If changing this, remember to update tui-interp.c as well. */
468 observer_attach_normal_stop (cli_on_normal_stop);
469 observer_attach_end_stepping_range (cli_on_end_stepping_range);
470 observer_attach_signal_received (cli_on_signal_received);
471 observer_attach_signal_exited (cli_on_signal_exited);
472 observer_attach_exited (cli_on_exited);
473 observer_attach_no_history (cli_on_no_history);
474 observer_attach_sync_execution_done (cli_on_sync_execution_done);
475 observer_attach_command_error (cli_on_command_error);
476 observer_attach_user_selected_context_changed
477 (cli_on_user_selected_context_changed);