Class-ify ui_out
[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 cli_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 if (!print_frame)
103 return;
104
105 SWITCH_THRU_ALL_UIS ()
106 {
107 struct interp *interp = top_level_interpreter ();
108 struct cli_interp *cli = as_cli_interp (interp);
109 struct thread_info *thread;
110
111 if (cli == NULL)
112 continue;
113
114 thread = inferior_thread ();
115 if (should_print_stop_to_console (interp, thread))
116 print_stop_event (cli->cli_uiout);
117 }
118 }
119
120 /* Observer for the signal_received notification. */
121
122 static void
123 cli_on_signal_received (enum gdb_signal siggnal)
124 {
125 SWITCH_THRU_ALL_UIS ()
126 {
127 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
128
129 if (cli == NULL)
130 continue;
131
132 print_signal_received_reason (cli->cli_uiout, siggnal);
133 }
134 }
135
136 /* Observer for the end_stepping_range notification. */
137
138 static void
139 cli_on_end_stepping_range (void)
140 {
141 SWITCH_THRU_ALL_UIS ()
142 {
143 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
144
145 if (cli == NULL)
146 continue;
147
148 print_end_stepping_range_reason (cli->cli_uiout);
149 }
150 }
151
152 /* Observer for the signalled notification. */
153
154 static void
155 cli_on_signal_exited (enum gdb_signal siggnal)
156 {
157 SWITCH_THRU_ALL_UIS ()
158 {
159 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
160
161 if (cli == NULL)
162 continue;
163
164 print_signal_exited_reason (cli->cli_uiout, siggnal);
165 }
166 }
167
168 /* Observer for the exited notification. */
169
170 static void
171 cli_on_exited (int exitstatus)
172 {
173 SWITCH_THRU_ALL_UIS ()
174 {
175 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
176
177 if (cli == NULL)
178 continue;
179
180 print_exited_reason (cli->cli_uiout, exitstatus);
181 }
182 }
183
184 /* Observer for the no_history notification. */
185
186 static void
187 cli_on_no_history (void)
188 {
189 SWITCH_THRU_ALL_UIS ()
190 {
191 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
192
193 if (cli == NULL)
194 continue;
195
196 print_no_history_reason (cli->cli_uiout);
197 }
198 }
199
200 /* Observer for the sync_execution_done notification. */
201
202 static void
203 cli_on_sync_execution_done (void)
204 {
205 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
206
207 if (cli == NULL)
208 return;
209
210 display_gdb_prompt (NULL);
211 }
212
213 /* Observer for the command_error notification. */
214
215 static void
216 cli_on_command_error (void)
217 {
218 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
219
220 if (cli == NULL)
221 return;
222
223 display_gdb_prompt (NULL);
224 }
225
226 /* Observer for the user_selected_context_changed notification. */
227
228 static void
229 cli_on_user_selected_context_changed (user_selected_what selection)
230 {
231 struct thread_info *tp;
232
233 /* This event is suppressed. */
234 if (cli_suppress_notification.user_selected_context)
235 return;
236
237 tp = find_thread_ptid (inferior_ptid);
238
239 SWITCH_THRU_ALL_UIS ()
240 {
241 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
242
243 if (cli == NULL)
244 continue;
245
246 if (selection & USER_SELECTED_INFERIOR)
247 print_selected_inferior (cli->cli_uiout);
248
249 if (tp != NULL
250 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
251 print_selected_thread_frame (cli->cli_uiout, selection);
252 }
253 }
254
255 /* pre_command_loop implementation. */
256
257 void
258 cli_interpreter_pre_command_loop (struct interp *self)
259 {
260 display_gdb_prompt (0);
261 }
262
263 /* These implement the cli out interpreter: */
264
265 static void *
266 cli_interpreter_init (struct interp *self, int top_level)
267 {
268 return interp_data (self);
269 }
270
271 static int
272 cli_interpreter_resume (void *data)
273 {
274 struct ui *ui = current_ui;
275 struct cli_interp *cli = (struct cli_interp *) data;
276 struct ui_file *stream;
277
278 /*sync_execution = 1; */
279
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. */
283
284 stream = cli->cli_uiout->set_stream (gdb_stdout);
285 if (stream != gdb_stdout)
286 {
287 cli->cli_uiout->set_stream (stream);
288 stream = NULL;
289 }
290
291 gdb_setup_readline (1);
292
293 ui->input_handler = command_line_handler;
294
295 if (stream != NULL)
296 cli->cli_uiout->set_stream (gdb_stdout);
297
298 return 1;
299 }
300
301 static int
302 cli_interpreter_suspend (void *data)
303 {
304 gdb_disable_readline ();
305 return 1;
306 }
307
308 static struct gdb_exception
309 cli_interpreter_exec (void *data, const char *command_str)
310 {
311 struct cli_interp *cli = (struct cli_interp *) data;
312 struct ui_file *old_stream;
313 struct gdb_exception result;
314
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);
319
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.
324
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);
330 return result;
331 }
332
333 int
334 cli_interpreter_supports_command_editing (struct interp *interp)
335 {
336 return 1;
337 }
338
339 static struct gdb_exception
340 safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
341 {
342 struct gdb_exception e = exception_none;
343 struct ui_out *saved_uiout;
344
345 /* Save and override the global ``struct ui_out'' builder. */
346 saved_uiout = current_uiout;
347 current_uiout = command_uiout;
348
349 TRY
350 {
351 execute_command (command, from_tty);
352 }
353 CATCH (exception, RETURN_MASK_ALL)
354 {
355 e = exception;
356 }
357 END_CATCH
358
359 /* Restore the global builder. */
360 current_uiout = saved_uiout;
361
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);
365 return e;
366 }
367
368 static struct ui_out *
369 cli_ui_out (struct interp *self)
370 {
371 struct cli_interp *cli = (struct cli_interp *) interp_data (self);
372
373 return cli->cli_uiout;
374 }
375
376 /* The CLI interpreter's vtable. */
377
378 static const struct interp_procs cli_interp_procs = {
379 cli_interpreter_init, /* init_proc */
380 cli_interpreter_resume, /* resume_proc */
381 cli_interpreter_suspend, /* suspend_proc */
382 cli_interpreter_exec, /* exec_proc */
383 cli_ui_out, /* ui_out_proc */
384 NULL, /* set_logging_proc */
385 cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
386 cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
387 };
388
389 /* Factory for CLI interpreters. */
390
391 static struct interp *
392 cli_interp_factory (const char *name)
393 {
394 struct cli_interp *cli = XNEW (struct cli_interp);
395
396 /* Create a default uiout builder for the CLI. */
397 cli->cli_uiout = cli_out_new (gdb_stdout);
398
399 return interp_new (name, &cli_interp_procs, cli);
400 }
401
402 /* Standard gdb initialization hook. */
403 extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
404
405 void
406 _initialize_cli_interp (void)
407 {
408 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
409
410 /* If changing this, remember to update tui-interp.c as well. */
411 observer_attach_normal_stop (cli_on_normal_stop);
412 observer_attach_end_stepping_range (cli_on_end_stepping_range);
413 observer_attach_signal_received (cli_on_signal_received);
414 observer_attach_signal_exited (cli_on_signal_exited);
415 observer_attach_exited (cli_on_exited);
416 observer_attach_no_history (cli_on_no_history);
417 observer_attach_sync_execution_done (cli_on_sync_execution_done);
418 observer_attach_command_error (cli_on_command_error);
419 observer_attach_user_selected_context_changed
420 (cli_on_user_selected_context_changed);
421 }
This page took 0.038509 seconds and 4 git commands to generate.