1 /* TUI Interpreter definitions for GDB, the GNU debugger.
3 Copyright (C) 2003-2021 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
21 #include "cli/cli-interp.h"
24 #include "event-top.h"
25 #include "gdbsupport/event-loop.h"
28 #include "tui/tui-data.h"
29 #include "tui/tui-win.h"
31 #include "tui/tui-io.h"
33 #include "observable.h"
34 #include "gdbthread.h"
38 /* Set to true when the TUI mode must be activated when we first start
40 static bool tui_start_enabled
= false;
42 class tui_interp final
: public cli_interp_base
45 explicit tui_interp (const char *name
)
46 : cli_interp_base (name
)
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
;
56 /* Returns the INTERP if the INTERP is a TUI, and returns NULL
60 as_tui_interp (struct interp
*interp
)
62 return dynamic_cast<tui_interp
*> (interp
);
65 /* Cleanup the tui before exiting. */
70 /* Disable the tui. Curses mode is left leaving the screen in a
71 clean state (see endwin()). */
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. */
79 /* Observer for the normal_stop notification. */
82 tui_on_normal_stop (struct bpstats
*bs
, int print_frame
)
87 SWITCH_THRU_ALL_UIS ()
89 struct interp
*interp
= top_level_interpreter ();
90 struct interp
*tui
= as_tui_interp (interp
);
91 struct thread_info
*thread
;
96 thread
= inferior_thread ();
97 if (should_print_stop_to_console (interp
, thread
))
98 print_stop_event (tui
->interp_ui_out ());
102 /* Observer for the signal_received notification. */
105 tui_on_signal_received (enum gdb_signal siggnal
)
107 SWITCH_THRU_ALL_UIS ()
109 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
114 print_signal_received_reason (tui
->interp_ui_out (), siggnal
);
118 /* Observer for the end_stepping_range notification. */
121 tui_on_end_stepping_range (void)
123 SWITCH_THRU_ALL_UIS ()
125 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
130 print_end_stepping_range_reason (tui
->interp_ui_out ());
134 /* Observer for the signal_exited notification. */
137 tui_on_signal_exited (enum gdb_signal siggnal
)
139 SWITCH_THRU_ALL_UIS ()
141 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
146 print_signal_exited_reason (tui
->interp_ui_out (), siggnal
);
150 /* Observer for the exited notification. */
153 tui_on_exited (int exitstatus
)
155 SWITCH_THRU_ALL_UIS ()
157 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
162 print_exited_reason (tui
->interp_ui_out (), exitstatus
);
166 /* Observer for the no_history notification. */
169 tui_on_no_history (void)
171 SWITCH_THRU_ALL_UIS ()
173 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
178 print_no_history_reason (tui
->interp_ui_out ());
182 /* Observer for the sync_execution_done notification. */
185 tui_on_sync_execution_done (void)
187 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
192 display_gdb_prompt (NULL
);
195 /* Observer for the command_error notification. */
198 tui_on_command_error (void)
200 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
205 display_gdb_prompt (NULL
);
208 /* Observer for the user_selected_context_changed notification. */
211 tui_on_user_selected_context_changed (user_selected_what selection
)
213 /* This event is suppressed. */
214 if (cli_suppress_notification
.user_selected_context
)
217 thread_info
*tp
= inferior_ptid
!= null_ptid
? inferior_thread () : NULL
;
219 SWITCH_THRU_ALL_UIS ()
221 struct interp
*tui
= as_tui_interp (top_level_interpreter ());
226 if (selection
& USER_SELECTED_INFERIOR
)
227 print_selected_inferior (tui
->interp_ui_out ());
230 && ((selection
& (USER_SELECTED_THREAD
| USER_SELECTED_FRAME
))))
231 print_selected_thread_frame (tui
->interp_ui_out (), selection
);
236 /* These implement the TUI interpreter. */
239 tui_interp::init (bool top_level
)
241 /* Install exit handler to leave the screen in a good shape. */
244 tui_initialize_io ();
245 tui_initialize_win ();
246 if (gdb_stdout
->isatty ())
247 tui_ensure_readline_initialized ();
250 /* Used as the command handler for the tui. */
253 tui_command_line_handler (gdb::unique_xmalloc_ptr
<char> &&rl
)
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.
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
265 tui_inject_newline_into_command_window ();
267 /* Now perform GDB's standard CLI command line handling. */
268 command_line_handler (std::move (rl
));
272 tui_interp::resume ()
274 struct ui
*ui
= current_ui
;
275 struct ui_file
*stream
;
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. */
281 stream
= tui_old_uiout
->set_stream (gdb_stdout
);
282 if (stream
!= gdb_stdout
)
284 tui_old_uiout
->set_stream (stream
);
288 gdb_setup_readline (1);
290 ui
->input_handler
= tui_command_line_handler
;
293 tui_old_uiout
->set_stream (gdb_stdout
);
295 if (tui_start_enabled
)
300 tui_interp::suspend ()
302 tui_start_enabled
= tui_active
;
307 tui_interp::interp_ui_out ()
312 return tui_old_uiout
;
316 tui_interp::exec (const char *command_str
)
318 internal_error (__FILE__
, __LINE__
, _("tui_exec called"));
322 /* Factory for TUI interpreters. */
324 static struct interp
*
325 tui_interp_factory (const char *name
)
327 return new tui_interp (name
);
330 void _initialize_tui_interp ();
332 _initialize_tui_interp ()
334 interp_factory_register (INTERP_TUI
, tui_interp_factory
);
336 if (interpreter_p
&& strcmp (interpreter_p
, INTERP_TUI
) == 0)
337 tui_start_enabled
= true;
339 if (interpreter_p
&& strcmp (interpreter_p
, INTERP_CONSOLE
) == 0)
341 xfree (interpreter_p
);
342 interpreter_p
= xstrdup (INTERP_TUI
);
345 /* If changing this, remember to update cli-interp.c as well. */
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
,
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
,
355 gdb::observers::command_error
.attach (tui_on_command_error
, "tui-interp");
356 gdb::observers::user_selected_context_changed
.attach
357 (tui_on_user_selected_context_changed
, "tui-interp");