OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [gdbtk/] [library/] [variables.tcl] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
# Variable display window for Insight.
2
# Copyright 1997, 1998, 1999, 2001 Red Hat
3
#
4
# This program is free software; you can redistribute it and/or modify it
5
# under the terms of the GNU General Public License (GPL) as published by
6
# the Free Software Foundation; either version 2 of the License, or (at
7
# your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
 
14
 
15
# ----------------------------------------------------------------------
16
# Implements variable windows for gdb. LocalsWin and WatchWin both
17
# inherit from this class. You need only override the method 
18
# 'getVariablesBlankPath' and a few other things...
19
# ----------------------------------------------------------------------
20
 
21
class VariableWin {
22
    inherit EmbeddedWin GDBWin
23
    protected variable Sizebox 1
24
 
25
    # ------------------------------------------------------------------
26
    #  CONSTRUCTOR - create new watch window
27
    # ------------------------------------------------------------------
28
    constructor {args} {
29
        #
30
        #  Create a window with the same name as this object
31
        #
32
        gdbtk_busy
33
        set _queue [Queue \#auto]
34
        build_win $itk_interior
35
        gdbtk_idle
36
 
37
        add_hook gdb_no_inferior_hook "$this no_inferior"
38
        add_hook gdb_clear_file_hook [code $this clear_file]
39
        # FIXME: This is too harsh.  We must add to varobj a method
40
        # to re-parse the expressions and compute new types so we can
41
        # keep the contents of the window whenever possible.
42
        add_hook file_changed_hook [code $this clear_file]
43
    }
44
 
45
    # ------------------------------------------------------------------
46
    #  METHOD:  build_win - build the watch window
47
    # ------------------------------------------------------------------
48
    method build_win {f} {
49
        global tixOption tcl_platform Display
50
        #    debug
51
        set width [font measure src-font "W"]
52
        # Choose the default width to be...
53
        set width [expr {40 * $width}]
54
        if {$tcl_platform(platform) == "windows"} {
55
            set scrollmode both
56
        } else {
57
            set scrollmode auto
58
        }
59
 
60
        debug "tree=$f.tree"
61
        set Tree [tixTree $f.tree        \
62
                      -opencmd  "$this open"  \
63
                      -closecmd "$this close" \
64
                      -ignoreinvoke 1         \
65
                      -width $width           \
66
                      -browsecmd [list $this selectionChanged] \
67
                      -scrollbar $scrollmode \
68
                      -sizebox $Sizebox]
69
        if {![pref get gdb/mode]} {
70
            $Tree configure -command [list $this editEntry]
71
        }
72
        set Hlist [$Tree subwidget hlist]
73
 
74
        # FIXME: probably should use columns instead.
75
        $Hlist configure -header 1
76
 
77
        set l [expr {$EntryLength - $Length - [string length "Name"]}]
78
        # Ok, this is as hack as it gets
79
        set blank "                                                                                                                                                             "
80
        $Hlist header create 0 -itemtype text \
81
            -text "Name[string range $blank 0 $l]Value"
82
 
83
        # Configure the look of the tree
84
        set sbg [$Hlist cget -bg]
85
        set fg [$Hlist cget -fg]
86
        set bg $tixOption(input1_bg)
87
        set width [font measure src-font $LengthString]
88
        $Hlist configure -indent $width -bg $bg \
89
            -selectforeground $fg -selectbackground $sbg \
90
            -selectborderwidth 0 -separator . -font src-font
91
 
92
        # Get display styles
93
        set normal_fg    [$Hlist cget -fg]
94
        set highlight_fg [pref get gdb/variable/highlight_fg]
95
        set disabled_fg  [pref get gdb/variable/disabled_fg]
96
        set NormalTextStyle [tixDisplayStyle text -refwindow $Hlist \
97
                                 -bg $bg -fg $normal_fg -font src-font]
98
        set HighlightTextStyle [tixDisplayStyle text -refwindow $Hlist \
99
                                    -bg $bg -fg $highlight_fg -font src-font]
100
        set DisabledTextStyle [tixDisplayStyle text -refwindow $Hlist \
101
                                   -bg $bg -fg $disabled_fg -font src-font]
102
 
103
        if {[catch {gdb_cmd "show output-radix"} msg]} {
104
            set Radix 10
105
        } else {
106
            regexp {[0-9]+} $msg Radix
107
        }
108
 
109
 
110
        # Update the tree display
111
        update dummy
112
        pack $Tree -expand yes -fill both
113
 
114
        # Create the popup menu for this widget
115
        bind $Hlist <3> "$this postMenu %X %Y"
116
        bind $Hlist <KeyPress-space> [code $this toggleView]
117
 
118
        # Do not use the tixPopup widget... 
119
        set Popup [menu $f.menu -tearoff 0]
120
        set disabled_foreground [$Popup cget -foreground]
121
        $Popup configure -disabledforeground $disabled_foreground
122
        set ViewMenu [menu $Popup.view]
123
 
124
        # Populate the view menu
125
        $ViewMenu add radiobutton -label "Hex" -variable Display($this) \
126
            -value hexadecimal
127
        $ViewMenu add radiobutton -label "Decimal" -variable Display($this) \
128
            -value decimal
129
        $ViewMenu add radiobutton -label "Binary" -variable Display($this) \
130
            -value binary
131
        $ViewMenu add radiobutton -label "Octal" -variable Display($this) \
132
            -value octal
133
        $ViewMenu add radiobutton -label "Natural" -variable Display($this) \
134
            -value natural
135
 
136
        $Popup add command -label "dummy" -state disabled
137
        $Popup add separator
138
        $Popup add cascade -label "Format" -menu $ViewMenu
139
        #    $Popup add checkbutton -label "Auto Update"
140
        #    $Popup add command -label "Update Now"
141
        if {![pref get gdb/mode]} {
142
            $Popup add command -label "Edit"
143
        }
144
 
145
        # Make sure to update menu info.
146
        selectionChanged ""
147
 
148
        window_name "Local Variables" "Locals"
149
    }
150
 
151
    # ------------------------------------------------------------------
152
    #  DESTRUCTOR - destroy window containing widget
153
    # ------------------------------------------------------------------
154
    destructor {
155
        #    debug
156
        # Make sure to clean up the frame
157
        catch {destroy $_frame}
158
 
159
        # Delete the display styles used with this window
160
        destroy $NormalTextStyle
161
        destroy $HighlightTextStyle
162
        destroy $DisabledTextStyle
163
 
164
        # Remove this window and all hooks
165
        remove_hook gdb_no_inferior_hook "$this no_inferior"
166
        remove_hook gdb_clear_file_hook [code $this clear_file]
167
        remove_hook file_changed_hook [code $this clear_file]
168
    }
169
 
170
    # ------------------------------------------------------------------
171
    #  METHOD:  clear_file - Clear out state and prepare for loading
172
    #              a new executable.
173
    # ------------------------------------------------------------------
174
    method clear_file {} {
175
        no_inferior
176
    }
177
 
178
    # ------------------------------------------------------------------
179
    #  METHOD:  reconfig - used when preferences change
180
    # ------------------------------------------------------------------
181
    method reconfig {} {
182
        #    debug
183
        foreach win [winfo children $itk_interior] {
184
            destroy $win
185
        }
186
 
187
        build_win $itk_interior
188
    }
189
 
190
    # ------------------------------------------------------------------
191
    #  METHOD:  build_menu_helper - Create the menu for a subclass.
192
    # ------------------------------------------------------------------
193
    method build_menu_helper {first} {
194
        global Display
195
        menu [namespace tail $this].mmenu
196
 
197
        [namespace tail $this].mmenu add cascade -label $first -underline 0 -menu [namespace tail $this].mmenu.var
198
 
199
        menu [namespace tail $this].mmenu.var
200
        if {![pref get gdb/mode]} {
201
            [namespace tail $this].mmenu.var add command -label Edit -underline 0 -state disabled \
202
                -command [format {
203
                    %s editEntry [%s getSelection]
204
                } $this $this]
205
        }
206
        [namespace tail $this].mmenu.var add cascade -label Format -underline 0 \
207
            -menu [namespace tail $this].mmenu.var.format
208
 
209
        menu [namespace tail $this].mmenu.var.format
210
        foreach label {Hex Decimal Binary Octal Natural} fmt {hexadecimal decimal binary octal natural} {
211
            [namespace tail $this].mmenu.var.format add radiobutton \
212
                -label $label -underline 0 \
213
                -value $fmt -variable Display($this) \
214
                -command [format {
215
                    %s setDisplay [%s getSelection] %s
216
                } $this $this $fmt]
217
        }
218
 
219
        #    [namespace tail $this].mmenu add cascade -label Update -underline 0 -menu [namespace tail $this].mmenu.update
220
        #    menu [namespace tail $this].mmenu.update
221
 
222
        # The -variable is set when a selection is made in the tree.
223
        #    [namespace tail $this].mmenu.update add checkbutton -label "Auto Update" -underline 0 \
224
            #      -command [format {
225
        #       %s toggleUpdate [%s getSelection]
226
        #      } $this $this]
227
        #    [namespace tail $this].mmenu.update add command -label "Update Now" -underline 0 \
228
            #      -accelerator "Ctrl+U" -command [format {
229
        #       %s updateNow [%s getSelection]
230
        #      } $this $this]
231
 
232
        set top [winfo toplevel [namespace tail $this]]
233
        $top configure -menu [namespace tail $this].mmenu
234
        bind_plain_key $top Control-u [format {
235
            if {!$Running} {
236
                if {[%s getSelection] != ""} {
237
                    %s updateNow [%s getSelection]
238
                }
239
            }
240
        } $this $this $this]
241
 
242
        return [namespace tail $this].mmenu.var
243
    }
244
 
245
    # Return the current selection, or the empty string if none.
246
    method getSelection {} {
247
        return [$Hlist info selection]
248
    }
249
 
250
    # This is called when a selection is made.  It updates the main
251
    # menu.
252
    method selectionChanged {variable} {
253
        global Display
254
 
255
        if {$Running} {
256
            # Clear the selection, too
257
            $Hlist selection clear
258
            return
259
        }
260
 
261
        # if something is being edited, cancel it
262
        if {[info exists EditEntry]} {
263
            UnEdit
264
        }
265
 
266
        if {$variable == ""} {
267
            set state disabled
268
        } else {
269
            set state normal
270
        }
271
 
272
        foreach menu [list [namespace tail $this].mmenu.var [namespace tail $this].mmenu.var.format ] {
273
            set i [$menu index last]
274
            while {$i >= 0} {
275
                if {[$menu type $i] != "cascade"} {
276
                    $menu entryconfigure $i -state $state
277
                }
278
                incr i -1
279
            }
280
        }
281
 
282
        if {$variable != "" && [$variable editable]} {
283
            set state normal
284
        } else {
285
            set state disabled
286
        }
287
 
288
        if {$variable != ""} {
289
            set Display($this) [$variable format]
290
        }
291
 
292
        foreach label {Hex Decimal Binary Octal Natural} {
293
            [namespace tail $this].mmenu.var.format entryconfigure $label
294
            if {$label != "Hex"} {
295
                [namespace tail $this].mmenu.var.format entryconfigure $label -state $state
296
            }
297
        }
298
        #    [namespace tail $this].mmenu.update entryconfigure 0 -variable Update($this,$name)
299
    }
300
 
301
    method updateNow {variable} {
302
        # debug "$variable"
303
 
304
        if {!$Running} {
305
            set text [label $variable]
306
            $Hlist entryconfigure $variable -itemtype text -text $text
307
        }
308
    }
309
 
310
    method getEntry {x y} {
311
        set realY [expr {$y - [winfo rooty $Hlist]}]
312
 
313
        # Get the tree entry which we are over
314
        return [$Hlist nearest $realY]
315
    }
316
 
317
    method editEntry {variable} {
318
        if {!$Running} {
319
            if {$variable != "" && [$variable editable]} {
320
                edit $variable
321
            }
322
        }
323
    }
324
 
325
    method postMenu {X Y} {
326
        global Update Display
327
        #    debug
328
 
329
        # Quicky for menu posting problems.. How to unpost and post??
330
 
331
        if {[winfo ismapped $Popup] || $Running} {
332
            return
333
        }
334
 
335
        set variable [getEntry $X $Y]
336
        if {[string length $variable] > 0} {
337
          # First things first: highlight the variable we just selected
338
          $Hlist selection set $variable
339
 
340
            # Configure menu items
341
            # the title is always first..
342
            #set labelIndex [$Popup index "dummy"]
343
            set viewIndex [$Popup index "Format"]
344
            #      set autoIndex [$Popup index "Auto Update"]
345
            #      set updateIndex [$Popup index "Update Now"]
346
            set noEdit [catch {$Popup index "Edit"} editIndex]
347
 
348
            # Retitle and set update commands
349
            $Popup entryconfigure 0 -label "[$variable name]"
350
            #      $Popup entryconfigure $autoIndex -command "$this toggleUpdate \{$entry\}" \
351
                -variable Update($this,$entry) 
352
            #      $Popup entryconfigure $updateIndex -command "$this updateNow \{$entry\}"
353
 
354
            # Edit pane
355
            if {$variable != "" && [$variable editable]} {
356
                if {!$noEdit} {
357
                    $Popup delete $editIndex
358
                }
359
                if {![pref get gdb/mode]} {
360
                    $Popup  add command -label Edit -command "$this edit \{$variable\}"
361
                }
362
            } else {
363
                if {!$noEdit} {
364
                    $Popup delete $editIndex
365
                }
366
            }
367
 
368
            # Set view menu
369
            set Display($this) [$variable format]
370
            foreach i {0 1 2 3 4} fmt {hexadecimal decimal binary octal natural} {
371
                debug "configuring entry $i ([$ViewMenu entrycget $i -label]) to $fmt"
372
                $ViewMenu entryconfigure $i \
373
                    -command "$this setDisplay \{$variable\} $fmt"
374
            }
375
 
376
            if {$::tcl_platform(platform) == "windows"} {
377
              # Don't ask me why this works, but it does work around
378
              # a Win98/2000 Tcl bug with deleting entries from popups...
379
              set no [$Popup index end]
380
              for { set k 1 } { $k < $no } { incr k } {
381
                $Popup insert 1 command
382
              }
383
              $Popup delete 1 [expr {$no - 1}]
384
            }
385
 
386
            tk_popup $Popup $X $Y
387
        }
388
    }
389
 
390
    # ------------------------------------------------------------------
391
    # METHOD edit -- edit a variable
392
    # ------------------------------------------------------------------
393
    method edit {variable} {
394
        global Update tixOption
395
 
396
        # disable menus
397
        selectionChanged ""
398
        debug "editing \"$variable\""
399
 
400
        set fg   [$Hlist cget -foreground]
401
        set bg   [$Hlist cget -background]
402
 
403
        if {$Editing == ""} {
404
            # Must create the frame
405
            set Editing [frame $Hlist.frame -bg $bg -bd 0 -relief flat]
406
            set lbl [::label $Editing.lbl -fg $fg -bg $bg -font src-font]
407
            set ent [entry $Editing.ent -bg $tixOption(bg) -font src-font]
408
            pack $lbl $ent -side left
409
        }
410
 
411
        if {[info exists EditEntry]} {
412
            # We already are editing something... So reinstall it first
413
            # I guess we discard any changes?
414
            UnEdit
415
        }
416
 
417
        # Update the label/entry widgets for this instance
418
        set Update($this,$variable) 1
419
        set EditEntry $variable
420
        set label [label $variable 1];  # do not append value
421
        $Editing.lbl configure -text "$label  "
422
        $Editing.ent delete 0 end
423
 
424
        # Strip the pointer type, text, etc, from pointers, and such
425
        set err [catch {$variable value} text]
426
        if {$err} {return}
427
        if {[$variable format] == "natural"} {
428
            # Natural formats must be stripped. They often contain
429
            # things like strings and characters after them.
430
            set index [string first \  $text]
431
            if {$index != -1} {
432
                set text [string range $text 0 [expr {$index - 1}]]
433
            }
434
        }
435
        $Editing.ent insert 0 $text
436
 
437
        # Find out what the previous entry is
438
        set previous [getPrevious $variable]
439
 
440
        $Hlist delete entry $variable
441
 
442
        set cmd [format { \
443
                              %s add {%s} %s -itemtype window -window %s \
444
                          } $Hlist $variable $previous $Editing]
445
        eval $cmd
446
 
447
        if {[$variable numChildren] > 0} {
448
            $Tree setmode $variable open
449
        }
450
 
451
        # Set focus to entry
452
        focus $Editing.ent
453
        $Editing.ent selection to end
454
 
455
        # Setup key bindings
456
        bind $Editing.ent <Return> "$this changeValue"
457
        bind $Hlist <Return> "$this changeValue"
458
        bind $Editing.ent <Escape> "$this UnEdit"
459
        bind $Hlist <Escape> "$this UnEdit"
460
    }
461
 
462
    method getPrevious {variable} {
463
        set prev [$Hlist info prev $variable]
464
        set parent [$Hlist info parent $variable]
465
 
466
        if {$prev != ""} {
467
            # A problem occurs with PREV if its parent is not the same as the entry's
468
            # parent. For example, consider these variables in the window:
469
            # + foo        struct {...}
470
            # - bar        struct {...}
471
            #     a        1
472
            #     b        2
473
            # local        0
474
            # if you attempt to edit "local", previous will be set at "bar.b", not
475
            # "struct bar"...
476
            if {[$Hlist info parent $prev] != $parent} {
477
                # This is the problem!
478
                # Find this object's sibling in that parent and place it there.
479
                set children [$Hlist info children $parent]
480
                set p {}
481
                foreach child $children {
482
                    if {$child == $variable} {
483
                        break
484
                    }
485
                    set p $child
486
                }
487
 
488
                if {$p == {}} {
489
                    # This is the topmost child
490
                    set previous "-before [lindex $children 1]"
491
                } else {
492
                    set previous "-after $p"
493
                }
494
            } else {
495
                set previous "-after \{$prev\}"
496
            }
497
        } else {
498
            # this is the first!
499
            set previous "-at 0"
500
        }
501
 
502
        if {$prev == "$parent"} {
503
            # This is the topmost-member of a sub-grouping..
504
            set previous "-at 0"
505
        }
506
 
507
        return $previous
508
    }
509
 
510
    method UnEdit {} {
511
        set previous [getPrevious $EditEntry]
512
 
513
        $Hlist delete entry $EditEntry
514
        set cmd [format {\
515
                             %s add {%s} %s -itemtype text -text {%s} \
516
                         } $Hlist $EditEntry $previous [label $EditEntry]]
517
        eval $cmd
518
        if {[$EditEntry numChildren] > 0} {
519
            $Tree setmode $EditEntry open
520
        }
521
 
522
        # Unbind
523
        bind $Hlist <Return> {}
524
        bind $Hlist <Escape> {}
525
        if {$Editing != ""} {
526
            bind $Editing.ent <Return> {}
527
            bind $Editing.ent <Escape> {}
528
        }
529
 
530
        unset EditEntry
531
        selectionChanged ""
532
    }
533
 
534
    method changeValue {} {
535
        # Get the old value
536
        set new [string trim [$Editing.ent get] \ \r\n]
537
        if {$new == ""} {
538
            UnEdit
539
            return
540
        }
541
 
542
        if {[catch {$EditEntry value $new} errTxt]} {
543
            tk_messageBox -icon error -type ok -message $errTxt \
544
                -title "Error in Expression" -parent [winfo toplevel $itk_interior]
545
            focus $Editing.ent
546
            $Editing.ent selection to end
547
        } else {
548
            UnEdit
549
 
550
            # We may have changed a register or something else that is 
551
            # being displayed in another window
552
            gdbtk_update
553
 
554
            # Get rid of entry... and replace it with new value
555
            focus $Tree
556
        }
557
    }
558
 
559
 
560
    # ------------------------------------------------------------------
561
    #  METHOD:  toggleView: Toggle open/close the current selection.
562
    # ------------------------------------------------------------------  
563
    method toggleView {} {
564
 
565
        set v [getSelection]
566
        set mode [$Tree getmode $v]
567
 
568
        # In the tixTree widget, "open" means "openable", not that it is open...
569
 
570
        debug "mode=$mode"
571
        switch $mode {
572
            open {
573
                $Tree setmode $v close
574
                open $v
575
            }
576
 
577
            close {
578
                $Tree setmode $v open
579
                close $v
580
            }
581
 
582
            default {
583
                dbug E "What happened?"
584
            }
585
        }
586
    }
587
 
588
    method toggleUpdate {variable} {
589
        global Update
590
 
591
        if {$Update($this,$variable)} {
592
            # Must update value
593
            $Hlist entryconfigure $variable \
594
                -style $NormalTextStyle    \
595
                -text [label $variable]
596
        } else {
597
            $Hlist entryconfigure $variable \
598
                -style $DisabledTextStyle
599
        }
600
        ::update
601
    }
602
 
603
    method setDisplay {variable format} {
604
        debug "$variable $format"
605
        if {!$Running} {
606
            $variable format $format
607
            set ::Display($this) $format
608
            $Hlist entryconfigure $variable -text [label $variable]
609
        }
610
    }
611
 
612
    # ------------------------------------------------------------------
613
    # METHOD:   label - used to label the entries in the tree
614
    # ------------------------------------------------------------------
615
    method label {variable {noValue 0}} {
616
        # Ok, this is as hack as it gets
617
        set blank "                                                                                                                                                             "
618
        # Use protected data Length to determine how big variable
619
        # name should be. This should clean the display up a little
620
        set name [$variable name]
621
        set indent [llength [split $variable .]]
622
        set indent [expr {$indent * $Length}]
623
        set len [string length $name]
624
        set l [expr {$EntryLength - $len - $indent}]
625
        set label "$name[string range $blank 0 $l]"
626
        #debug "label=$label $noValue"
627
        if {$noValue} {
628
            return $label
629
        }
630
 
631
        set err [catch {$variable value} value]
632
        set value [string trim $value \ \r\t\n]
633
        #debug "err=$err value=$value"
634
 
635
        # Insert the variable's type for things like ptrs, etc.
636
        set type [$variable type]
637
        if {!$err} {
638
            if {$value == "{...}"} {
639
                set val " $type $value"
640
            } elseif {[string first * $type] != -1} {
641
                set val " ($type) $value"
642
            } elseif {[string first \[ $type] != -1} {
643
                set val " $type"
644
            } else {
645
                set val " $value"
646
            }
647
        } else {
648
            set val " $value"
649
        }
650
 
651
        return "$label $val"
652
    }
653
 
654
    # ------------------------------------------------------------------
655
    # METHOD:   open - used to open an entry in the variable tree
656
    # ------------------------------------------------------------------
657
    method open {path} {
658
        global Update
659
        # We must lookup all the variables for this struct
660
        #    debug "$path"
661
 
662
        # Cancel any edits
663
        if {[info exists EditEntry]} {
664
            UnEdit
665
        }
666
 
667
        if {!$Running} {
668
            # Do not open disabled paths
669
            if {$Update($this,$path)} {
670
                cursor watch
671
                populate $path
672
                cursor {}
673
            }
674
        } else {
675
            $Tree setmode $path open
676
        }
677
    }
678
 
679
    # ------------------------------------------------------------------
680
    # METHOD:   close - used to close an entry in the variable tree
681
    # ------------------------------------------------------------------
682
    method close {path} {
683
        global Update
684
        debug "$path"
685
        # Close the path and destroy all the entry widgets
686
 
687
        # Cancel any edits
688
        if {[info exists EditEntry]} {
689
            UnEdit
690
        }
691
 
692
        if {!$Running} {
693
            # Only update when we we are not disabled
694
            if {$Update($this,$path)} {
695
 
696
                # Delete the offspring of this entry
697
                $Hlist delete offspring $path
698
            }
699
        } else {
700
            $Tree setmode $path close
701
        }
702
    }
703
 
704
    method isVariable {var} {
705
 
706
        set err [catch {gdb_cmd "output $var"} msg]
707
        if {$err
708
            || [regexp -nocase "no symbol|syntax error" $msg]} {
709
            return 0
710
        }
711
 
712
        return 1
713
    }
714
 
715
    # OVERRIDE THIS METHOD
716
    method getVariablesBlankPath {} {
717
        dbug -W "You forgot to override getVariablesBlankPath!!"
718
        return {}
719
    }
720
 
721
    method cmd {cmd} {
722
        eval $cmd
723
    }
724
 
725
    # ------------------------------------------------------------------
726
    # METHOD:   populate - populate an entry in the tree
727
    # ------------------------------------------------------------------
728
    method populate {parent} {
729
        global Update
730
        debug "$parent"
731
 
732
        if {[string length $parent] == 0} {
733
            set variables [getVariablesBlankPath]
734
        } else {
735
            set variables [$parent children]
736
        }
737
 
738
        debug "variables=$variables"
739
        eval $_queue push $variables
740
        for {set variable [$_queue pop]} {$variable != ""} {set variable [$_queue pop]} {
741
            debug "inserting variable: $variable"
742
            set Update($this,$variable) 1
743
 
744
            $Hlist add $variable          \
745
                -itemtype text              \
746
                -text [label $variable]
747
            if {[$variable numChildren] > 0} {
748
                # Make sure we get this labeled as openable
749
                $Tree setmode $variable open
750
            }
751
 
752
            # Special case: If we see "public" with no value or type, then we
753
            # have one of our special c++/java children. Open it automagically
754
            # for the user.
755
            if {[string compare [$variable name] "public"] == 0
756
                && [$variable type] == "" && [$variable value] == ""} {
757
                eval $_queue push [$variable children]
758
                $Tree setmode $variable close
759
            }
760
        }
761
 
762
        debug "done with populate"
763
    }
764
 
765
    # Get all current locals
766
    proc getLocals {} {
767
 
768
        set vars {}
769
        set err [catch {gdb_get_args} v]
770
        if {!$err} {
771
            set vars [concat $vars $v]
772
        }
773
 
774
        set err [catch {gdb_get_locals} v]
775
        if {!$err} {
776
            set vars [concat $vars $v]
777
        }
778
 
779
        debug "--getLocals:\n$vars\n--getLocals"
780
        return [lsort $vars]
781
    }
782
 
783
    method context_switch {} {
784
        set err [catch {gdb_selected_frame} current_frame]
785
        debug "1: err=$err; _frame=\"$_frame\"; current_frame=\"$current_frame\""
786
        if {$err && $_frame != ""} {
787
            # No current frame
788
            debug "no current frame"
789
            catch {destroy $_frame}
790
            set _frame {}
791
            return 1
792
        } elseif {$current_frame == "" && $_frame == ""} {
793
            debug "2"
794
            return 0
795
        } elseif {$_frame == "" || $current_frame != [$_frame address]} {
796
            # We've changed frames. If we knew something about
797
            # the stack layout, we could be more intelligent about
798
            # destroying variables, but we don't know that here (yet).
799
            debug "switching to frame at $current_frame"
800
 
801
            # Destroy the old frame and create the new one
802
            catch {destroy $_frame}
803
            set _frame [Frame ::\#auto $current_frame]
804
            debug "created new frame: $_frame at [$_frame address]"
805
            return 1
806
        }
807
 
808
        # Nothing changed
809
        debug "3"
810
        return 0
811
    }
812
 
813
    # ------------------------------------------------------------------
814
    # METHOD:   update
815
    # OVERRIDE THIS METHOD and call it from there
816
    # ------------------------------------------------------------------
817
    method update {event} {
818
        global Update
819
        debug
820
 
821
        # First, reset color on label to black
822
        foreach w $ChangeList {
823
            catch {
824
                $Hlist entryconfigure $w -style $NormalTextStyle
825
            }
826
        }
827
 
828
        # Tell toplevel variables to update themselves. This will
829
        # give us a list of all the variables in the table that
830
        # have changed values.
831
        set ChangeList {}
832
        set variables [$Hlist info children {}]
833
        foreach var $variables {
834
            # debug "VARIABLE: $var ($Update($this,$var))"
835
            set numchild [$var numChildren]
836
            set UpdatedList [$var update]
837
            # FIXME: For now, we can only infer that the type has changed
838
            # if the variable is not a scalar; the varobj code will have to
839
            # give us an indication that this happened.
840
            if {([lindex $UpdatedList 0] == $var)
841
                && ($numchild > 0)} {
842
              debug "Type changed."
843
              # We must fix the tree entry to correspond to the new type
844
              $Hlist delete offsprings $var
845
              $Hlist entryconfigure $var -text [label $var]
846
              if {[$var numChildren] > 0} {
847
                $Tree setmode $var open
848
              } else {
849
                $Tree setmode $var none
850
              }
851
            } else {
852
              set ChangeList [concat $ChangeList $UpdatedList]
853
              # debug "ChangeList=$ChangeList"
854
            }
855
        }
856
 
857
        foreach var $ChangeList {
858
            $Hlist entryconfigure $var \
859
                -style  $HighlightTextStyle   \
860
                -text [label $var]
861
        }
862
    }
863
 
864
    method idle {event} {
865
        # Re-enable the UI
866
        enable_ui
867
    }
868
 
869
    # RECURSION!!
870
    method displayedVariables {top} {
871
        #    debug
872
        set variableList {}
873
        set variables [$Hlist info children $top]
874
        foreach var $variables {
875
            set mode [$Tree getmode $var]
876
            if {$mode == "close"} {
877
                set moreVars [displayedVariables $var]
878
                lappend variableList [join $moreVars]
879
            }
880
            lappend variableList $var
881
        }
882
 
883
        return [join $variableList]
884
    }
885
 
886
    method deleteTree {} {
887
        global Update
888
        debug
889
#       set variables [displayedVariables {}]
890
 
891
        # Delete all HList entries
892
        $Hlist delete all
893
 
894
        # Delete the variable objects
895
#       foreach i [array names Variables] {
896
#           $Variables($i) delete
897
#           unset Variables($i)
898
#           catch {unset Update($this,$i)}
899
#       }
900
    }
901
 
902
    # ------------------------------------------------------------------
903
    # METHOD:   enable_ui
904
    #           Enable all ui elements.
905
    # ------------------------------------------------------------------
906
    method enable_ui {} {
907
 
908
        # Clear fencepost
909
        set Running 0
910
        cursor {}
911
    }
912
 
913
    # ------------------------------------------------------------------
914
    #   PUBLIC METHOD:  busy - BusyEvent handler
915
    #           Disable all ui elements that could affect gdb's state
916
    # ------------------------------------------------------------------
917
    method busy {event} {
918
 
919
        # Set fencepost
920
        set Running 1
921
 
922
        # Cancel any edits
923
        if {[info exists EditEntry]} {
924
            UnEdit
925
        }
926
 
927
        # Change cursor
928
        cursor watch
929
    }
930
 
931
    # ------------------------------------------------------------------
932
    # METHOD:   no_inferior
933
    #           Reset this object.
934
    # ------------------------------------------------------------------
935
    method no_inferior {} {
936
 
937
        # Clear out the Hlist
938
        deleteTree
939
 
940
        # Clear fencepost
941
        set Running 0
942
        set _frame {}
943
        cursor {}
944
    }
945
 
946
    # ------------------------------------------------------------------
947
    #  METHOD:  cursor - change the toplevel's cursor
948
    # ------------------------------------------------------------------
949
    method cursor {what} {
950
        [winfo toplevel [namespace tail $this]] configure -cursor $what
951
        ::update idletasks
952
    }
953
 
954
    #
955
    # PUBLIC DATA
956
    #
957
 
958
    #
959
    #  PROTECTED DATA
960
    #
961
 
962
    # the tixTree widget for this class
963
    protected variable Tree  {}
964
 
965
    # the hlist of this widget
966
    protected variable Hlist {}
967
 
968
    # entry widgets which need to have their color changed back to black
969
    # when idle (used in conjunction with update)
970
    protected variable ChangeList {}
971
 
972
    protected variable ViewMenu
973
    protected variable Popup
974
 
975
    # These are for setting the indent level to an number of characters.
976
    # This will help clean the tree a little
977
    common EntryLength 15
978
    common Length 1
979
    common LengthString " "
980
 
981
    # These should be common... but deletion?
982
    # Display styles for HList
983
    protected variable HighlightTextStyle
984
    protected variable NormalTextStyle
985
    protected variable DisabledTextStyle
986
 
987
    protected variable Radix
988
 
989
    # Frame object for the selected frame
990
    protected variable _frame {}
991
 
992
    protected variable Editing {}
993
    protected variable EditEntry
994
 
995
    # Fencepost for enable/disable_ui and idle/busy hooks.
996
    protected variable Running 0
997
 
998
    # little queue for convenience
999
    protected variable _queue {}
1000
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.