Unify shell-finding logic
[deliverable/binutils-gdb.git] / gdb / cli / cli-interp.c
CommitLineData
4a8f6654
AC
1/* CLI Definitions for GDB, the GNU debugger.
2
e2882c85 3 Copyright (C) 2002-2018 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 28#include "infrun.h"
76727919 29#include "observable.h"
26cde2cc
PA
30#include "gdbthread.h"
31#include "thread-fsm.h"
00431a78 32#include "inferior.h"
4a8f6654 33
d6f9b0fb
PA
34cli_interp_base::cli_interp_base (const char *name)
35 : interp (name)
36{}
37
38cli_interp_base::~cli_interp_base ()
39{}
40
8322445e 41/* The console interpreter. */
d6f9b0fb
PA
42
43class cli_interp final : public cli_interp_base
8322445e 44{
d6f9b0fb
PA
45 public:
46 explicit cli_interp (const char *name);
ba543ca5 47 ~cli_interp ();
d6f9b0fb
PA
48
49 void init (bool top_level) override;
50 void resume () override;
51 void suspend () override;
52 gdb_exception exec (const char *command_str) override;
53 ui_out *interp_ui_out () override;
54
8322445e 55 /* The ui_out for the console interpreter. */
112e8700 56 cli_ui_out *cli_uiout;
8322445e
PA
57};
58
d6f9b0fb
PA
59cli_interp::cli_interp (const char *name)
60 : cli_interp_base (name)
61{
62 /* Create a default uiout builder for the CLI. */
63 this->cli_uiout = cli_out_new (gdb_stdout);
64}
65
ba543ca5
GB
66cli_interp::~cli_interp ()
67{
68 delete cli_uiout;
69}
70
4034d0ff
AT
71/* Suppress notification struct. */
72struct cli_suppress_notification cli_suppress_notification =
73 {
74 0 /* user_selected_context_changed */
75 };
76
73ab01a0
PA
77/* Returns the INTERP's data cast as cli_interp if INTERP is a CLI,
78 and returns NULL otherwise. */
79
80static struct cli_interp *
81as_cli_interp (struct interp *interp)
82{
716b8bc5 83 return dynamic_cast<cli_interp *> (interp);
73ab01a0 84}
4a8f6654 85
4791eb66 86/* Longjmp-safe wrapper for "execute_command". */
71fff37b 87static struct gdb_exception safe_execute_command (struct ui_out *uiout,
95a6b0a1 88 const char *command,
ebcd3b23 89 int from_tty);
fd664c91 90
26cde2cc
PA
91/* See cli-interp.h.
92
93 Breakpoint hits should always be mirrored to a console. Deciding
94 what to mirror to a console wrt to breakpoints and random stops
95 gets messy real fast. E.g., say "s" trips on a breakpoint. We'd
96 clearly want to mirror the event to the console in this case. But
97 what about more complicated cases like "s&; thread n; s&", and one
98 of those steps spawning a new thread, and that thread hitting a
99 breakpoint? It's impossible in general to track whether the thread
100 had any relation to the commands that had been executed. So we
101 just simplify and always mirror breakpoints and random events to
102 all consoles.
103
104 OTOH, we should print the source line to the console when stepping
105 or other similar commands, iff the step was started by that console
106 (or in MI's case, by a console command), but not if it was started
107 with MI's -exec-step or similar. */
108
109int
110should_print_stop_to_console (struct interp *console_interp,
111 struct thread_info *tp)
112{
113 if ((bpstat_what (tp->control.stop_bpstat).main_action
114 == BPSTAT_WHAT_STOP_NOISY)
8980e177
PA
115 || tp->thread_fsm == NULL
116 || tp->thread_fsm->command_interp == console_interp
117 || !thread_fsm_finished_p (tp->thread_fsm))
26cde2cc
PA
118 return 1;
119 return 0;
120}
121
fd664c91
PA
122/* Observers for several run control events. If the interpreter is
123 quiet (i.e., another interpreter is being run with
124 interpreter-exec), print nothing. */
125
243a9253
PA
126/* Observer for the normal_stop notification. */
127
128static void
129cli_on_normal_stop (struct bpstats *bs, int print_frame)
130{
eaae60fd
PA
131 if (!print_frame)
132 return;
133
0e454242 134 SWITCH_THRU_ALL_UIS ()
243a9253 135 {
eaae60fd
PA
136 struct interp *interp = top_level_interpreter ();
137 struct cli_interp *cli = as_cli_interp (interp);
138 struct thread_info *thread;
73ab01a0
PA
139
140 if (cli == NULL)
141 continue;
142
eaae60fd
PA
143 thread = inferior_thread ();
144 if (should_print_stop_to_console (interp, thread))
73ab01a0 145 print_stop_event (cli->cli_uiout);
243a9253
PA
146 }
147}
148
fd664c91
PA
149/* Observer for the signal_received notification. */
150
151static void
152cli_on_signal_received (enum gdb_signal siggnal)
153{
0e454242 154 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
155 {
156 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
157
158 if (cli == NULL)
159 continue;
160
161 print_signal_received_reason (cli->cli_uiout, siggnal);
162 }
fd664c91
PA
163}
164
165/* Observer for the end_stepping_range notification. */
166
167static void
168cli_on_end_stepping_range (void)
169{
0e454242 170 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
171 {
172 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
173
174 if (cli == NULL)
175 continue;
176
177 print_end_stepping_range_reason (cli->cli_uiout);
178 }
fd664c91
PA
179}
180
181/* Observer for the signalled notification. */
182
183static void
184cli_on_signal_exited (enum gdb_signal siggnal)
185{
0e454242 186 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
187 {
188 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
189
190 if (cli == NULL)
191 continue;
192
193 print_signal_exited_reason (cli->cli_uiout, siggnal);
194 }
fd664c91
PA
195}
196
197/* Observer for the exited notification. */
198
199static void
200cli_on_exited (int exitstatus)
201{
0e454242 202 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
203 {
204 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
205
206 if (cli == NULL)
207 continue;
208
209 print_exited_reason (cli->cli_uiout, exitstatus);
210 }
fd664c91
PA
211}
212
213/* Observer for the no_history notification. */
214
215static void
216cli_on_no_history (void)
217{
0e454242 218 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
219 {
220 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
221
222 if (cli == NULL)
223 continue;
224
225 print_no_history_reason (cli->cli_uiout);
226 }
fd664c91
PA
227}
228
92bcb5f9
PA
229/* Observer for the sync_execution_done notification. */
230
231static void
232cli_on_sync_execution_done (void)
233{
73ab01a0
PA
234 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
235
236 if (cli == NULL)
237 return;
238
239 display_gdb_prompt (NULL);
92bcb5f9
PA
240}
241
242/* Observer for the command_error notification. */
243
244static void
245cli_on_command_error (void)
246{
73ab01a0
PA
247 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
248
249 if (cli == NULL)
250 return;
251
252 display_gdb_prompt (NULL);
92bcb5f9
PA
253}
254
4034d0ff
AT
255/* Observer for the user_selected_context_changed notification. */
256
257static void
258cli_on_user_selected_context_changed (user_selected_what selection)
259{
4034d0ff
AT
260 struct thread_info *tp;
261
262 /* This event is suppressed. */
263 if (cli_suppress_notification.user_selected_context)
264 return;
265
266 tp = find_thread_ptid (inferior_ptid);
267
0e454242 268 SWITCH_THRU_ALL_UIS ()
4034d0ff
AT
269 {
270 struct cli_interp *cli = as_cli_interp (top_level_interpreter ());
271
272 if (cli == NULL)
273 continue;
274
275 if (selection & USER_SELECTED_INFERIOR)
276 print_selected_inferior (cli->cli_uiout);
277
278 if (tp != NULL
279 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
280 print_selected_thread_frame (cli->cli_uiout, selection);
281 }
282}
283
b2d86570
PA
284/* pre_command_loop implementation. */
285
286void
d6f9b0fb 287cli_interp_base::pre_command_loop ()
b2d86570
PA
288{
289 display_gdb_prompt (0);
290}
291
4a8f6654
AC
292/* These implement the cli out interpreter: */
293
d6f9b0fb
PA
294void
295cli_interp::init (bool top_level)
4a8f6654 296{
4a8f6654
AC
297}
298
d6f9b0fb
PA
299void
300cli_interp::resume ()
4a8f6654 301{
3c216924 302 struct ui *ui = current_ui;
d6f9b0fb 303 struct cli_interp *cli = this;
38caaeec
DJ
304 struct ui_file *stream;
305
4a8f6654 306 /*sync_execution = 1; */
38caaeec 307
ebcd3b23
MS
308 /* gdb_setup_readline will change gdb_stdout. If the CLI was
309 previously writing to gdb_stdout, then set it to the new
310 gdb_stdout afterwards. */
38caaeec 311
112e8700 312 stream = cli->cli_uiout->set_stream (gdb_stdout);
38caaeec
DJ
313 if (stream != gdb_stdout)
314 {
112e8700 315 cli->cli_uiout->set_stream (stream);
38caaeec
DJ
316 stream = NULL;
317 }
318
3c216924
PA
319 gdb_setup_readline (1);
320
321 ui->input_handler = command_line_handler;
38caaeec
DJ
322
323 if (stream != NULL)
112e8700 324 cli->cli_uiout->set_stream (gdb_stdout);
4a8f6654
AC
325}
326
d6f9b0fb
PA
327void
328cli_interp::suspend ()
4a8f6654
AC
329{
330 gdb_disable_readline ();
4a8f6654
AC
331}
332
d6f9b0fb
PA
333gdb_exception
334cli_interp::exec (const char *command_str)
4a8f6654 335{
d6f9b0fb 336 struct cli_interp *cli = this;
4a8f6654 337 struct ui_file *old_stream;
71fff37b 338 struct gdb_exception result;
4a8f6654 339
ebcd3b23
MS
340 /* gdb_stdout could change between the time cli_uiout was
341 initialized and now. Since we're probably using a different
342 interpreter which has a new ui_file for gdb_stdout, use that one
343 instead of the default.
4a8f6654 344
ebcd3b23
MS
345 It is important that it gets reset everytime, since the user
346 could set gdb to use a different interpreter. */
112e8700 347 old_stream = cli->cli_uiout->set_stream (gdb_stdout);
95a6b0a1 348 result = safe_execute_command (cli->cli_uiout, command_str, 1);
112e8700 349 cli->cli_uiout->set_stream (old_stream);
4a8f6654
AC
350 return result;
351}
352
d6f9b0fb
PA
353bool
354cli_interp_base::supports_command_editing ()
3c216924 355{
d6f9b0fb 356 return true;
3c216924
PA
357}
358
71fff37b 359static struct gdb_exception
95a6b0a1
TT
360safe_execute_command (struct ui_out *command_uiout, const char *command,
361 int from_tty)
4a8f6654 362{
7556d4a4 363 struct gdb_exception e = exception_none;
f9679975
PA
364
365 /* Save and override the global ``struct ui_out'' builder. */
753ff9bd
TT
366 scoped_restore saved_uiout = make_scoped_restore (&current_uiout,
367 command_uiout);
cdb27c12 368
492d29ea 369 TRY
04bd08de
TT
370 {
371 execute_command (command, from_tty);
372 }
492d29ea 373 CATCH (exception, RETURN_MASK_ALL)
7556d4a4
PA
374 {
375 e = exception;
376 }
492d29ea 377 END_CATCH
f9679975 378
8a076db9
AC
379 /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
380 caller should print the exception. */
9cbc821d 381 exception_print (gdb_stderr, e);
8a076db9 382 return e;
4a8f6654
AC
383}
384
d6f9b0fb
PA
385ui_out *
386cli_interp::interp_ui_out ()
4801a9a3 387{
d6f9b0fb 388 struct cli_interp *cli = (struct cli_interp *) this;
8322445e
PA
389
390 return cli->cli_uiout;
391}
392
616268b6
PA
393/* These hold the pushed copies of the gdb output files.
394 If NULL then nothing has yet been pushed. */
395struct saved_output_files
396{
397 ui_file *out;
398 ui_file *err;
399 ui_file *log;
400 ui_file *targ;
401 ui_file *targerr;
402};
403static saved_output_files saved_output;
404
405/* See cli-interp.h. */
406
407void
d6f9b0fb 408cli_interp_base::set_logging (ui_file_up logfile, bool logging_redirect)
616268b6
PA
409{
410 if (logfile != NULL)
411 {
412 saved_output.out = gdb_stdout;
413 saved_output.err = gdb_stderr;
414 saved_output.log = gdb_stdlog;
415 saved_output.targ = gdb_stdtarg;
416 saved_output.targerr = gdb_stdtargerr;
417
418 /* A raw pointer since ownership is transferred to
419 gdb_stdout. */
420 ui_file *output = make_logging_output (gdb_stdout,
421 std::move (logfile),
422 logging_redirect);
423 gdb_stdout = output;
424 gdb_stdlog = output;
425 gdb_stderr = output;
426 gdb_stdtarg = output;
427 gdb_stdtargerr = output;
428 }
429 else
430 {
431 /* Only delete one of the files -- they are all set to the same
432 value. */
433 delete gdb_stdout;
434
435 gdb_stdout = saved_output.out;
436 gdb_stderr = saved_output.err;
437 gdb_stdlog = saved_output.log;
438 gdb_stdtarg = saved_output.targ;
439 gdb_stdtargerr = saved_output.targerr;
440
441 saved_output.out = NULL;
442 saved_output.err = NULL;
443 saved_output.log = NULL;
444 saved_output.targ = NULL;
445 saved_output.targerr = NULL;
446 }
447}
448
8322445e
PA
449/* Factory for CLI interpreters. */
450
451static struct interp *
452cli_interp_factory (const char *name)
453{
d6f9b0fb 454 return new cli_interp (name);
4801a9a3 455}
4a8f6654 456
4791eb66 457/* Standard gdb initialization hook. */
b9362cc7 458
4a8f6654
AC
459void
460_initialize_cli_interp (void)
461{
8322445e 462 interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
73ab01a0
PA
463
464 /* If changing this, remember to update tui-interp.c as well. */
76727919
TT
465 gdb::observers::normal_stop.attach (cli_on_normal_stop);
466 gdb::observers::end_stepping_range.attach (cli_on_end_stepping_range);
467 gdb::observers::signal_received.attach (cli_on_signal_received);
468 gdb::observers::signal_exited.attach (cli_on_signal_exited);
469 gdb::observers::exited.attach (cli_on_exited);
470 gdb::observers::no_history.attach (cli_on_no_history);
471 gdb::observers::sync_execution_done.attach (cli_on_sync_execution_done);
472 gdb::observers::command_error.attach (cli_on_command_error);
473 gdb::observers::user_selected_context_changed.attach
4034d0ff 474 (cli_on_user_selected_context_changed);
4a8f6654 475}
This page took 0.988249 seconds and 4 git commands to generate.