GDB (API)
/home/stan/gdb/src/gdb/gdbtk/library/watch.tcl
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines