GDB (API)
|
00001 # Local Variable Window for Insight. 00002 # Copyright (C) 2002-2012 Red Hat, Inc. 00003 # 00004 # This program is free software; you can redistribute it and/or modify it 00005 # under the terms of the GNU General Public License (GPL) as published by 00006 # the Free Software Foundation; either version 2 of the License, or (at 00007 # your option) any later version. 00008 # 00009 # This program is distributed in the hope that it will be useful, 00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 # GNU General Public License for more details. 00013 00014 00015 # ---------------------------------------------------------------------- 00016 # Implements local variables windows for gdb. 00017 # ---------------------------------------------------------------------- 00018 00019 itcl::class LocalsWin { 00020 inherit EmbeddedWin GDBWin 00021 # ------------------------------------------------------------------ 00022 # CONSTRUCTOR - create new locals window 00023 # ------------------------------------------------------------------ 00024 constructor {args} { 00025 debug 00026 00027 gdbtk_busy 00028 build_win $itk_interior 00029 gdbtk_idle 00030 00031 add_hook gdb_no_inferior_hook "$this no_inferior" 00032 add_hook gdb_clear_file_hook [code $this clear_file] 00033 add_hook file_changed_hook [code $this clear_file] 00034 00035 update dummy 00036 } 00037 00038 00039 # ------------------------------------------------------------------ 00040 # PUBLIC METHOD: busy - BusyEvent handler 00041 # Disable all ui elements that could affect gdb's state 00042 # ------------------------------------------------------------------ 00043 method busy {event} { 00044 debug 00045 cursor watch 00046 } 00047 00048 # ------------------------------------------------------------------ 00049 # PUBLIC METHOD: reconfig - used when preferences change 00050 # ------------------------------------------------------------------ 00051 method reconfig {} { 00052 debug 00053 $tree update 00054 } 00055 00056 # Re-enable the UI 00057 method idle {event} { 00058 debug 00059 cursor {} 00060 } 00061 00062 # ------------------------------------------------------------------ 00063 # METHOD: no_inferior 00064 # Reset this object. 00065 # ------------------------------------------------------------------ 00066 method no_inferior {} { 00067 debug 00068 cursor {} 00069 catch {delete object $_frame} 00070 set _frame {} 00071 $tree remove all 00072 } 00073 00074 # ------------------------------------------------------------------ 00075 # METHOD: cursor - change the toplevel's cursor 00076 # ------------------------------------------------------------------ 00077 method cursor {what} { 00078 [winfo toplevel [namespace tail $this]] configure -cursor $what 00079 ::update idletasks 00080 } 00081 00082 00083 # ------------------------------------------------------------------ 00084 # METHOD: build_win - build window for variables. 00085 # ------------------------------------------------------------------ 00086 method build_win {f} { 00087 #debug "$f" 00088 00089 set tree [VarTree $f.tree -type "local"] 00090 pack $f.tree -expand yes -fill both 00091 pack $f -expand yes -fill both 00092 00093 window_name "Local Variables" 00094 ::update idletasks 00095 } 00096 00097 00098 # ------------------------------------------------------------------ 00099 # METHOD: clear_file - Clear out state so that a new executable 00100 # can be loaded. For LocalWins, this means doing 00101 # everything that no_inferior does. 00102 # ------------------------------------------------------------------ 00103 method clear_file {} { 00104 no_inferior 00105 } 00106 00107 # ------------------------------------------------------------------ 00108 # DESTRUCTOR - delete locals window 00109 # ------------------------------------------------------------------ 00110 destructor { 00111 debug 00112 set tree {} 00113 00114 # Remove this window and all hooks 00115 remove_hook gdb_no_inferior_hook "$this no_inferior" 00116 remove_hook gdb_clear_file_hook [code $this clear_file] 00117 remove_hook file_changed_hook [code $this clear_file] 00118 } 00119 00120 method context_switch {} { 00121 debug 00122 00123 set err [catch {gdb_selected_frame} current_frame] 00124 #debug "1: err=$err; _frame=\"$_frame\"; current_frame=\"$current_frame\"" 00125 00126 if {$err && $_frame != ""} { 00127 # No current frame 00128 debug "no current frame" 00129 catch {delete object $_frame} 00130 set _frame {} 00131 return 1 00132 } elseif {$current_frame == "" && $_frame == ""} { 00133 #debug "2" 00134 return 0 00135 } elseif {$_frame == "" || $current_frame != [$_frame address]} { 00136 # We've changed frames. If we knew something about 00137 # the stack layout, we could be more intelligent about 00138 # destroying variables, but we don't know that here (yet). 00139 debug "switching to frame at $current_frame" 00140 00141 # Destroy the old frame and create the new one 00142 catch {destroy $_frame} 00143 set _frame [Frame ::\#auto $current_frame] 00144 debug "created new frame: $_frame at [$_frame address]" 00145 return 1 00146 } 00147 00148 # Nothing changed 00149 #debug "3" 00150 return 0 00151 } 00152 00153 00154 method update {event} { 00155 debug 00156 00157 # Check that a context switch has not occured 00158 if {[context_switch]} { 00159 debug "CONTEXT SWITCH" 00160 00161 # delete variables in tree 00162 $tree remove all 00163 00164 if {$_frame != ""} { 00165 $tree add [$_frame variables] 00166 } 00167 } else { 00168 if {$_frame == ""} {return} 00169 # check for any new variables in the same frame 00170 $tree add [$_frame new] 00171 } 00172 after idle [code $tree update] 00173 } 00174 00175 protected variable Entry 00176 protected variable tree 00177 protected variable _frame {} 00178 }