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