Record minimal symbols directly in reader.
[deliverable/binutils-gdb.git] / gdb / cli / cli-interp.c
1 /* CLI Definitions for GDB, the GNU debugger.
2
3 Copyright (C) 2002-2016 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 "event-top.h"
28 #include "infrun.h"
29 #include "observer.h"
30 #include "gdbthread.h"
31 #include "thread-fsm.h"
32
33 /* The console interpreter. */
34 struct cli_interp
35 {
36 /* The ui_out for the console interpreter. */
37 struct ui_out *cli_uiout;
38 };
39
40 /* Suppress notification struct. */
41 struct cli_suppress_notification cli_suppress_notification =
42 {
43 0 /* user_selected_context_changed */
44 };
45
46 /* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
47 and returns NULL otherwise. */
48
49 static struct cli_interp *
50 as_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 }
56
57 /* Longjmp-safe wrapper for "execute_command". */
58 static struct gdb_exception safe_execute_command (struct ui_out *uiout,
59 char *command,
60 int from_tty);
61
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
80 int
81 should_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)
86 || tp->thread_fsm == NULL
87 || tp->thread_fsm->command_interp == console_interp
88 || !thread_fsm_finished_p (tp->thread_fsm))
89 return 1;
90 return 0;
91 }
92
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
97 /* Observer for the normal_stop notification. */
98
99 static void
100 cli_on_normal_stop (struct bpstats *bs, int print_frame)
101 {
102 struct switch_thru_all_uis state;
103
104 if (!print_frame)
105 return;
106
107 SWITCH_THRU_ALL_UIS (state)
108 {
109 struct interp *interp = top_level_interpreter ();
110 struct cli_interp *cli = as_cli_interp (interp);
111 struct thread_info *thread;
112
113 if (cli == NULL)
114 continue;
115
116 thread = inferior_thread ();
117 if (should_print_stop_to_console (interp, thread))
118 print_stop_event (cli->cli_uiout);
119 }
120 }
121
122 /* Observer for the signal_received notification. */
123
124 static void
125 cli_on_signal_received (enum gdb_signal siggnal)
126 {
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 }
138 }
139
140 /* Observer for the end_stepping_range notification. */
141
142 static void
143 cli_on_end_stepping_range (void)
144 {
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 }
156 }
157
158 /* Observer for the signalled notification. */
159
160 static void
161 cli_on_signal_exited (enum gdb_signal siggnal)
162 {
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 }
174 }
175
176 /* Observer for the exited notification. */
177
178 static void
179 cli_on_exited (int exitstatus)
180 {
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 }
192 }
193
194 /* Observer for the no_history notification. */
195
196 static void
197 cli_on_no_history (void)
198 {
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 }
210 }
211
212 /* Observer for the sync_execution_done notification. */
213
214 static void
215 cli_on_sync_execution_done (void)
216 {
217 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
218
219 if (cli == NULL)
220 return;
221
222 display_gdb_prompt (NULL);
223 }
224
225 /* Observer for the command_error notification. */
226
227 static void
228 cli_on_command_error (void)
229 {
230 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
231
232 if (cli == NULL)
233 return;
234
235 display_gdb_prompt (NULL);
236 }
237
238 /* Observer for the user_selected_context_changed notification. */
239
240 static void
241 cli_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
268 /* pre_command_loop implementation. */
269
270 void
271 cli_interpreter_pre_command_loop (struct interp *self)
272 {
273 display_gdb_prompt (0);
274 }
275
276 /* These implement the cli out interpreter: */
277
278 static void *
279 cli_interpreter_init (struct interp *self, int top_level)
280 {
281 return interp_data (self);
282 }
283
284 static int
285 cli_interpreter_resume (void *data)
286 {
287 struct ui *ui = current_ui;
288 struct cli_interp *cli = (struct cli_interp *) data;
289 struct ui_file *stream;
290
291 /*sync_execution = 1; */
292
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. */
296
297 stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
298 if (stream != gdb_stdout)
299 {
300 cli_out_set_stream (cli->cli_uiout, stream);
301 stream = NULL;
302 }
303
304 gdb_setup_readline (1);
305
306 ui->input_handler = command_line_handler;
307
308 if (stream != NULL)
309 cli_out_set_stream (cli->cli_uiout, gdb_stdout);
310
311 return 1;
312 }
313
314 static int
315 cli_interpreter_suspend (void *data)
316 {
317 gdb_disable_readline ();
318 return 1;
319 }
320
321 static struct gdb_exception
322 cli_interpreter_exec (void *data, const char *command_str)
323 {
324 struct cli_interp *cli = (struct cli_interp *) data;
325 struct ui_file *old_stream;
326 struct gdb_exception result;
327
328 /* FIXME: cagney/2003-02-01: Need to const char *propogate
329 safe_execute_command. */
330 char *str = (char *) alloca (strlen (command_str) + 1);
331 strcpy (str, command_str);
332
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.
337
338 It is important that it gets reset everytime, since the user
339 could set gdb to use a different interpreter. */
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);
343 return result;
344 }
345
346 int
347 cli_interpreter_supports_command_editing (struct interp *interp)
348 {
349 return 1;
350 }
351
352 static struct gdb_exception
353 safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
354 {
355 struct gdb_exception e = exception_none;
356 struct ui_out *saved_uiout;
357
358 /* Save and override the global ``struct ui_out'' builder. */
359 saved_uiout = current_uiout;
360 current_uiout = command_uiout;
361
362 TRY
363 {
364 execute_command (command, from_tty);
365 }
366 CATCH (exception, RETURN_MASK_ALL)
367 {
368 e = exception;
369 }
370 END_CATCH
371
372 /* Restore the global builder. */
373 current_uiout = saved_uiout;
374
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;
379 }
380
381 static struct ui_out *
382 cli_ui_out (struct interp *self)
383 {
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
391 static 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 */
398 cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
399 cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
400 };
401
402 /* Factory for CLI interpreters. */
403
404 static struct interp *
405 cli_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);
413 }
414
415 /* Standard gdb initialization hook. */
416 extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
417
418 void
419 _initialize_cli_interp (void)
420 {
421 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
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);
432 observer_attach_user_selected_context_changed
433 (cli_on_user_selected_context_changed);
434 }
This page took 0.039326 seconds and 5 git commands to generate.