gdb/copyright.py: Convert to Python 3
[deliverable/binutils-gdb.git] / gdb / tui / tui-interp.c
... / ...
CommitLineData
1/* TUI Interpreter definitions for GDB, the GNU debugger.
2
3 Copyright (C) 2003-2019 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/cli-interp.h"
22#include "interps.h"
23#include "top.h"
24#include "event-top.h"
25#include "event-loop.h"
26#include "ui-out.h"
27#include "cli-out.h"
28#include "tui/tui-data.h"
29#include "tui/tui-win.h"
30#include "tui/tui.h"
31#include "tui/tui-io.h"
32#include "infrun.h"
33#include "observable.h"
34#include "gdbthread.h"
35#include "inferior.h"
36#include "main.h"
37
38/* Set to true when the TUI mode must be activated when we first start
39 gdb. */
40static bool tui_start_enabled = false;
41
42class tui_interp final : public cli_interp_base
43{
44public:
45 explicit tui_interp (const char *name)
46 : cli_interp_base (name)
47 {}
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};
55
56/* Returns the INTERP if the INTERP is a TUI, and returns NULL
57 otherwise. */
58
59static tui_interp *
60as_tui_interp (struct interp *interp)
61{
62 return dynamic_cast<tui_interp *> (interp);
63}
64
65/* Cleanup the tui before exiting. */
66
67static void
68tui_exit (void)
69{
70 /* Disable the tui. Curses mode is left leaving the screen in a
71 clean state (see endwin()). */
72 tui_disable ();
73}
74
75/* Observers for several run control events. If the interpreter is
76 quiet (i.e., another interpreter is being run with
77 interpreter-exec), print nothing. */
78
79/* Observer for the normal_stop notification. */
80
81static void
82tui_on_normal_stop (struct bpstats *bs, int print_frame)
83{
84 if (!print_frame)
85 return;
86
87 SWITCH_THRU_ALL_UIS ()
88 {
89 struct interp *interp = top_level_interpreter ();
90 struct interp *tui = as_tui_interp (interp);
91 struct thread_info *thread;
92
93 if (tui == NULL)
94 continue;
95
96 thread = inferior_thread ();
97 if (should_print_stop_to_console (interp, thread))
98 print_stop_event (tui->interp_ui_out ());
99 }
100}
101
102/* Observer for the signal_received notification. */
103
104static void
105tui_on_signal_received (enum gdb_signal siggnal)
106{
107 SWITCH_THRU_ALL_UIS ()
108 {
109 struct interp *tui = as_tui_interp (top_level_interpreter ());
110
111 if (tui == NULL)
112 continue;
113
114 print_signal_received_reason (tui->interp_ui_out (), siggnal);
115 }
116}
117
118/* Observer for the end_stepping_range notification. */
119
120static void
121tui_on_end_stepping_range (void)
122{
123 SWITCH_THRU_ALL_UIS ()
124 {
125 struct interp *tui = as_tui_interp (top_level_interpreter ());
126
127 if (tui == NULL)
128 continue;
129
130 print_end_stepping_range_reason (tui->interp_ui_out ());
131 }
132}
133
134/* Observer for the signal_exited notification. */
135
136static void
137tui_on_signal_exited (enum gdb_signal siggnal)
138{
139 SWITCH_THRU_ALL_UIS ()
140 {
141 struct interp *tui = as_tui_interp (top_level_interpreter ());
142
143 if (tui == NULL)
144 continue;
145
146 print_signal_exited_reason (tui->interp_ui_out (), siggnal);
147 }
148}
149
150/* Observer for the exited notification. */
151
152static void
153tui_on_exited (int exitstatus)
154{
155 SWITCH_THRU_ALL_UIS ()
156 {
157 struct interp *tui = as_tui_interp (top_level_interpreter ());
158
159 if (tui == NULL)
160 continue;
161
162 print_exited_reason (tui->interp_ui_out (), exitstatus);
163 }
164}
165
166/* Observer for the no_history notification. */
167
168static void
169tui_on_no_history (void)
170{
171 SWITCH_THRU_ALL_UIS ()
172 {
173 struct interp *tui = as_tui_interp (top_level_interpreter ());
174
175 if (tui == NULL)
176 continue;
177
178 print_no_history_reason (tui->interp_ui_out ());
179 }
180}
181
182/* Observer for the sync_execution_done notification. */
183
184static void
185tui_on_sync_execution_done (void)
186{
187 struct interp *tui = as_tui_interp (top_level_interpreter ());
188
189 if (tui == NULL)
190 return;
191
192 display_gdb_prompt (NULL);
193}
194
195/* Observer for the command_error notification. */
196
197static void
198tui_on_command_error (void)
199{
200 struct interp *tui = as_tui_interp (top_level_interpreter ());
201
202 if (tui == NULL)
203 return;
204
205 display_gdb_prompt (NULL);
206}
207
208/* Observer for the user_selected_context_changed notification. */
209
210static void
211tui_on_user_selected_context_changed (user_selected_what selection)
212{
213 /* This event is suppressed. */
214 if (cli_suppress_notification.user_selected_context)
215 return;
216
217 thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : NULL;
218
219 SWITCH_THRU_ALL_UIS ()
220 {
221 struct interp *tui = as_tui_interp (top_level_interpreter ());
222
223 if (tui == NULL)
224 continue;
225
226 if (selection & USER_SELECTED_INFERIOR)
227 print_selected_inferior (tui->interp_ui_out ());
228
229 if (tp != NULL
230 && ((selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME))))
231 print_selected_thread_frame (tui->interp_ui_out (), selection);
232
233 }
234}
235
236/* These implement the TUI interpreter. */
237
238void
239tui_interp::init (bool top_level)
240{
241 /* Install exit handler to leave the screen in a good shape. */
242 atexit (tui_exit);
243
244 tui_initialize_io ();
245 tui_initialize_win ();
246 if (ui_file_isatty (gdb_stdout))
247 tui_initialize_readline ();
248}
249
250void
251tui_interp::resume ()
252{
253 struct ui *ui = current_ui;
254 struct ui_file *stream;
255
256 /* gdb_setup_readline will change gdb_stdout. If the TUI was
257 previously writing to gdb_stdout, then set it to the new
258 gdb_stdout afterwards. */
259
260 stream = tui_old_uiout->set_stream (gdb_stdout);
261 if (stream != gdb_stdout)
262 {
263 tui_old_uiout->set_stream (stream);
264 stream = NULL;
265 }
266
267 gdb_setup_readline (1);
268
269 ui->input_handler = command_line_handler;
270
271 if (stream != NULL)
272 tui_old_uiout->set_stream (gdb_stdout);
273
274 if (tui_start_enabled)
275 tui_enable ();
276}
277
278void
279tui_interp::suspend ()
280{
281 tui_start_enabled = tui_active;
282 tui_disable ();
283}
284
285ui_out *
286tui_interp::interp_ui_out ()
287{
288 if (tui_active)
289 return tui_out;
290 else
291 return tui_old_uiout;
292}
293
294gdb_exception
295tui_interp::exec (const char *command_str)
296{
297 internal_error (__FILE__, __LINE__, _("tui_exec called"));
298}
299
300
301/* Factory for TUI interpreters. */
302
303static struct interp *
304tui_interp_factory (const char *name)
305{
306 return new tui_interp (name);
307}
308
309void
310_initialize_tui_interp (void)
311{
312 interp_factory_register (INTERP_TUI, tui_interp_factory);
313
314 if (interpreter_p && strcmp (interpreter_p, INTERP_TUI) == 0)
315 tui_start_enabled = true;
316
317 if (interpreter_p && strcmp (interpreter_p, INTERP_CONSOLE) == 0)
318 {
319 xfree (interpreter_p);
320 interpreter_p = xstrdup (INTERP_TUI);
321 }
322
323 /* If changing this, remember to update cli-interp.c as well. */
324 gdb::observers::normal_stop.attach (tui_on_normal_stop);
325 gdb::observers::signal_received.attach (tui_on_signal_received);
326 gdb::observers::end_stepping_range.attach (tui_on_end_stepping_range);
327 gdb::observers::signal_exited.attach (tui_on_signal_exited);
328 gdb::observers::exited.attach (tui_on_exited);
329 gdb::observers::no_history.attach (tui_on_no_history);
330 gdb::observers::sync_execution_done.attach (tui_on_sync_execution_done);
331 gdb::observers::command_error.attach (tui_on_command_error);
332 gdb::observers::user_selected_context_changed.attach
333 (tui_on_user_selected_context_changed);
334}
This page took 0.088293 seconds and 4 git commands to generate.