Emit inferior, thread and frame selection events to all UIs
[deliverable/binutils-gdb.git] / gdb / cli / cli-interp.c
CommitLineData
4a8f6654
AC
1/* CLI Definitions for GDB, the GNU debugger.
2
618f726f 3 Copyright (C) 2002-2016 Free Software Foundation, Inc.
4a8f6654
AC
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
4a8f6654
AC
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/>. */
4a8f6654
AC
19
20#include "defs.h"
3c216924 21#include "cli-interp.h"
4a8f6654 22#include "interps.h"
4a8f6654
AC
23#include "event-top.h"
24#include "ui-out.h"
25#include "cli-out.h"
26#include "top.h" /* for "execute_command" */
3c216924 27#include "event-top.h"
fd664c91
PA
28#include "infrun.h"
29#include "observer.h"
26cde2cc
PA
30#include "gdbthread.h"
31#include "thread-fsm.h"
4a8f6654 32
8322445e
PA
33/* The console interpreter. */
34struct cli_interp
35{
36 /* The ui_out for the console interpreter. */
37 struct ui_out *cli_uiout;
38};
39
4034d0ff
AT
40/* Suppress notification struct. */
41struct cli_suppress_notification cli_suppress_notification =
42 {
43 0 /* user_selected_context_changed */
44 };
45
73ab01a0
PA
46/* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
47 and returns NULL otherwise. */
48
49static struct cli_interp *
50as_cli_interp (struct interp *interp)
51{
52 if (strcmp (interp_name (interp), INTERP_CONSOLE) == 0)
53 return (struct cli_interp *) interp_data (interp);
54 return NULL;
55}
4a8f6654 56
4791eb66 57/* Longjmp-safe wrapper for "execute_command". */
71fff37b 58static struct gdb_exception safe_execute_command (struct ui_out *uiout,
ebcd3b23
MS
59 char *command,
60 int from_tty);
fd664c91 61
26cde2cc
PA
62/* See cli-interp.h.
63
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
73 all consoles.
74
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. */
79
80int
81should_print_stop_to_console (struct interp *console_interp,
82 struct thread_info *tp)
83{
84 if ((bpstat_what (tp->control.stop_bpstat).main_action
85 == BPSTAT_WHAT_STOP_NOISY)
8980e177
PA
86 || tp->thread_fsm == NULL
87 || tp->thread_fsm->command_interp == console_interp
88 || !thread_fsm_finished_p (tp->thread_fsm))
26cde2cc
PA
89 return 1;
90 return 0;
91}
92
fd664c91
PA
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. */
96
243a9253
PA
97/* Observer for the normal_stop notification. */
98
99static void
100cli_on_normal_stop (struct bpstats *bs, int print_frame)
101{
73ab01a0
PA
102 struct switch_thru_all_uis state;
103
eaae60fd
PA
104 if (!print_frame)
105 return;
106
73ab01a0 107 SWITCH_THRU_ALL_UIS (state)
243a9253 108 {
eaae60fd
PA
109 struct interp *interp = top_level_interpreter ();
110 struct cli_interp *cli = as_cli_interp (interp);
111 struct thread_info *thread;
73ab01a0
PA
112
113 if (cli == NULL)
114 continue;
115
eaae60fd
PA
116 thread = inferior_thread ();
117 if (should_print_stop_to_console (interp, thread))
73ab01a0 118 print_stop_event (cli->cli_uiout);
243a9253
PA
119 }
120}
121
fd664c91
PA
122/* Observer for the signal_received notification. */
123
124static void
125cli_on_signal_received (enum gdb_signal siggnal)
126{
73ab01a0
PA
127 struct switch_thru_all_uis state;
128
129 SWITCH_THRU_ALL_UIS (state)
130 {
131 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
132
133 if (cli == NULL)
134 continue;
135
136 print_signal_received_reason (cli->cli_uiout, siggnal);
137 }
fd664c91
PA
138}
139
140/* Observer for the end_stepping_range notification. */
141
142static void
143cli_on_end_stepping_range (void)
144{
73ab01a0
PA
145 struct switch_thru_all_uis state;
146
147 SWITCH_THRU_ALL_UIS (state)
148 {
149 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
150
151 if (cli == NULL)
152 continue;
153
154 print_end_stepping_range_reason (cli->cli_uiout);
155 }
fd664c91
PA
156}
157
158/* Observer for the signalled notification. */
159
160static void
161cli_on_signal_exited (enum gdb_signal siggnal)
162{
73ab01a0
PA
163 struct switch_thru_all_uis state;
164
165 SWITCH_THRU_ALL_UIS (state)
166 {
167 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
168
169 if (cli == NULL)
170 continue;
171
172 print_signal_exited_reason (cli->cli_uiout, siggnal);
173 }
fd664c91
PA
174}
175
176/* Observer for the exited notification. */
177
178static void
179cli_on_exited (int exitstatus)
180{
73ab01a0
PA
181 struct switch_thru_all_uis state;
182
183 SWITCH_THRU_ALL_UIS (state)
184 {
185 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
186
187 if (cli == NULL)
188 continue;
189
190 print_exited_reason (cli->cli_uiout, exitstatus);
191 }
fd664c91
PA
192}
193
194/* Observer for the no_history notification. */
195
196static void
197cli_on_no_history (void)
198{
73ab01a0
PA
199 struct switch_thru_all_uis state;
200
201 SWITCH_THRU_ALL_UIS (state)
202 {
203 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
204
205 if (cli == NULL)
206 continue;
207
208 print_no_history_reason (cli->cli_uiout);
209 }
fd664c91
PA
210}
211
92bcb5f9
PA
212/* Observer for the sync_execution_done notification. */
213
214static void
215cli_on_sync_execution_done (void)
216{
73ab01a0
PA
217 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
218
219 if (cli == NULL)
220 return;
221
222 display_gdb_prompt (NULL);
92bcb5f9
PA
223}
224
225/* Observer for the command_error notification. */
226
227static void
228cli_on_command_error (void)
229{
73ab01a0
PA
230 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
231
232 if (cli == NULL)
233 return;
234
235 display_gdb_prompt (NULL);
92bcb5f9
PA
236}
237
4034d0ff
AT
238/* Observer for the user_selected_context_changed notification. */
239
240static void
241cli_on_user_selected_context_changed (user_selected_what selection)
242{
243 struct switch_thru_all_uis state;
244 struct thread_info *tp;
245
246 /* This event is suppressed. */
247 if (cli_suppress_notification.user_selected_context)
248 return;
249
250 tp = find_thread_ptid (inferior_ptid);
251
252 SWITCH_THRU_ALL_UIS (state)
253 {
254 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
255
256 if (cli == NULL)
257 continue;
258
259 if (selection & USER_SELECTED_INFERIOR)
260 print_selected_inferior (cli->cli_uiout);
261
262 if (tp != NULL
263 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
264 print_selected_thread_frame (cli->cli_uiout, selection);
265 }
266}
267
b2d86570
PA
268/* pre_command_loop implementation. */
269
270void
271cli_interpreter_pre_command_loop (struct interp *self)
272{
273 display_gdb_prompt (0);
274}
275
4a8f6654
AC
276/* These implement the cli out interpreter: */
277
278static void *
4801a9a3 279cli_interpreter_init (struct interp *self, int top_level)
4a8f6654 280{
8322445e 281 return interp_data (self);
4a8f6654
AC
282}
283
284static int
285cli_interpreter_resume (void *data)
286{
3c216924 287 struct ui *ui = current_ui;
8322445e 288 struct cli_interp *cli = (struct cli_interp *) data;
38caaeec
DJ
289 struct ui_file *stream;
290
4a8f6654 291 /*sync_execution = 1; */
38caaeec 292
ebcd3b23
MS
293 /* gdb_setup_readline will change gdb_stdout. If the CLI was
294 previously writing to gdb_stdout, then set it to the new
295 gdb_stdout afterwards. */
38caaeec 296
8322445e 297 stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
38caaeec
DJ
298 if (stream != gdb_stdout)
299 {
8322445e 300 cli_out_set_stream (cli->cli_uiout, stream);
38caaeec
DJ
301 stream = NULL;
302 }
303
3c216924
PA
304 gdb_setup_readline (1);
305
306 ui->input_handler = command_line_handler;
38caaeec
DJ
307
308 if (stream != NULL)
8322445e 309 cli_out_set_stream (cli->cli_uiout, gdb_stdout);
38caaeec 310
4a8f6654
AC
311 return 1;
312}
313
314static int
315cli_interpreter_suspend (void *data)
316{
317 gdb_disable_readline ();
318 return 1;
319}
320
71fff37b 321static struct gdb_exception
4a8f6654
AC
322cli_interpreter_exec (void *data, const char *command_str)
323{
8322445e 324 struct cli_interp *cli = (struct cli_interp *) data;
4a8f6654 325 struct ui_file *old_stream;
71fff37b 326 struct gdb_exception result;
4a8f6654
AC
327
328 /* FIXME: cagney/2003-02-01: Need to const char *propogate
329 safe_execute_command. */
224c3ddb
SM
330 char *str = (char *) alloca (strlen (command_str) + 1);
331 strcpy (str, command_str);
4a8f6654 332
ebcd3b23
MS
333 /* gdb_stdout could change between the time cli_uiout was
334 initialized and now. Since we're probably using a different
335 interpreter which has a new ui_file for gdb_stdout, use that one
336 instead of the default.
4a8f6654 337
ebcd3b23
MS
338 It is important that it gets reset everytime, since the user
339 could set gdb to use a different interpreter. */
8322445e
PA
340 old_stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
341 result = safe_execute_command (cli->cli_uiout, str, 1);
342 cli_out_set_stream (cli->cli_uiout, old_stream);
4a8f6654
AC
343 return result;
344}
345
3c216924
PA
346int
347cli_interpreter_supports_command_editing (struct interp *interp)
348{
349 return 1;
350}
351
71fff37b 352static struct gdb_exception
f9679975 353safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
4a8f6654 354{
7556d4a4 355 struct gdb_exception e = exception_none;
f9679975
PA
356 struct ui_out *saved_uiout;
357
358 /* Save and override the global ``struct ui_out'' builder. */
79a45e25
PA
359 saved_uiout = current_uiout;
360 current_uiout = command_uiout;
cdb27c12 361
492d29ea 362 TRY
04bd08de
TT
363 {
364 execute_command (command, from_tty);
365 }
492d29ea 366 CATCH (exception, RETURN_MASK_ALL)
7556d4a4
PA
367 {
368 e = exception;
369 }
492d29ea 370 END_CATCH
f9679975
PA
371
372 /* Restore the global builder. */
79a45e25 373 current_uiout = saved_uiout;
f9679975 374
8a076db9
AC
375 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
376 caller should print the exception. */
9cbc821d 377 exception_print (gdb_stderr, e);
8a076db9 378 return e;
4a8f6654
AC
379}
380
4801a9a3
PA
381static struct ui_out *
382cli_ui_out (struct interp *self)
383{
8322445e
PA
384 struct cli_interp *cli = (struct cli_interp *) interp_data (self);
385
386 return cli->cli_uiout;
387}
388
389/* The CLI interpreter's vtable. */
390
391static const struct interp_procs cli_interp_procs = {
392 cli_interpreter_init, /* init_proc */
393 cli_interpreter_resume, /* resume_proc */
394 cli_interpreter_suspend, /* suspend_proc */
395 cli_interpreter_exec, /* exec_proc */
396 cli_ui_out, /* ui_out_proc */
397 NULL, /* set_logging_proc */
b2d86570 398 cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
3c216924 399 cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
8322445e
PA
400};
401
402/* Factory for CLI interpreters. */
403
404static struct interp *
405cli_interp_factory (const char *name)
406{
407 struct cli_interp *cli = XNEW (struct cli_interp);
408
409 /* Create a default uiout builder for the CLI. */
410 cli->cli_uiout = cli_out_new (gdb_stdout);
411
412 return interp_new (name, &cli_interp_procs, cli);
4801a9a3 413}
4a8f6654 414
4791eb66 415/* Standard gdb initialization hook. */
b9362cc7
AC
416extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
417
4a8f6654
AC
418void
419_initialize_cli_interp (void)
420{
8322445e 421 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
73ab01a0
PA
422
423 /* If changing this, remember to update tui-interp.c as well. */
424 observer_attach_normal_stop (cli_on_normal_stop);
425 observer_attach_end_stepping_range (cli_on_end_stepping_range);
426 observer_attach_signal_received (cli_on_signal_received);
427 observer_attach_signal_exited (cli_on_signal_exited);
428 observer_attach_exited (cli_on_exited);
429 observer_attach_no_history (cli_on_no_history);
430 observer_attach_sync_execution_done (cli_on_sync_execution_done);
431 observer_attach_command_error (cli_on_command_error);
4034d0ff
AT
432 observer_attach_user_selected_context_changed
433 (cli_on_user_selected_context_changed);
4a8f6654 434}
This page took 1.015317 seconds and 4 git commands to generate.