GDB (API)
|
00001 # Watch window for Insight. 00002 # Copyright (C) 2002, 2003, 2006 Red Hat 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 watch windows for gdb. 00017 # ---------------------------------------------------------------------- 00018 00019 itcl::class WatchWin { 00020 inherit EmbeddedWin GDBWin 00021 # ------------------------------------------------------------------ 00022 # CONSTRUCTOR - create new watch 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 00036 00037 # ------------------------------------------------------------------ 00038 # PUBLIC METHOD: busy - BusyEvent handler 00039 # Disable all ui elements that could affect gdb's state 00040 # ------------------------------------------------------------------ 00041 method busy {event} { 00042 debug 00043 set Running 1 00044 cursor watch 00045 } 00046 00047 # Re-enable the UI 00048 method idle {event} { 00049 debug 00050 set Running 0 00051 cursor {} 00052 } 00053 00054 # ------------------------------------------------------------------ 00055 # METHOD: no_inferior 00056 # Reset this object. 00057 # ------------------------------------------------------------------ 00058 method no_inferior {} { 00059 debug 00060 cursor {} 00061 set Running 0 00062 foreach var $Watched { 00063 $var delete 00064 } 00065 $tree remove all 00066 } 00067 00068 # ------------------------------------------------------------------ 00069 # METHOD: cursor - change the toplevel's cursor 00070 # ------------------------------------------------------------------ 00071 method cursor {what} { 00072 [winfo toplevel [namespace tail $this]] configure -cursor $what 00073 ::update idletasks 00074 } 00075 00076 00077 # ------------------------------------------------------------------ 00078 # METHOD: build_win - build window for watch. 00079 # ------------------------------------------------------------------ 00080 method build_win {f} { 00081 #debug "$f" 00082 00083 set f [::frame $f.f] 00084 set treeFrame [frame $f.top] 00085 set entryFrame [frame $f.expr] 00086 00087 set tree [VarTree $treeFrame.tree] 00088 pack $tree -expand yes -fill both 00089 00090 set Entry [entry $entryFrame.ent -font global/fixed] 00091 button $entryFrame.but -text "Add Watch" -command [code $this validateEntry] 00092 pack $f -fill both -expand yes 00093 grid $entryFrame.ent -row 0 -column 0 -sticky news -padx 2 00094 grid $entryFrame.but -row 0 -column 1 -padx 2 00095 grid columnconfigure $entryFrame 0 -weight 1 00096 grid columnconfigure $entryFrame 1 00097 00098 grid $treeFrame -row 0 -column 0 -sticky news 00099 grid $entryFrame -row 1 -column 0 -padx 5 -pady 5 -sticky news 00100 grid columnconfigure $f 0 -weight 1 00101 grid rowconfigure $f 0 -weight 1 00102 window_name "Watch" 00103 ::update idletasks 00104 # Binding for the entry 00105 bind $entryFrame.ent <Return> "$entryFrame.but flash; $entryFrame.but invoke" 00106 } 00107 00108 method validateEntry {} { 00109 if {!$Running} { 00110 debug "Getting entry value...." 00111 set variable [$Entry get] 00112 debug "Got $variable, going to add" 00113 set ok [add $variable] 00114 debug "Added... with ok: $ok" 00115 $Entry delete 0 end 00116 } 00117 } 00118 00119 # ------------------------------------------------------------------ 00120 # METHOD: clear_file - Clear out state so that a new executable 00121 # can be loaded. For WatchWins, this means doing 00122 # everything that no_inferior does. 00123 # ------------------------------------------------------------------ 00124 method clear_file {} { 00125 debug 00126 no_inferior 00127 } 00128 00129 # ------------------------------------------------------------------ 00130 # DESTRUCTOR - delete watch window 00131 # ------------------------------------------------------------------ 00132 destructor { 00133 debug 00134 set tree {} 00135 00136 # Remove this window and all hooks 00137 remove_hook gdb_no_inferior_hook "$this no_inferior" 00138 remove_hook gdb_clear_file_hook [code $this clear_file] 00139 remove_hook file_changed_hook [code $this clear_file] 00140 00141 foreach var $Watched { 00142 $var delete 00143 } 00144 } 00145 00146 method remove {entry} { 00147 debug $entry 00148 00149 # Remove this entry from the list of watched variables 00150 set Watched [lremove $Watched $entry] 00151 00152 $entry remove 00153 $entry delete 00154 } 00155 00156 00157 method update {event} { 00158 $tree update 00159 } 00160 00161 00162 # ------------------------------------------------------------------ 00163 # METHOD: add - add a variable to the watch window 00164 # ------------------------------------------------------------------ 00165 method add {name} { 00166 debug "Trying to add \"$name\" to watch" 00167 00168 # Strip all the junk after the first \n 00169 set var [split $name \n] 00170 set var [lindex $var 0] 00171 set var [split $var =] 00172 set var [lindex $var 0] 00173 00174 # Strip out leading/trailing +, -, ;, spaces, commas 00175 set var [string trim $var +-\;\ \r\n,] 00176 00177 # Make sure that we have a valid variable 00178 set err [catch {gdb_cmd "set variable $var"} errTxt] 00179 if {$err} { 00180 dbug W "ERROR adding variable: $errTxt" 00181 ManagedWin::open WarningDlg -transient \ 00182 -over $this -message [list $errTxt] -ignorable "watchvar" 00183 } else { 00184 if {[string index $var 0] == "\$"} { 00185 # We must make a special attempt at verifying convenience 00186 # variables.. Specifically, these are printed as "void" 00187 # when they are not defined. So if a user type "$_I_made_tbis_up", 00188 # gdb responds with the value "void" instead of an error 00189 catch {gdb_cmd "p $var"} msg 00190 set msg [split $msg =] 00191 set msg [string trim [lindex $msg 1] \ \r\n] 00192 if {$msg == "void"} { 00193 return 0 00194 } 00195 } 00196 00197 debug "In add, going to add $name" 00198 # make one last attempt to get errors 00199 set err [catch {set foo($name) 1}] 00200 debug "err1=$err" 00201 set err [expr {$err + [catch {expr {$foo($name) + 1}}]}] 00202 debug "err2=$err" 00203 if {!$err} { 00204 set var [gdb_variable create -expr $name] 00205 debug "var=$var" 00206 $tree add $var 00207 lappend Watched $var 00208 return 1 00209 } 00210 } 00211 return 0 00212 } 00213 00214 protected variable Entry 00215 protected variable Watched {} 00216 protected variable tree 00217 protected variable Running 00218 }