Push thread->control.command_interp to the struct thread_fsm
[deliverable/binutils-gdb.git] / gdb / cli / cli-interp.c
... / ...
CommitLineData
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. */
34struct cli_interp
35{
36 /* The ui_out for the console interpreter. */
37 struct ui_out *cli_uiout;
38};
39
40/* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
41 and returns NULL otherwise. */
42
43static struct cli_interp *
44as_cli_interp (struct interp *interp)
45{
46 if (strcmp (interp_name (interp), INTERP_CONSOLE) == 0)
47 return (struct cli_interp *) interp_data (interp);
48 return NULL;
49}
50
51/* Longjmp-safe wrapper for "execute_command". */
52static struct gdb_exception safe_execute_command (struct ui_out *uiout,
53 char *command,
54 int from_tty);
55
56/* See cli-interp.h.
57
58 Breakpoint hits should always be mirrored to a console. Deciding
59 what to mirror to a console wrt to breakpoints and random stops
60 gets messy real fast. E.g., say "s" trips on a breakpoint. We'd
61 clearly want to mirror the event to the console in this case. But
62 what about more complicated cases like "s&; thread n; s&", and one
63 of those steps spawning a new thread, and that thread hitting a
64 breakpoint? It's impossible in general to track whether the thread
65 had any relation to the commands that had been executed. So we
66 just simplify and always mirror breakpoints and random events to
67 all consoles.
68
69 OTOH, we should print the source line to the console when stepping
70 or other similar commands, iff the step was started by that console
71 (or in MI's case, by a console command), but not if it was started
72 with MI's -exec-step or similar. */
73
74int
75should_print_stop_to_console (struct interp *console_interp,
76 struct thread_info *tp)
77{
78 if ((bpstat_what (tp->control.stop_bpstat).main_action
79 == BPSTAT_WHAT_STOP_NOISY)
80 || tp->thread_fsm == NULL
81 || tp->thread_fsm->command_interp == console_interp
82 || !thread_fsm_finished_p (tp->thread_fsm))
83 return 1;
84 return 0;
85}
86
87/* Observers for several run control events. If the interpreter is
88 quiet (i.e., another interpreter is being run with
89 interpreter-exec), print nothing. */
90
91/* Observer for the normal_stop notification. */
92
93static void
94cli_on_normal_stop (struct bpstats *bs, int print_frame)
95{
96 struct switch_thru_all_uis state;
97
98 SWITCH_THRU_ALL_UIS (state)
99 {
100 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
101
102 if (cli == NULL)
103 continue;
104
105 if (print_frame)
106 print_stop_event (cli->cli_uiout);
107 }
108}
109
110/* Observer for the signal_received notification. */
111
112static void
113cli_on_signal_received (enum gdb_signal siggnal)
114{
115 struct switch_thru_all_uis state;
116
117 SWITCH_THRU_ALL_UIS (state)
118 {
119 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
120
121 if (cli == NULL)
122 continue;
123
124 print_signal_received_reason (cli->cli_uiout, siggnal);
125 }
126}
127
128/* Observer for the end_stepping_range notification. */
129
130static void
131cli_on_end_stepping_range (void)
132{
133 struct switch_thru_all_uis state;
134
135 SWITCH_THRU_ALL_UIS (state)
136 {
137 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
138
139 if (cli == NULL)
140 continue;
141
142 print_end_stepping_range_reason (cli->cli_uiout);
143 }
144}
145
146/* Observer for the signalled notification. */
147
148static void
149cli_on_signal_exited (enum gdb_signal siggnal)
150{
151 struct switch_thru_all_uis state;
152
153 SWITCH_THRU_ALL_UIS (state)
154 {
155 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
156
157 if (cli == NULL)
158 continue;
159
160 print_signal_exited_reason (cli->cli_uiout, siggnal);
161 }
162}
163
164/* Observer for the exited notification. */
165
166static void
167cli_on_exited (int exitstatus)
168{
169 struct switch_thru_all_uis state;
170
171 SWITCH_THRU_ALL_UIS (state)
172 {
173 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
174
175 if (cli == NULL)
176 continue;
177
178 print_exited_reason (cli->cli_uiout, exitstatus);
179 }
180}
181
182/* Observer for the no_history notification. */
183
184static void
185cli_on_no_history (void)
186{
187 struct switch_thru_all_uis state;
188
189 SWITCH_THRU_ALL_UIS (state)
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
202static void
203cli_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
215static void
216cli_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/* pre_command_loop implementation. */
227
228void
229cli_interpreter_pre_command_loop (struct interp *self)
230{
231 display_gdb_prompt (0);
232}
233
234/* These implement the cli out interpreter: */
235
236static void *
237cli_interpreter_init (struct interp *self, int top_level)
238{
239 return interp_data (self);
240}
241
242static int
243cli_interpreter_resume (void *data)
244{
245 struct ui *ui = current_ui;
246 struct cli_interp *cli = (struct cli_interp *) data;
247 struct ui_file *stream;
248
249 /*sync_execution = 1; */
250
251 /* gdb_setup_readline will change gdb_stdout. If the CLI was
252 previously writing to gdb_stdout, then set it to the new
253 gdb_stdout afterwards. */
254
255 stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
256 if (stream != gdb_stdout)
257 {
258 cli_out_set_stream (cli->cli_uiout, stream);
259 stream = NULL;
260 }
261
262 gdb_setup_readline (1);
263
264 ui->input_handler = command_line_handler;
265
266 if (stream != NULL)
267 cli_out_set_stream (cli->cli_uiout, gdb_stdout);
268
269 return 1;
270}
271
272static int
273cli_interpreter_suspend (void *data)
274{
275 gdb_disable_readline ();
276 return 1;
277}
278
279static struct gdb_exception
280cli_interpreter_exec (void *data, const char *command_str)
281{
282 struct cli_interp *cli = (struct cli_interp *) data;
283 struct ui_file *old_stream;
284 struct gdb_exception result;
285
286 /* FIXME: cagney/2003-02-01: Need to const char *propogate
287 safe_execute_command. */
288 char *str = (char *) alloca (strlen (command_str) + 1);
289 strcpy (str, command_str);
290
291 /* gdb_stdout could change between the time cli_uiout was
292 initialized and now. Since we're probably using a different
293 interpreter which has a new ui_file for gdb_stdout, use that one
294 instead of the default.
295
296 It is important that it gets reset everytime, since the user
297 could set gdb to use a different interpreter. */
298 old_stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
299 result = safe_execute_command (cli->cli_uiout, str, 1);
300 cli_out_set_stream (cli->cli_uiout, old_stream);
301 return result;
302}
303
304int
305cli_interpreter_supports_command_editing (struct interp *interp)
306{
307 return 1;
308}
309
310static struct gdb_exception
311safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
312{
313 struct gdb_exception e = exception_none;
314 struct ui_out *saved_uiout;
315
316 /* Save and override the global ``struct ui_out'' builder. */
317 saved_uiout = current_uiout;
318 current_uiout = command_uiout;
319
320 TRY
321 {
322 execute_command (command, from_tty);
323 }
324 CATCH (exception, RETURN_MASK_ALL)
325 {
326 e = exception;
327 }
328 END_CATCH
329
330 /* Restore the global builder. */
331 current_uiout = saved_uiout;
332
333 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
334 caller should print the exception. */
335 exception_print (gdb_stderr, e);
336 return e;
337}
338
339static struct ui_out *
340cli_ui_out (struct interp *self)
341{
342 struct cli_interp *cli = (struct cli_interp *) interp_data (self);
343
344 return cli->cli_uiout;
345}
346
347/* The CLI interpreter's vtable. */
348
349static const struct interp_procs cli_interp_procs = {
350 cli_interpreter_init, /* init_proc */
351 cli_interpreter_resume, /* resume_proc */
352 cli_interpreter_suspend, /* suspend_proc */
353 cli_interpreter_exec, /* exec_proc */
354 cli_ui_out, /* ui_out_proc */
355 NULL, /* set_logging_proc */
356 cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
357 cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
358};
359
360/* Factory for CLI interpreters. */
361
362static struct interp *
363cli_interp_factory (const char *name)
364{
365 struct cli_interp *cli = XNEW (struct cli_interp);
366
367 /* Create a default uiout builder for the CLI. */
368 cli->cli_uiout = cli_out_new (gdb_stdout);
369
370 return interp_new (name, &cli_interp_procs, cli);
371}
372
373/* Standard gdb initialization hook. */
374extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
375
376void
377_initialize_cli_interp (void)
378{
379 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
380
381 /* If changing this, remember to update tui-interp.c as well. */
382 observer_attach_normal_stop (cli_on_normal_stop);
383 observer_attach_end_stepping_range (cli_on_end_stepping_range);
384 observer_attach_signal_received (cli_on_signal_received);
385 observer_attach_signal_exited (cli_on_signal_exited);
386 observer_attach_exited (cli_on_exited);
387 observer_attach_no_history (cli_on_no_history);
388 observer_attach_sync_execution_done (cli_on_sync_execution_done);
389 observer_attach_command_error (cli_on_command_error);
390}
This page took 0.024458 seconds and 4 git commands to generate.