X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui-hooks.c;h=2555da7f1ae2916070cb0edeede6142c2414dd23;hb=7226433c44e3792aeea6ad19c54cd3056ea4308e;hp=6ba6285b44f2eeb78ede0d3170ad8c01cef9fdf5;hpb=32d0add0a654c1204ab71dc8a55d9374538c4b33;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c index 6ba6285b44..2555da7f1a 100644 --- a/gdb/tui/tui-hooks.c +++ b/gdb/tui/tui-hooks.c @@ -1,6 +1,6 @@ /* GDB hooks for TUI. - Copyright (C) 2001-2015 Free Software Foundation, Inc. + Copyright (C) 2001-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -32,7 +32,8 @@ #include "breakpoint.h" #include "ui-out.h" #include "top.h" -#include "observer.h" +#include "observable.h" +#include "source.h" #include #include @@ -44,7 +45,6 @@ #include "tui/tui-regs.h" #include "tui/tui-win.h" #include "tui/tui-stack.h" -#include "tui/tui-windata.h" #include "tui/tui-winsource.h" #include "gdb_curses.h" @@ -54,8 +54,6 @@ "gdb_curses.h". */ #include "readline/readline.h" -int tui_target_has_run = 0; - static void tui_new_objfile_hook (struct objfile* objfile) { @@ -63,81 +61,29 @@ tui_new_objfile_hook (struct objfile* objfile) tui_display_main (); } -static int ATTRIBUTE_PRINTF (1, 0) -tui_query_hook (const char *msg, va_list argp) -{ - int retval; - int ans2; - int answer; - char *question; - struct cleanup *old_chain; - - /* Format the question outside of the loop, to avoid reusing - ARGP. */ - question = xstrvprintf (msg, argp); - old_chain = make_cleanup (xfree, question); - - echo (); - while (1) - { - wrap_here (""); /* Flush any buffered output. */ - gdb_flush (gdb_stdout); - - fputs_filtered (question, gdb_stdout); - printf_filtered (_("(y or n) ")); - - wrap_here (""); - gdb_flush (gdb_stdout); - - answer = tui_getc (stdin); - clearerr (stdin); /* in case of C-d */ - if (answer == EOF) /* C-d */ - { - retval = 1; - break; - } - /* Eat rest of input line, to EOF or newline. */ - if (answer != '\n') - do - { - ans2 = tui_getc (stdin); - clearerr (stdin); - } - while (ans2 != EOF && ans2 != '\n' && ans2 != '\r'); - - if (answer >= 'a') - answer -= 040; - if (answer == 'Y') - { - retval = 1; - break; - } - if (answer == 'N') - { - retval = 0; - break; - } - printf_filtered (_("Please answer y or n.\n")); - } - noecho (); - - do_cleanups (old_chain); - return retval; -} - /* Prevent recursion of deprecated_register_changed_hook(). */ static int tui_refreshing_registers = 0; +/* Observer for the register_changed notification. */ + static void -tui_register_changed_hook (int regno) +tui_register_changed (struct frame_info *frame, int regno) { struct frame_info *fi; + if (!tui_is_window_visible (DATA_WIN)) + return; + + /* The frame of the register that was changed may differ from the selected + frame, but we only want to show the register values of the selected frame. + And even if the frames differ a register change made in one can still show + up in the other. So we always use the selected frame here, and ignore + FRAME. */ fi = get_selected_frame (NULL); if (tui_refreshing_registers == 0) { tui_refreshing_registers = 1; - tui_check_data_values (fi); + TUI_DATA_WIN->check_register_values (fi); tui_refreshing_registers = 0; } } @@ -147,7 +93,7 @@ tui_register_changed_hook (int regno) static void tui_event_create_breakpoint (struct breakpoint *b) { - tui_update_all_breakpoint_info (); + tui_update_all_breakpoint_info (nullptr); } /* Breakpoint deletion hook. @@ -155,45 +101,34 @@ tui_event_create_breakpoint (struct breakpoint *b) static void tui_event_delete_breakpoint (struct breakpoint *b) { - tui_update_all_breakpoint_info (); + tui_update_all_breakpoint_info (b); } static void tui_event_modify_breakpoint (struct breakpoint *b) { - tui_update_all_breakpoint_info (); + tui_update_all_breakpoint_info (nullptr); } -/* Called when a command is about to proceed the inferior. */ +/* Refresh TUI's frame and register information. This is a hook intended to be + used to update the screen after potential frame and register changes. -static void -tui_about_to_proceed (void) -{ - /* Leave tui mode (optional). */ -#if 0 - if (tui_active) - { - target_terminal_ours (); - endwin (); - target_terminal_inferior (); - } -#endif - tui_target_has_run = 1; -} + REGISTERS_TOO_P controls whether to refresh our register information even + if frame information hasn't changed. */ -/* The selected frame has changed. This is happens after a target - stop or when the user explicitly changes the frame - (up/down/thread/...). */ static void -tui_selected_frame_level_changed_hook (int level) +tui_refresh_frame_and_register_information (int registers_too_p) { struct frame_info *fi; CORE_ADDR pc; + int frame_info_changed_p; - /* Negative level means that the selected frame was cleared. */ - if (level < 0) + if (!has_stack_frames ()) return; + target_terminal::scoped_restore_terminal_state term_state; + target_terminal::ours_for_output (); + fi = get_selected_frame (NULL); /* Ensure that symbols for this frame are read in. Also, determine the source language of this frame, and switch to it if @@ -213,26 +148,27 @@ tui_selected_frame_level_changed_hook (int level) /* Display the frame position (even if there is no symbols or the PC is not known). */ - tui_show_frame_info (fi); + frame_info_changed_p = tui_show_frame_info (fi); /* Refresh the register window if it's visible. */ - if (tui_is_window_visible (DATA_WIN)) + if (tui_is_window_visible (DATA_WIN) + && (frame_info_changed_p || registers_too_p)) { tui_refreshing_registers = 1; - tui_check_data_values (fi); + TUI_DATA_WIN->check_register_values (fi); tui_refreshing_registers = 0; } } -/* Called from print_frame_info to list the line we stopped in. */ +/* Dummy callback for deprecated_print_frame_info_listing_hook which is called + from print_frame_info. */ + static void -tui_print_frame_info_listing_hook (struct symtab *s, - int line, - int stopline, - int noerror) +tui_dummy_print_frame_info_listing_hook (struct symtab *s, + int line, + int stopline, + int noerror) { - select_source_symtab (s); - tui_show_frame_info (get_selected_frame (NULL)); } /* Perform all necessary cleanups regarding our module's inferior data @@ -247,66 +183,94 @@ tui_inferior_exit (struct inferior *inf) tui_display_main (); } -/* Observers created when installing TUI hooks. */ -static struct observer *tui_bp_created_observer; -static struct observer *tui_bp_deleted_observer; -static struct observer *tui_bp_modified_observer; -static struct observer *tui_inferior_exit_observer; -static struct observer *tui_about_to_proceed_observer; +/* Observer for the before_prompt notification. */ + +static void +tui_before_prompt (const char *current_gdb_prompt) +{ + /* This refresh is intended to catch changes to the selected frame following + a call to "up", "down" or "frame". As such we don't necessarily want to + refresh registers here unless the frame actually changed by one of these + commands. Registers will otherwise be refreshed after a normal stop or by + our tui_register_changed_hook. */ + tui_refresh_frame_and_register_information (/*registers_too_p=*/0); +} + +/* Observer for the normal_stop notification. */ + +static void +tui_normal_stop (struct bpstats *bs, int print_frame) +{ + /* This refresh is intended to catch changes to the selected frame and to + registers following a normal stop. */ + tui_refresh_frame_and_register_information (/*registers_too_p=*/1); +} + +/* Token associated with observers registered while TUI hooks are + installed. */ +static const gdb::observers::token tui_observers_token {}; + +/* Attach or detach a single observer, according to ATTACH. */ + +template +static void +attach_or_detach (T &observable, typename T::func_type func, bool attach) +{ + if (attach) + observable.attach (func, tui_observers_token); + else + observable.detach (tui_observers_token); +} + +/* Attach or detach TUI observers, according to ATTACH. */ + +static void +tui_attach_detach_observers (bool attach) +{ + attach_or_detach (gdb::observers::breakpoint_created, + tui_event_create_breakpoint, attach); + attach_or_detach (gdb::observers::breakpoint_deleted, + tui_event_delete_breakpoint, attach); + attach_or_detach (gdb::observers::breakpoint_modified, + tui_event_modify_breakpoint, attach); + attach_or_detach (gdb::observers::inferior_exit, + tui_inferior_exit, attach); + attach_or_detach (gdb::observers::before_prompt, + tui_before_prompt, attach); + attach_or_detach (gdb::observers::normal_stop, + tui_normal_stop, attach); + attach_or_detach (gdb::observers::register_changed, + tui_register_changed, attach); +} /* Install the TUI specific hooks. */ void tui_install_hooks (void) { - deprecated_selected_frame_level_changed_hook - = tui_selected_frame_level_changed_hook; + /* If this hook is not set to something then print_frame_info will + assume that the CLI, not the TUI, is active, and will print the frame info + for us in such a way that we are not prepared to handle. This hook is + otherwise effectively obsolete. */ deprecated_print_frame_info_listing_hook - = tui_print_frame_info_listing_hook; - - deprecated_query_hook = tui_query_hook; + = tui_dummy_print_frame_info_listing_hook; /* Install the event hooks. */ - tui_bp_created_observer - = observer_attach_breakpoint_created (tui_event_create_breakpoint); - tui_bp_deleted_observer - = observer_attach_breakpoint_deleted (tui_event_delete_breakpoint); - tui_bp_modified_observer - = observer_attach_breakpoint_modified (tui_event_modify_breakpoint); - tui_inferior_exit_observer - = observer_attach_inferior_exit (tui_inferior_exit); - tui_about_to_proceed_observer - = observer_attach_about_to_proceed (tui_about_to_proceed); - - deprecated_register_changed_hook = tui_register_changed_hook; + tui_attach_detach_observers (true); } /* Remove the TUI specific hooks. */ void tui_remove_hooks (void) { - deprecated_selected_frame_level_changed_hook = 0; deprecated_print_frame_info_listing_hook = 0; - deprecated_query_hook = 0; - deprecated_register_changed_hook = 0; /* Remove our observers. */ - observer_detach_breakpoint_created (tui_bp_created_observer); - tui_bp_created_observer = NULL; - observer_detach_breakpoint_deleted (tui_bp_deleted_observer); - tui_bp_deleted_observer = NULL; - observer_detach_breakpoint_modified (tui_bp_modified_observer); - tui_bp_modified_observer = NULL; - observer_detach_inferior_exit (tui_inferior_exit_observer); - tui_inferior_exit_observer = NULL; - observer_detach_about_to_proceed (tui_about_to_proceed_observer); - tui_about_to_proceed_observer = NULL; + tui_attach_detach_observers (false); } -void _initialize_tui_hooks (void); - void _initialize_tui_hooks (void) { /* Install the permanent hooks. */ - observer_attach_new_objfile (tui_new_objfile_hook); + gdb::observers::new_objfile.attach (tui_new_objfile_hook); }