diff options
Diffstat (limited to 'gdb/tui/tui-hooks.c')
-rw-r--r-- | gdb/tui/tui-hooks.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c index 35d7ce8..3beca39 100644 --- a/gdb/tui/tui-hooks.c +++ b/gdb/tui/tui-hooks.c @@ -46,9 +46,13 @@ #include "target.h" #include "gdbcore.h" #include "event-loop.h" +#include "event-top.h" #include "frame.h" #include "breakpoint.h" #include "gdb-events.h" +#include "ui-out.h" +#include "top.h" +#include <readline/readline.h> #include <unistd.h> #include <fcntl.h> @@ -66,6 +70,8 @@ int tui_target_has_run = 0; static void (* tui_target_new_objfile_chain) (struct objfile*); extern void (*selected_frame_level_changed_hook) (int); +static void tui_event_loop (void); +static void tui_command_loop (void); static void tui_new_objfile_hook (struct objfile* objfile) @@ -329,6 +335,86 @@ tui_exit (void) tui_disable (); } +/* Initialize all the necessary variables, start the event loop, + register readline, and stdin, start the loop. */ +static void +tui_command_loop (void) +{ + int length; + char *a_prompt; + char *gdb_prompt = get_prompt (); + + /* If we are using readline, set things up and display the first + prompt, otherwise just print the prompt. */ + if (async_command_editing_p) + { + /* Tell readline what the prompt to display is and what function it + will need to call after a whole line is read. This also displays + the first prompt. */ + length = strlen (PREFIX (0)) + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1; + a_prompt = (char *) xmalloc (length); + strcpy (a_prompt, PREFIX (0)); + strcat (a_prompt, gdb_prompt); + strcat (a_prompt, SUFFIX (0)); + rl_callback_handler_install (a_prompt, input_handler); + } + else + display_gdb_prompt (0); + + /* Now it's time to start the event loop. */ + tui_event_loop (); +} + +/* Start up the event loop. This is the entry point to the event loop + from the command loop. */ + +static void +tui_event_loop (void) +{ + /* Loop until there is nothing to do. This is the entry point to the + event loop engine. gdb_do_one_event, called via catch_errors() + will process one event for each invocation. It blocks waits for + an event and then processes it. >0 when an event is processed, 0 + when catch_errors() caught an error and <0 when there are no + longer any event sources registered. */ + while (1) + { + int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); + if (result < 0) + break; + + /* Update gdb output according to TUI mode. Since catch_errors + preserves the uiout from changing, this must be done at top + level of event loop. */ + if (tui_active) + uiout = tui_out; + else + uiout = tui_old_uiout; + + if (result == 0) + { + /* FIXME: this should really be a call to a hook that is + interface specific, because interfaces can display the + prompt in their own way. */ + display_gdb_prompt (0); + /* This call looks bizarre, but it is required. If the user + entered a command that caused an error, + after_char_processing_hook won't be called from + rl_callback_read_char_wrapper. Using a cleanup there + won't work, since we want this function to be called + after a new prompt is printed. */ + if (after_char_processing_hook) + (*after_char_processing_hook) (); + /* Maybe better to set a flag to be checked somewhere as to + whether display the prompt or not. */ + } + } + + /* We are done with the event loop. There are no more event sources + to listen to. So we exit GDB. */ + return; +} + /* Initialize the tui by installing several gdb hooks, initializing the tui IO and preparing the readline with the kind binding. */ static void @@ -346,6 +432,9 @@ tui_init_hook (char *argv0) tui_initialize_io (); tui_initialize_readline (); + /* Tell gdb to use the tui_command_loop as the main loop. */ + command_loop_hook = tui_command_loop; + /* Decide in which mode to start using GDB (based on -tui). */ if (tui_version) { |