Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / tui / tui-interp.c
CommitLineData
021e7609
AC
1/* TUI Interpreter definitions for GDB, the GNU debugger.
2
88b9d363 3 Copyright (C) 2003-2022 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"
400b5eca 25#include "gdbsupport/event-loop.h"
021e7609 26#include "ui-out.h"
95cd630e 27#include "cli-out.h"
d7b2e967 28#include "tui/tui-data.h"
d7b2e967 29#include "tui/tui-win.h"
021e7609 30#include "tui/tui.h"
d7b2e967 31#include "tui/tui-io.h"
fd664c91 32#include "infrun.h"
76727919 33#include "observable.h"
eaae60fd 34#include "gdbthread.h"
00431a78 35#include "inferior.h"
b0be6c91 36#include "main.h"
fd664c91 37
87d557ae 38/* Set to true when the TUI mode must be activated when we first start
1cc6d956 39 gdb. */
87d557ae 40static bool tui_start_enabled = false;
63858210 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
021e7609 244 tui_initialize_io ();
9612b5ec 245 tui_initialize_win ();
da5bd37e 246 if (gdb_stdout->isatty ())
a350efd4 247 tui_ensure_readline_initialized ();
021e7609
AC
248}
249
cd074e04
AB
250/* Used as the command handler for the tui. */
251
252static void
253tui_command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
254{
255 /* When a tui enabled GDB is running in either tui mode or cli mode then
256 it is always the tui interpreter that is in use. As a result we end
257 up in here even in standard cli mode.
258
259 We only need to do any special actions when the tui is in use
260 though. When the tui is active the users return is not echoed to the
261 screen as a result the display will not automatically move us to the
262 next line. Here we manually insert a newline character and move the
263 cursor. */
264 if (tui_active)
265 tui_inject_newline_into_command_window ();
266
267 /* Now perform GDB's standard CLI command line handling. */
268 command_line_handler (std::move (rl));
269}
270
d6f9b0fb
PA
271void
272tui_interp::resume ()
021e7609 273{
3c216924 274 struct ui *ui = current_ui;
95cd630e
DJ
275 struct ui_file *stream;
276
1cc6d956
MS
277 /* gdb_setup_readline will change gdb_stdout. If the TUI was
278 previously writing to gdb_stdout, then set it to the new
279 gdb_stdout afterwards. */
95cd630e 280
112e8700 281 stream = tui_old_uiout->set_stream (gdb_stdout);
95cd630e
DJ
282 if (stream != gdb_stdout)
283 {
112e8700 284 tui_old_uiout->set_stream (stream);
95cd630e
DJ
285 stream = NULL;
286 }
287
3c216924
PA
288 gdb_setup_readline (1);
289
cd074e04 290 ui->input_handler = tui_command_line_handler;
95cd630e
DJ
291
292 if (stream != NULL)
112e8700 293 tui_old_uiout->set_stream (gdb_stdout);
95cd630e 294
63858210
SC
295 if (tui_start_enabled)
296 tui_enable ();
021e7609
AC
297}
298
d6f9b0fb
PA
299void
300tui_interp::suspend ()
021e7609 301{
63858210 302 tui_start_enabled = tui_active;
021e7609 303 tui_disable ();
021e7609
AC
304}
305
d6f9b0fb
PA
306ui_out *
307tui_interp::interp_ui_out ()
4801a9a3
PA
308{
309 if (tui_active)
310 return tui_out;
311 else
312 return tui_old_uiout;
313}
314
d6f9b0fb
PA
315gdb_exception
316tui_interp::exec (const char *command_str)
021e7609 317{
e2e0b3e5 318 internal_error (__FILE__, __LINE__, _("tui_exec called"));
021e7609
AC
319}
320
8322445e
PA
321
322/* Factory for TUI interpreters. */
323
324static struct interp *
325tui_interp_factory (const char *name)
326{
d6f9b0fb 327 return new tui_interp (name);
8322445e
PA
328}
329
6c265988 330void _initialize_tui_interp ();
021e7609 331void
6c265988 332_initialize_tui_interp ()
021e7609 333{
8322445e
PA
334 interp_factory_register (INTERP_TUI, tui_interp_factory);
335
cc4349ed 336 if (interpreter_p && strcmp (interpreter_p, INTERP_TUI) == 0)
87d557ae 337 tui_start_enabled = true;
63858210
SC
338
339 if (interpreter_p && strcmp (interpreter_p, INTERP_CONSOLE) == 0)
340 {
341 xfree (interpreter_p);
cc4349ed 342 interpreter_p = xstrdup (INTERP_TUI);
63858210 343 }
73ab01a0
PA
344
345 /* If changing this, remember to update cli-interp.c as well. */
c90e7d63
SM
346 gdb::observers::normal_stop.attach (tui_on_normal_stop, "tui-interp");
347 gdb::observers::signal_received.attach (tui_on_signal_received, "tui-interp");
348 gdb::observers::end_stepping_range.attach (tui_on_end_stepping_range,
349 "tui-interp");
350 gdb::observers::signal_exited.attach (tui_on_signal_exited, "tui-interp");
351 gdb::observers::exited.attach (tui_on_exited, "tui-interp");
352 gdb::observers::no_history.attach (tui_on_no_history, "tui-interp");
353 gdb::observers::sync_execution_done.attach (tui_on_sync_execution_done,
354 "tui-interp");
355 gdb::observers::command_error.attach (tui_on_command_error, "tui-interp");
76727919 356 gdb::observers::user_selected_context_changed.attach
c90e7d63 357 (tui_on_user_selected_context_changed, "tui-interp");
021e7609 358}
This page took 2.15025 seconds and 4 git commands to generate.