Move "tee" building down to interpreter::set_logging_proc
[external/binutils.git] / gdb / cli / cli-interp.c
1 /* CLI Definitions for GDB, the GNU debugger.
2
3    Copyright (C) 2002-2017 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 /* These hold the pushed copies of the gdb output files.
377    If NULL then nothing has yet been pushed.  */
378 struct saved_output_files
379 {
380   ui_file *out;
381   ui_file *err;
382   ui_file *log;
383   ui_file *targ;
384   ui_file *targerr;
385 };
386 static saved_output_files saved_output;
387
388 /* See cli-interp.h.  */
389
390 void
391 cli_set_logging (struct interp *interp,
392                  ui_file_up logfile, bool logging_redirect)
393 {
394   if (logfile != NULL)
395     {
396       saved_output.out = gdb_stdout;
397       saved_output.err = gdb_stderr;
398       saved_output.log = gdb_stdlog;
399       saved_output.targ = gdb_stdtarg;
400       saved_output.targerr = gdb_stdtargerr;
401
402       /* A raw pointer since ownership is transferred to
403          gdb_stdout.  */
404       ui_file *output = make_logging_output (gdb_stdout,
405                                              std::move (logfile),
406                                              logging_redirect);
407       gdb_stdout = output;
408       gdb_stdlog = output;
409       gdb_stderr = output;
410       gdb_stdtarg = output;
411       gdb_stdtargerr = output;
412     }
413   else
414     {
415       /* Only delete one of the files -- they are all set to the same
416          value.  */
417       delete gdb_stdout;
418
419       gdb_stdout = saved_output.out;
420       gdb_stderr = saved_output.err;
421       gdb_stdlog = saved_output.log;
422       gdb_stdtarg = saved_output.targ;
423       gdb_stdtargerr = saved_output.targerr;
424
425       saved_output.out = NULL;
426       saved_output.err = NULL;
427       saved_output.log = NULL;
428       saved_output.targ = NULL;
429       saved_output.targerr = NULL;
430     }
431 }
432
433 /* The CLI interpreter's vtable.  */
434
435 static const struct interp_procs cli_interp_procs = {
436   cli_interpreter_init,         /* init_proc */
437   cli_interpreter_resume,       /* resume_proc */
438   cli_interpreter_suspend,      /* suspend_proc */
439   cli_interpreter_exec,         /* exec_proc */
440   cli_ui_out,                   /* ui_out_proc */
441   cli_set_logging,              /* set_logging_proc */
442   cli_interpreter_pre_command_loop, /* pre_command_loop_proc */
443   cli_interpreter_supports_command_editing, /* supports_command_editing_proc */
444 };
445
446 /* Factory for CLI interpreters.  */
447
448 static struct interp *
449 cli_interp_factory (const char *name)
450 {
451   struct cli_interp *cli = XNEW (struct cli_interp);
452
453   /* Create a default uiout builder for the CLI.  */
454   cli->cli_uiout = cli_out_new (gdb_stdout);
455
456   return interp_new (name, &cli_interp_procs, cli);
457 }
458
459 /* Standard gdb initialization hook.  */
460 extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
461
462 void
463 _initialize_cli_interp (void)
464 {
465   interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
466
467   /* If changing this, remember to update tui-interp.c as well.  */
468   observer_attach_normal_stop (cli_on_normal_stop);
469   observer_attach_end_stepping_range (cli_on_end_stepping_range);
470   observer_attach_signal_received (cli_on_signal_received);
471   observer_attach_signal_exited (cli_on_signal_exited);
472   observer_attach_exited (cli_on_exited);
473   observer_attach_no_history (cli_on_no_history);
474   observer_attach_sync_execution_done (cli_on_sync_execution_done);
475   observer_attach_command_error (cli_on_command_error);
476   observer_attach_user_selected_context_changed
477     (cli_on_user_selected_context_changed);
478 }