GDB (API)
/home/stan/gdb/src/gdb/tui/tui-hooks.c
Go to the documentation of this file.
00001 /* GDB hooks for TUI.
00002 
00003    Copyright (C) 2001-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "symtab.h"
00022 #include "inferior.h"
00023 #include "command.h"
00024 #include "bfd.h"
00025 #include "symfile.h"
00026 #include "objfiles.h"
00027 #include "target.h"
00028 #include "gdbcore.h"
00029 #include "event-loop.h"
00030 #include "event-top.h"
00031 #include "frame.h"
00032 #include "breakpoint.h"
00033 #include "ui-out.h"
00034 #include "top.h"
00035 #include "observer.h"
00036 #include <unistd.h>
00037 #include <fcntl.h>
00038 
00039 #include "tui/tui.h"
00040 #include "tui/tui-hooks.h"
00041 #include "tui/tui-data.h"
00042 #include "tui/tui-layout.h"
00043 #include "tui/tui-io.h"
00044 #include "tui/tui-regs.h"
00045 #include "tui/tui-win.h"
00046 #include "tui/tui-stack.h"
00047 #include "tui/tui-windata.h"
00048 #include "tui/tui-winsource.h"
00049 
00050 #include "gdb_curses.h"
00051 
00052 /* This redefines CTRL if it is not already defined, so it must come
00053    after terminal state releated include files like <term.h> and
00054    "gdb_curses.h".  */
00055 #include "readline/readline.h"
00056 
00057 int tui_target_has_run = 0;
00058 
00059 static void
00060 tui_new_objfile_hook (struct objfile* objfile)
00061 {
00062   if (tui_active)
00063     tui_display_main ();
00064 }
00065 
00066 static int ATTRIBUTE_PRINTF (1, 0)
00067 tui_query_hook (const char *msg, va_list argp)
00068 {
00069   int retval;
00070   int ans2;
00071   int answer;
00072   char *question;
00073   struct cleanup *old_chain;
00074 
00075   /* Format the question outside of the loop, to avoid reusing
00076      ARGP.  */
00077   question = xstrvprintf (msg, argp);
00078   old_chain = make_cleanup (xfree, question);
00079 
00080   echo ();
00081   while (1)
00082     {
00083       wrap_here ("");           /* Flush any buffered output.  */
00084       gdb_flush (gdb_stdout);
00085 
00086       fputs_filtered (question, gdb_stdout);
00087       printf_filtered (_("(y or n) "));
00088 
00089       wrap_here ("");
00090       gdb_flush (gdb_stdout);
00091 
00092       answer = tui_getc (stdin);
00093       clearerr (stdin);         /* in case of C-d */
00094       if (answer == EOF)        /* C-d */
00095         {
00096           retval = 1;
00097           break;
00098         }
00099       /* Eat rest of input line, to EOF or newline.  */
00100       if (answer != '\n')
00101         do
00102           {
00103             ans2 = tui_getc (stdin);
00104             clearerr (stdin);
00105           }
00106         while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
00107 
00108       if (answer >= 'a')
00109         answer -= 040;
00110       if (answer == 'Y')
00111         {
00112           retval = 1;
00113           break;
00114         }
00115       if (answer == 'N')
00116         {
00117           retval = 0;
00118           break;
00119         }
00120       printf_filtered (_("Please answer y or n.\n"));
00121     }
00122   noecho ();
00123 
00124   do_cleanups (old_chain);
00125   return retval;
00126 }
00127 
00128 /* Prevent recursion of deprecated_register_changed_hook().  */
00129 static int tui_refreshing_registers = 0;
00130 
00131 static void
00132 tui_register_changed_hook (int regno)
00133 {
00134   struct frame_info *fi;
00135 
00136   fi = get_selected_frame (NULL);
00137   if (tui_refreshing_registers == 0)
00138     {
00139       tui_refreshing_registers = 1;
00140       tui_check_data_values (fi);
00141       tui_refreshing_registers = 0;
00142     }
00143 }
00144 
00145 /* Breakpoint creation hook.
00146    Update the screen to show the new breakpoint.  */
00147 static void
00148 tui_event_create_breakpoint (struct breakpoint *b)
00149 {
00150   tui_update_all_breakpoint_info ();
00151 }
00152 
00153 /* Breakpoint deletion hook.
00154    Refresh the screen to update the breakpoint marks.  */
00155 static void
00156 tui_event_delete_breakpoint (struct breakpoint *b)
00157 {
00158   tui_update_all_breakpoint_info ();
00159 }
00160 
00161 static void
00162 tui_event_modify_breakpoint (struct breakpoint *b)
00163 {
00164   tui_update_all_breakpoint_info ();
00165 }
00166 
00167 /* Called when a command is about to proceed the inferior.  */
00168 
00169 static void
00170 tui_about_to_proceed (void)
00171 {
00172   /* Leave tui mode (optional).  */
00173 #if 0
00174   if (tui_active)
00175     {
00176       target_terminal_ours ();
00177       endwin ();
00178       target_terminal_inferior ();
00179     }
00180 #endif
00181   tui_target_has_run = 1;
00182 }
00183 
00184 /* The selected frame has changed.  This is happens after a target
00185    stop or when the user explicitly changes the frame
00186    (up/down/thread/...).  */
00187 static void
00188 tui_selected_frame_level_changed_hook (int level)
00189 {
00190   struct frame_info *fi;
00191   CORE_ADDR pc;
00192 
00193   /* Negative level means that the selected frame was cleared.  */
00194   if (level < 0)
00195     return;
00196 
00197   fi = get_selected_frame (NULL);
00198   /* Ensure that symbols for this frame are read in.  Also, determine
00199      the source language of this frame, and switch to it if
00200      desired.  */
00201   if (get_frame_pc_if_available (fi, &pc))
00202     {
00203       struct symtab *s;
00204 
00205       s = find_pc_symtab (pc);
00206       /* elz: This if here fixes the problem with the pc not being
00207          displayed in the tui asm layout, with no debug symbols.  The
00208          value of s would be 0 here, and select_source_symtab would
00209          abort the command by calling the 'error' function.  */
00210       if (s)
00211         select_source_symtab (s);
00212     }
00213 
00214   /* Display the frame position (even if there is no symbols or the PC
00215      is not known).  */
00216   tui_show_frame_info (fi);
00217 
00218   /* Refresh the register window if it's visible.  */
00219   if (tui_is_window_visible (DATA_WIN))
00220     {
00221       tui_refreshing_registers = 1;
00222       tui_check_data_values (fi);
00223       tui_refreshing_registers = 0;
00224     }
00225 }
00226 
00227 /* Called from print_frame_info to list the line we stopped in.  */
00228 static void
00229 tui_print_frame_info_listing_hook (struct symtab *s,
00230                                    int line,
00231                                    int stopline, 
00232                                    int noerror)
00233 {
00234   select_source_symtab (s);
00235   tui_show_frame_info (get_selected_frame (NULL));
00236 }
00237 
00238 /* Perform all necessary cleanups regarding our module's inferior data
00239    that is required after the inferior INF just exited.  */
00240 
00241 static void
00242 tui_inferior_exit (struct inferior *inf)
00243 {
00244   /* Leave the SingleKey mode to make sure the gdb prompt is visible.  */
00245   tui_set_key_mode (TUI_COMMAND_MODE);
00246   tui_show_frame_info (0);
00247   tui_display_main ();
00248 }
00249 
00250 /* Observers created when installing TUI hooks.  */
00251 static struct observer *tui_bp_created_observer;
00252 static struct observer *tui_bp_deleted_observer;
00253 static struct observer *tui_bp_modified_observer;
00254 static struct observer *tui_inferior_exit_observer;
00255 static struct observer *tui_about_to_proceed_observer;
00256 
00257 /* Install the TUI specific hooks.  */
00258 void
00259 tui_install_hooks (void)
00260 {
00261   deprecated_selected_frame_level_changed_hook
00262     = tui_selected_frame_level_changed_hook;
00263   deprecated_print_frame_info_listing_hook
00264     = tui_print_frame_info_listing_hook;
00265 
00266   deprecated_query_hook = tui_query_hook;
00267 
00268   /* Install the event hooks.  */
00269   tui_bp_created_observer
00270     = observer_attach_breakpoint_created (tui_event_create_breakpoint);
00271   tui_bp_deleted_observer
00272     = observer_attach_breakpoint_deleted (tui_event_delete_breakpoint);
00273   tui_bp_modified_observer
00274     = observer_attach_breakpoint_modified (tui_event_modify_breakpoint);
00275   tui_inferior_exit_observer
00276     = observer_attach_inferior_exit (tui_inferior_exit);
00277   tui_about_to_proceed_observer
00278     = observer_attach_about_to_proceed (tui_about_to_proceed);
00279 
00280   deprecated_register_changed_hook = tui_register_changed_hook;
00281 }
00282 
00283 /* Remove the TUI specific hooks.  */
00284 void
00285 tui_remove_hooks (void)
00286 {
00287   deprecated_selected_frame_level_changed_hook = 0;
00288   deprecated_print_frame_info_listing_hook = 0;
00289   deprecated_query_hook = 0;
00290   deprecated_register_changed_hook = 0;
00291 
00292   /* Remove our observers.  */
00293   observer_detach_breakpoint_created (tui_bp_created_observer);
00294   tui_bp_created_observer = NULL;
00295   observer_detach_breakpoint_deleted (tui_bp_deleted_observer);
00296   tui_bp_deleted_observer = NULL;
00297   observer_detach_breakpoint_modified (tui_bp_modified_observer);
00298   tui_bp_modified_observer = NULL;
00299   observer_detach_inferior_exit (tui_inferior_exit_observer);
00300   tui_inferior_exit_observer = NULL;
00301   observer_detach_about_to_proceed (tui_about_to_proceed_observer);
00302   tui_about_to_proceed_observer = NULL;
00303 }
00304 
00305 void _initialize_tui_hooks (void);
00306 
00307 void
00308 _initialize_tui_hooks (void)
00309 {
00310   /* Install the permanent hooks.  */
00311   observer_attach_new_objfile (tui_new_objfile_hook);
00312 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines