URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [insight/] [gdb/] [gdbtcl/] [browserwin.itb] - Rev 1765
Compare with Previous | Blame | View Log
# Browswer window for Insight.# Copyright 1998, 1999, 2001 Red Hat## This program is free software; you can redistribute it and/or modify it# under the terms of the GNU General Public License (GPL) as published by# the Free Software Foundation; either version 2 of the License, or (at# your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.# ----------------------------------------------------------------------# Implements Browser window for gdb## ----------------------------------------------------------------------# ------------------------------------------------------------------# CONSTRUCTOR - create new browser window# ------------------------------------------------------------------option add *BrowserWin.textBackground whitebody BrowserWin::constructor {args} {#eval itk_initialize $argswindow_name "Function Browser"set Current(filename) {}set Current(function) {}_build_wineval itk_initialize $args# Create the toplevel binding for this classbind Configure_Browser_$this <Configure> [code $this _resize]add_hook file_changed_hook [code $this _fill_file_box]}# ------------------------------------------------------------------# DESTRUCTOR - destroy window containing widget# ------------------------------------------------------------------body BrowserWin::destructor {} {if {$resize_after != ""} {after cancel $resize_after}if {$filter_trace_after != ""} {after cancel $filter_trace_after}if {$MoreVisible} {pref set gdb/browser/view_is_open 1} else {pref set gdb/browser/view_is_open 0}remove_hook file_changed_hook [code $this _fill_file_box]trace vdelete [pref varname gdb/search/last_symbol] \w [code $this _filter_trace_proc]}# ------------------------------------------------------------------# METHOD: _build_win - build the main browser window# ------------------------------------------------------------------body BrowserWin::_build_win {} {global PREFS_state gdb_ImageDir# Three frames: regexp, listboxes, and drop-down paneitk_component add filter {iwidgets::labeledframe $itk_interior.filter -labeltext "Filter" \-labelrelief groove -labelborderwidth 2 -ipadx 6 -ipady 4}append labelUpdateCode [$itk_component(filter) clientHandlesConfigure 1] "\n"itk_component add browser {frame $itk_interior.browser}itk_component add view {frame $itk_interior.view}# Set up the contents of the Filter frameitk_component add filt_label {label [$itk_component(filter) childsite].lbl -text {Show if function } \-font src-font}itk_component add filt_type {combobox::combobox [$itk_component(filter) childsite].type -height 4 \-width 15 -editable 0 \-command [code $this _set_filter_mode] \-font src-font} { }# Fill the filter mode combo-boxforeach elem $filter_modes {$itk_component(filt_type) list insert end $elem}set cur_filter_mode [pref get gdb/search/filter_mode]if {[lsearch $filter_modes $cur_filter_mode] < 0} {set cur_filter_mode [lindex $filter_modes 0]}$itk_component(filt_type) entryset $cur_filter_modeitk_component add filt_entry {entry [$itk_component(filter) childsite].ent -font src-font \-textvariable [pref varname gdb/search/last_symbol] -background white} {usual Entryrename -background -textbackground textBackground Background}# Watch keystrokes into the entry box and filter on them...trace variable [pref varname gdb/search/last_symbol] w \[code $this _filter_trace_proc]pack $itk_component(filt_label) -side leftpack $itk_component(filt_type) -side left -padx 4 -fill y -pady 5pack $itk_component(filt_entry) -side right -fill both -expand 1 \-padx 6 -pady 5# Files Listbox for the Browser frameitk_component add file_box {iwidgets::scrolledlistbox $itk_component(browser).files \-selectmode extended -exportselection false \-labeltext "Files" -labelpos nw -labelrelief groove \-labelborderwidth 2 -ipadx 8 -ipady 6 \-childsitepos s -hscrollmode none -textbackground white}append labelUpdateCode [$itk_component(file_box) clientHandlesConfigure 1] \"\n"bind [$itk_component(file_box) component listbox] <ButtonRelease-1> \[code $this _process_file_selection %y]itk_component add file_sep {frame [$itk_component(file_box) childsite].sep -relief raised -height 2 \-borderwidth 1}itk_component add file_hide {checkbutton [$itk_component(file_box) childsite].hide \-text {Hide .h files} \-variable [pref varname gdb/browser/hide_h] \-command [code $this _file_hide_h]}itk_component add file_all {button [$itk_component(file_box) childsite].sel \-text {Select All} -width 12 \-command [code $this _select 1]}# Pack the file box in, and grid in the separate bits of the child-site.pack $itk_component(file_box) -side left -fill both -expand yes \-padx 5 -pady 5grid $itk_component(file_sep) -column 0 -row 0 -columnspan 2 \-sticky ew -pady 8grid $itk_component(file_hide) -column 0 -row 1 -padx 5 -sticky wgrid $itk_component(file_all) -column 1 -row 1 -padx 5 -sticky egrid columnconfigure [$itk_component(file_box) childsite] 0 -weight 1# Functions Listbox for the Browser frameitk_component add func_box {iwidgets::scrolledlistbox $itk_component(browser).funcs \-selectmode extended \-exportselection false \-labeltext "Functions" -labelpos nw -labelrelief groove \-labelborderwidth 2 -ipadx 8 -ipady 6 \-childsitepos s -hscrollmode none -textbackground white}append labelUpdateCode [$itk_component(func_box) clientHandlesConfigure 1] \"\n"bind [$itk_component(func_box) component listbox] <ButtonRelease-1> \[code $this _process_func_selection %y]itk_component add func_sep {frame [$itk_component(func_box) childsite].sep -relief raised \-height 2 -borderwidth 1}itk_component add func_bp_label {label [$itk_component(func_box) childsite].bpl -text {Breakpoints:}}itk_component add func_add_bp {button [$itk_component(func_box) childsite].abp -text {Set} \-command [code $this do_all_bp 1]}itk_component add func_remove_bp {button [$itk_component(func_box) childsite].rbp -text {Delete} \-command [code $this do_all_bp 0]}# Pack in the Function box, and grid in the bits of the child-sitepack $itk_component(func_box) -side right -fill both -expand yes \-padx 5 -pady 5grid $itk_component(func_sep) -row 0 -column 0 -columnspan 3 \-sticky ew -pady 8grid $itk_component(func_bp_label) -row 1 -column 0 -padx 5grid $itk_component(func_remove_bp) -row 1 -column 1 -padx 5grid $itk_component(func_add_bp) -row 1 -column 2 -padx 5grid columnconfigure [$itk_component(func_box) childsite] 1 -weight 1grid columnconfigure [$itk_component(func_box) childsite] 2 -weight 1# "More" frame for viewing sourceif {[lsearch [image names] _MORE_] == -1} {image create photo _MORE_ -file [file join $gdb_ImageDir more.gif]image create photo _LESS_ -file [file join $gdb_ImageDir less.gif]}itk_component add view_vis {frame $itk_interior.view.visible}itk_component add view_more {button $itk_component(view_vis).btn -image _MORE_ -relief flat \-command [code $this _toggle_more]}itk_component add view_label {label $itk_component(view_vis).lbl -text {View Source}}itk_component add view_sep {frame $itk_component(view_vis).sep -relief raised -borderwidth 1 -height 2}pack $itk_component(view_more) -side left -padx 10 -pady 10pack $itk_component(view_label) -side left -padx 10 -pady 10pack $itk_component(view_sep) -padx 4 -pady 10 -fill x -expand 1grid columnconfigure $itk_component(view_vis) 2 -weight 1pack $itk_component(view_vis) -side top -fill x -expand yes# Key bindings for "visible" framesbind_plain_key $itk_component(filt_entry) Return [list $this search]bind $itk_component(func_box) <3> [code $this _toggle_bp %y]# Construct hidden frameitk_component add view_hidden {frame $itk_interior.hidden}itk_component add view_src {SrcTextWin $itk_component(view_hidden).src -Tracing 0 \-parent $this -ignore_var_balloons 1} {rename -background -textbackground textBackground Background}$itk_component(view_src) configure -textheight 2iitk_component add view_bottom {frame $itk_component(view_hidden).bottom}itk_component add view_name {label $itk_component(view_hidden).name -font src-font}itk_component add view_func {combobox::combobox $itk_component(view_bottom).combo -maxheight 15 \-font src-font \-command [code $this _goto_func]} {# Should be able to do this, but can't cause the combobox doesn't# fake up a MegaWidget well enough#rename -background -textbackground textBackground Background}itk_component add view_mode {combobox::combobox $itk_component(view_bottom).mode -width 9 \-font src-font \-command [code $this mode]} {#rename -background -textbackground textBackground Background}itk_component add view_search {entry $itk_component(view_bottom).search -borderwidth 2 \-font src-font -width 10 \-background white} {rename -background -textbackground textBackground Background}# Pack all the components of view_hidden into the frame:pack $itk_component(view_search) -side right -padx 5 -fill none \-expand 1 -anchor epack $itk_component(view_mode) -side right -padx 5pack $itk_component(view_func) -side leftpack $itk_component(view_name) -side top -fill x -padx 5 -pady 3pack $itk_component(view_bottom) -side bottom -fill x -pady 3 -padx 5pack $itk_component(view_src) -fill both -expand 1 -padx 5 -pady 3# Fill combo boxes$itk_component(view_mode) list insert end SOURCE$itk_component(view_mode) list insert end ASSEMBLY$itk_component(view_mode) list insert end MIXED# don't allow SRC+ASM mode... $itk_component(view_mode) insert end SRC+ASM$itk_component(view_mode) entryset [$itk_component(view_src) mode_get]# Key bindings for hidden framebind_plain_key $itk_component(view_search) Return \[code $this _search_src forwards]bind_plain_key $itk_component(view_search) Shift-Return \[code $this _search_src backwards]# Now map everything onto the screengrid $itk_component(filter) -column 0 -row 0 -padx 6 -pady 4 -sticky ewgrid $itk_component(browser) -column 0 -row 1 -sticky nsewgrid $itk_component(view) -column 0 -row 2 -pady 4 -padx 6 -sticky ew# Now set up any initial values:set MoreVisible [pref get gdb/browser/view_is_open]set BrowserHeight [pref get gdb/browser/top_height]set Width [pref get gdb/browser/width]if {$BrowserHeight > 0} {grid rowconfigure $itk_component(hull) $componentToRow(browser) \-minsize $BrowserHeight}if {$Width > 0} {grid columnconfigure $itk_component(hull) 0 -minsize $Width}grid rowconfigure $itk_component(hull) 1 -weight 1grid columnconfigure $itk_component(hull) 0 -weight 1update idletaskseval $labelUpdateCodeif {$MoreVisible} {debug "Got moreVisible at 1"set MoreVisible 0_toggle_more 1}# Fill file box_fill_file_boxafter idle "update idletasksgrid rowconfigure $itk_component(hull) 2 \-minsize \[winfo height $itk_component(view)\]"# Finally set up the top level bindings:_bind_toplevel 1}# ------------------------------------------------------------------# METHOD: _filter_trace_proc# This is called when something is entered in the filter# box. The actual filtering is done in an after to avoid# flashing too much if the user is typing quickly.# ------------------------------------------------------------------body BrowserWin::_filter_trace_proc {v1 v2 mode} {if {$filter_trace_after != ""} {after cancel $filter_trace_after}set filter_trace_after [after 100 [code $this _filter_trace_after]]}# ------------------------------------------------------------------# METHOD: _filter_trace_after# This is a wrapper around search, needed to pass to trace# ------------------------------------------------------------------body BrowserWin::_filter_trace_after {} {set filter_trace_after ""search}# ------------------------------------------------------------------# METHOD: _search_src# Search for text or jump to a specific line# in source window, going in the specified DIRECTION.# ------------------------------------------------------------------body BrowserWin::_search_src {direction} {set exp [$itk_component(view_search) get]$itk_component(view_src) search $exp $direction}# ------------------------------------------------------------------# METHOD: search# Search for functions matching regexp/pattern# in specified files# ------------------------------------------------------------------body BrowserWin::search {} {set files [$itk_component(file_box) getcurselection]if {[llength $files] == 0} {return}_freeze_meset filt_pat [format $filter_regexp($cur_filter_mode) \[pref get gdb/search/last_symbol]]if {[llength $files] == [$itk_component(file_box) size]} {set err [catch {gdb_search functions $filt_pat \-filename 1} matches]} else {set err [catch {gdb_search functions $filt_pat \-files $files -filename 1} matches]}if {$err} {debug "ERROR searching for [pref get gdb/search/last_symbol]: $matches"_thaw_mereturn}$itk_component(func_box) delete 0 endset i -1catch {unset index_to_file}foreach func [lsort -command "list_element_strcmp 0" $matches] {$itk_component(func_box) insert end [lindex $func 0]set index_to_file([incr i]) [lindex $func 1]}_thaw_me}# ------------------------------------------------------------------# METHOD: _toggle_more# Toggle display of source listing# ------------------------------------------------------------------body BrowserWin::_toggle_more {{in_constructor 0}} {debug "Running toggle_more with MoreVisible: $MoreVisible"# Temporarily disable the resize bindings before opening the window._bind_toplevel 0set topHeight [winfo height $_top]set topWidth [winfo width $_top]if {!$MoreVisible} {$itk_component(view_label) configure -text {Hide Source}$itk_component(view_more) configure -image _LESS_grid $itk_component(view_hidden) -row 3 -column 0 -sticky nsew \-padx 6 -pady 4# Check the stored height. Restore the view to this if it will fit on the# screen. Otherwise, figure out how big to make it...set height [pref get gdb/browser/view_height]set bottom [expr {[winfo y $_top] + $topHeight}]set extra [expr {[winfo screenheight $_top] - $bottom - 20}]if {$height < 0} {set default [winfo pixels $_top 3i]set height [expr {$extra > $default ? $default : $extra}]} else {set height [expr {$extra > $height ? $height : $extra}]}wm geometry $_top ${topWidth}x[expr {$topHeight + $height}]grid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \-weight 1grid rowconfigure $itk_component(hull) $componentToRow(browser) -weight 0pref set gdb/browser/view_height $heightset MoreVisible 1update idletasks# If we have a selected function, display it in the windowset f [$itk_component(func_box) getcurselection]if {$f != ""} {# FIXME - If there is more than 1 function selected, I just load the# first. It would probably be better to load the one nearest to the# middle of the current window on the listbox. But I am running out# of time for this round...if {[llength $f] > 1} {set f [lindex $f 0]}_fill_source $f} else {# If no function was chosen, try the file box...set f [$itk_component(file_box) getcurselection]if { $f != "" } {if {[llength $f] > 1} {set f [lindex $f 0]}_fill_source $f 0}}} else {if {!$in_constructor} {pref set gdb/browser/view_height \[winfo height $itk_component(view_hidden)]}$itk_component(view_label) configure -text {View Source}$itk_component(view_more) configure -image _MORE_grid propagate $itk_component(func_box) 0grid propagate $itk_component(file_box) 0set newTopHeight [expr {$topHeight - \[winfo height $itk_component(view_hidden)]}]wm geometry $_top ${topWidth}x$newTopHeightif {!$in_constructor} {grid rowconfigure $itk_component(hull) $componentToRow(browser) -weight 1grid forget $itk_component(view_hidden)grid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \-minsize 0 -weight 0}set MoreVisible 0# Flush the changesupdate idletasksgrid propagate $itk_component(func_box) 1grid propagate $itk_component(file_box) 1}# restore the bindings_bind_toplevel 1}# ------------------------------------------------------------------# METHOD: _bind_toplevel# Setup the bindings for the toplevel.# ------------------------------------------------------------------body BrowserWin::_bind_toplevel {install} {set bindings [bindtags $_top]if {$install} {bindtags $_top [linsert $bindings 0 Configure_Browser_$this]} else {set bindLoc [lsearch $bindings Configure_Browser_$this]bindtags $_top [lreplace $bindings $bindLoc $bindLoc]}}# ------------------------------------------------------------------# METHOD: _do_resize# Does the actual work of the resize.# ------------------------------------------------------------------body BrowserWin::_do_resize {} {update idletasksdebug "Running _do_resize"set width [winfo width $itk_component(hull)]pref set gdb/browser/width $widthgrid columnconfigure $itk_component(hull) 0 -minsize $widthif {$MoreVisible} {set v_height [winfo height $itk_component(view_hidden)]pref set gdb/browser/view_height $v_heightgrid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \-minsize $v_heightgrid rowconfigure $itk_component(hull) $componentToRow(browser)} else {set b_height [winfo height $itk_component(browser)]pref set gdb/browser/top_height $b_heightgrid rowconfigure $itk_component(hull) $componentToRow(browser) \-minsize $b_height}eval $labelUpdateCodepack propagate $_top 1set resize_after ""}# ------------------------------------------------------------------# METHOD: _resize# Resize "itk_component(view_hidden)" after all configure events# ------------------------------------------------------------------body BrowserWin::_resize {} {pack propagate $_top 0if {$MoreVisible} {grid rowconfigure $itk_component(hull) $componentToRow(view_hidden) \-minsize 0} else {grid rowconfigure $itk_component(hull) 1 -minsize 0}grid columnconfigure $itk_component(hull) 0 -minsize 0if {$resize_after != ""} {after cancel $resize_after}set resize_after [after 100 "[code $this _do_resize]"]}# ------------------------------------------------------------------# METHOD: _process_file_selection# This fills the func combo, and the more window if it# is currently open with the hit in the File combobox.# ------------------------------------------------------------------body BrowserWin::_process_file_selection {y} {set curIndex [$itk_component(file_box) nearest $y]set curSelection [$itk_component(file_box) curselection]# We got a button-release - First make sure the click selected the item...if {[lsearch $curIndex $curSelection] >= 0} {_fill_source [$itk_component(file_box) get $curIndex] 0} else {# If the item was deselected, go back to the first one in the list...# It would be better to keep a stack of the clicked items, and go to the# last one on the stack. But in extended mode, this is tricky. FIXMEif {[llength $curSelection] > 0} {_fill_source [$itk_component(file_box) get [lindex $curSelection 0]] 0} else {_fill_source ""}}search}# ------------------------------------------------------------------# METHOD: _process_func_selection# This points the more window to the hit in the Func combobox# if it is currently open.# ------------------------------------------------------------------body BrowserWin::_process_func_selection {y} {set curIndex [$itk_component(func_box) nearest $y]set curSelection [$itk_component(func_box) curselection]# We got a button-release - First make sure the click selected the item...if {[lsearch $curIndex $curSelection] >= 0} {set funcName [$itk_component(func_box) get $curIndex]set fileName $index_to_file($curIndex)_fill_source $funcName 1 $fileName}}# ------------------------------------------------------------------# METHOD: do_all_bp# Toggle a bp at every selected function in FuncLB# ------------------------------------------------------------------body BrowserWin::do_all_bp {onp} {set funcs [$itk_component(func_box) getcurselection]_freeze_meforeach f $funcs {if {[catch {gdb_loc $f} linespec]} {dbug W "Could not gdb_loc \"$f\""return}set bpnum [bp_exists $linespec]if {$bpnum == -1 && $onp} {# FIXME: gdb_set_bp is the preferred method, but it requires# a file and line number. This doesn't work very well for# templates...gdb_cmd "break $f"} elseif {!$onp} {catch {gdb_cmd "delete $bpnum"}}}_thaw_me}# ------------------------------------------------------------------# METHOD: _toggle_bp# Toggle bp at function specified by the given Y# coordinate in the listbox# ------------------------------------------------------------------body BrowserWin::_toggle_bp {y} {set f [$itk_component(func_box) get [$itk_component(func_box) nearest $y]]if {$f != ""} {if {[catch {gdb_loc $f} linespec]} {return}set bpnum [bp_exists $linespec]if {$bpnum == -1} {# FIXME: gdb_set_bp is the preferred method, but it requires# a file and line number. This doesn't work very well for# templates...gdb_cmd "break $f"} else {catch {gdb_cmd "delete $bpnum"}}}}# ------------------------------------------------------------------# METHOD: _select# (Un/Highlight all files in the files list# ------------------------------------------------------------------body BrowserWin::_select {highlight} {if {$highlight} {$itk_component(file_box) selection set 0 end} else {$itk_component(file_box) selection clear 0 end}search}# ------------------------------------------------------------------# METHOD: _set_filter_mode# React to changes in the filter mode# ------------------------------------------------------------------body BrowserWin::_set_filter_mode {w mode} {if {[string compare $mode $cur_filter_mode] != 0} {set cur_filter_mode $modepref set gdb/search/filter_mode $modesearch}}# ------------------------------------------------------------------# METHOD: _file_hide_h# Run when the "Hide .h files" preference is chosen.# ------------------------------------------------------------------body BrowserWin::_file_hide_h {} {_fill_file_boxsearch}# ------------------------------------------------------------------# METHOD: _fill_source# Helper function to fill the srctextwin# when needed.# ------------------------------------------------------------------body BrowserWin::_fill_source {f {funcp 1} {filename ""}} {if {!$MoreVisible } {return}if {($funcp && [string compare $f $Current(function)]) \|| [string compare $f $Current(filename)]} {if {!$funcp} {if {$filename == ""} {set f $f:1} else {set f $f:$filename}}if {[catch {gdb_loc $f} linespec]} {return}lassign $linespec foo funcname name line addr pc_addr libset file_changed [string compare $Current(filename) $name]# fill srctextwinif {$file_changed} {# Set the file name label:$itk_component(view_name) configure -text $name:_freeze_me}$itk_component(view_src) location BROWSE_TAG $name $funcname \$line $addr $pc_addr libif {$file_changed} {_thaw_me}set Current(function) $funcname# fill func comboif {$file_changed} {set Current(filename) $name_fill_funcs_combo $name}# Set current function in combo box$itk_component(view_func) entryset $f}}# ------------------------------------------------------------------# METHOD: mode# Function called by srctextwin when the display# mode changes# ------------------------------------------------------------------body BrowserWin::mode {w {mode ""} {go 1}} {if {$mode != ""} {$itk_component(view_src) mode_set $mode $go$itk_component(view_mode) entryset $mode}}# ------------------------------------------------------------------# METHOD: _goto_func# Callback for the function combo box which# sets the srctextwin looking at the given function (VAL)# ------------------------------------------------------------------body BrowserWin::_goto_func {w {val ""}} {if {$val != ""} {set mang 0if {[info exists _mangled_func($val)]} {set mang $_mangled_func($val)}if {$mang} {set loc $val} else {set fn [lindex [::file split $Current(filename)] end]set loc $fn:$val}debug "GOTO \"$loc\""if {![catch {gdb_loc $loc} result]} {lassign $result foo funcname name line addr pc_addr lib$itk_component(view_src) location BROWSE_TAG $name $funcname \$line $addr $pc_addr lib} else {dbug W "gdb_loc returned \"$result\""}}}# ------------------------------------------------------------------# METHOD: _fill_file_box# This private method fills the file listbox# ------------------------------------------------------------------body BrowserWin::_fill_file_box {} {# It would be cool if gdb_listfiles took a regexp to match,# but it doesn't...$itk_component(file_box) clearset allFiles [gdb_listfiles]if {[pref get gdb/browser/hide_h]} {foreach file $allFiles {if {[string compare [file extension $file] ".h"]} {$itk_component(file_box) insert end $file}}} else {foreach file $allFiles {$itk_component(file_box) insert end $file}}search}# ------------------------------------------------------------------# METHOD: _fill_funcs_combo# This private method fills the functions combo box# with all the functions in NAME.# ------------------------------------------------------------------body BrowserWin::_fill_funcs_combo {name} {$itk_component(view_func) list delete 0 endif {$name != ""} {set maxlen 10if {[catch {gdb_listfuncs $name} listfuncs]} {tk_messageBox -icon error -default ok \-title "GDB" -type ok -modal system \-message "This file can not be found or does not contain\ndebugging information."return}foreach f $listfuncs {lassign $f func mangif {$func == "global constructors keyed to main"} {continue}set _mangled_func($func) $mang$itk_component(view_func) list insert end $funcif {[string length $func] > $maxlen} {set maxlen [string length $func]}}$itk_component(view_func) configure -width [expr {$maxlen + 1}]}}
