"gcc -fno-builtin -Wall -Wwrite-strings -Wshadow" can be your friend.
[deliverable/binutils-gdb.git] / gdb / gdbtk.tcl
CommitLineData
4604b34c
SG
1# GDB GUI setup for GDB, the GNU debugger.
2# Copyright 1994, 1995
3# Free Software Foundation, Inc.
4
5# Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
6
7# This file is part of GDB.
8
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
754e5da2
SG
22
23set cfile Blank
006e71e9 24set wins($cfile) .src.text
754e5da2
SG
25set current_label {}
26set screen_height 0
27set screen_top 0
28set screen_bot 0
006e71e9 29set current_output_win .cmd.text
8532893d 30set cfunc NIL
86db943c 31set line_numbers 1
546b8ca7 32set breakpoint_file(-1) {[garbage]}
280c564c 33set disassemble_with_source nosource
86db943c 34
006e71e9
SG
35#option add *Foreground Black
36#option add *Background White
37#option add *Font -*-*-medium-r-normal--18-*-*-*-m-*-*-1
746d1df4 38tk colormodel . monochrome
754e5da2
SG
39
40proc echo string {puts stdout $string}
41
8532893d
SG
42if [info exists env(EDITOR)] then {
43 set editor $env(EDITOR)
44 } else {
45 set editor emacs
46}
47
48# GDB callbacks
49#
50# These functions are called by GDB (from C code) to do various things in
51# TK-land. All start with the prefix `gdbtk_tcl_' to make them easy to find.
52#
53
54#
55# GDB Callback:
56#
57# gdbtk_tcl_fputs (text) - Output text to the command window
58#
59# Description:
60#
61# GDB calls this to output TEXT to the GDB command window. The text is
62# placed at the end of the text widget. Note that output may not occur,
63# due to buffering. Use gdbtk_tcl_flush to cause an immediate update.
64#
65
754e5da2 66proc gdbtk_tcl_fputs {arg} {
8532893d
SG
67 global current_output_win
68
69 $current_output_win insert end "$arg"
70 $current_output_win yview -pickplace end
71}
72
86db943c
SG
73proc gdbtk_tcl_fputs_error {arg} {
74 .cmd.text insert end "$arg"
75 .cmd.text yview -pickplace end
76}
77
8532893d
SG
78#
79# GDB Callback:
80#
81# gdbtk_tcl_flush () - Flush output to the command window
82#
83# Description:
84#
85# GDB calls this to force all buffered text to the GDB command window.
86#
87
88proc gdbtk_tcl_flush {} {
546b8ca7
SG
89 global current_output_win
90
8532893d
SG
91 $current_output_win yview -pickplace end
92 update idletasks
754e5da2
SG
93}
94
8532893d
SG
95#
96# GDB Callback:
97#
98# gdbtk_tcl_query (message) - Create a yes/no query dialog box
99#
100# Description:
101#
102# GDB calls this to create a yes/no dialog box containing MESSAGE. GDB
103# is hung while the dialog box is active (ie: no commands will work),
104# however windows can still be refreshed in case of damage or exposure.
105#
754e5da2
SG
106
107proc gdbtk_tcl_query {message} {
108 tk_dialog .query "gdb : query" "$message" {} 1 "No" "Yes"
109 }
110
8532893d
SG
111#
112# GDB Callback:
113#
114# gdbtk_start_variable_annotation (args ...) -
115#
116# Description:
117#
118# Not yet implemented.
119#
754e5da2
SG
120
121proc gdbtk_tcl_start_variable_annotation {valaddr ref_type stor_cl cum_expr field type_cast} {
122 echo "gdbtk_tcl_start_variable_annotation $valaddr $ref_type $stor_cl $cum_expr $field $type_cast"
123}
124
8532893d
SG
125#
126# GDB Callback:
127#
128# gdbtk_end_variable_annotation (args ...) -
129#
130# Description:
131#
132# Not yet implemented.
133#
134
754e5da2
SG
135proc gdbtk_tcl_end_variable_annotation {} {
136 echo gdbtk_tcl_end_variable_annotation
137}
138
8532893d
SG
139#
140# GDB Callback:
141#
142# gdbtk_tcl_breakpoint (action bpnum file line) - Notify the TK
143# interface of changes to breakpoints.
144#
145# Description:
146#
147# GDB calls this to notify TK of changes to breakpoints. ACTION is one
148# of:
149# create - Notify of breakpoint creation
150# delete - Notify of breakpoint deletion
151# enable - Notify of breakpoint enabling
152# disable - Notify of breakpoint disabling
153#
154# All actions take the same set of arguments: BPNUM is the breakpoint
155# number, FILE is the source file and LINE is the line number, and PC is
156# the pc of the affected breakpoint.
157#
158
159proc gdbtk_tcl_breakpoint {action bpnum file line pc} {
160 ${action}_breakpoint $bpnum $file $line $pc
754e5da2
SG
161}
162
335129a9 163proc asm_win_name {funcname} {
546b8ca7
SG
164 if {$funcname == "*None*"} {return .asm.text}
165
335129a9
SG
166 regsub -all {\.} $funcname _ temp
167
168 return .asm.func_${temp}
169}
170
8532893d
SG
171#
172# Local procedure:
173#
174# create_breakpoint (bpnum file line pc) - Record breakpoint info in TK land
175#
176# Description:
177#
178# GDB calls this indirectly (through gdbtk_tcl_breakpoint) to notify TK
179# land of breakpoint creation. This consists of recording the file and
180# line number in the breakpoint_file and breakpoint_line arrays. Also,
181# if there is already a window associated with FILE, it is updated with
182# a breakpoint tag.
183#
184
185proc create_breakpoint {bpnum file line pc} {
754e5da2
SG
186 global wins
187 global breakpoint_file
188 global breakpoint_line
8532893d 189 global pos_to_breakpoint
335129a9 190 global pos_to_bpcount
8532893d
SG
191 global cfunc
192 global pclist
754e5da2
SG
193
194# Record breakpoint locations
195
196 set breakpoint_file($bpnum) $file
197 set breakpoint_line($bpnum) $line
8532893d 198 set pos_to_breakpoint($file:$line) $bpnum
335129a9
SG
199 if ![info exists pos_to_bpcount($file:$line)] {
200 set pos_to_bpcount($file:$line) 0
201 }
202 incr pos_to_bpcount($file:$line)
203 set pos_to_breakpoint($pc) $bpnum
204 if ![info exists pos_to_bpcount($pc)] {
205 set pos_to_bpcount($pc) 0
206 }
207 incr pos_to_bpcount($pc)
754e5da2 208
8532893d 209# If there's a window for this file, update it
754e5da2
SG
210
211 if [info exists wins($file)] {
212 insert_breakpoint_tag $wins($file) $line
213 }
8532893d
SG
214
215# If there's an assembly window, update that too
216
335129a9 217 set win [asm_win_name $cfunc]
8532893d 218 if [winfo exists $win] {
637b1661 219 insert_breakpoint_tag $win [pc_to_line $pclist($cfunc) $pc]
8532893d 220 }
754e5da2
SG
221}
222
8532893d
SG
223#
224# Local procedure:
225#
226# delete_breakpoint (bpnum file line pc) - Delete breakpoint info from TK land
227#
228# Description:
229#
230# GDB calls this indirectly (through gdbtk_tcl_breakpoint) to notify TK
231# land of breakpoint destruction. This consists of removing the file and
232# line number from the breakpoint_file and breakpoint_line arrays. Also,
233# if there is already a window associated with FILE, the tags are removed
234# from it.
235#
236
237proc delete_breakpoint {bpnum file line pc} {
754e5da2
SG
238 global wins
239 global breakpoint_file
240 global breakpoint_line
8532893d 241 global pos_to_breakpoint
335129a9
SG
242 global pos_to_bpcount
243 global cfunc pclist
754e5da2 244
8532893d 245# Save line number and file for later
754e5da2
SG
246
247 set line $breakpoint_line($bpnum)
248
8532893d
SG
249 set file $breakpoint_file($bpnum)
250
754e5da2
SG
251# Reset breakpoint annotation info
252
335129a9 253 if {$pos_to_bpcount($file:$line) > 0} {
637b1661 254 decr pos_to_bpcount($file:$line)
335129a9
SG
255
256 if {$pos_to_bpcount($file:$line) == 0} {
637b1661
SG
257 catch "unset pos_to_breakpoint($file:$line)"
258
335129a9
SG
259 unset breakpoint_file($bpnum)
260 unset breakpoint_line($bpnum)
754e5da2 261
8532893d 262# If there's a window for this file, update it
754e5da2 263
335129a9
SG
264 if [info exists wins($file)] {
265 delete_breakpoint_tag $wins($file) $line
266 }
267 }
268 }
269
270# If there's an assembly window, update that too
271
272 if {$pos_to_bpcount($pc) > 0} {
637b1661 273 decr pos_to_bpcount($pc)
335129a9
SG
274
275 if {$pos_to_bpcount($pc) == 0} {
637b1661
SG
276 catch "unset pos_to_breakpoint($pc)"
277
335129a9
SG
278 set win [asm_win_name $cfunc]
279 if [winfo exists $win] {
637b1661 280 delete_breakpoint_tag $win [pc_to_line $pclist($cfunc) $pc]
335129a9
SG
281 }
282 }
754e5da2
SG
283 }
284}
285
8532893d
SG
286#
287# Local procedure:
288#
289# enable_breakpoint (bpnum file line pc) - Record breakpoint info in TK land
290#
291# Description:
292#
293# GDB calls this indirectly (through gdbtk_tcl_breakpoint) to notify TK
294# land of a breakpoint being enabled. This consists of unstippling the
295# specified breakpoint indicator.
296#
297
298proc enable_breakpoint {bpnum file line pc} {
299 global wins
335129a9
SG
300 global cfunc pclist
301
302 if [info exists wins($file)] {
303 $wins($file) tag configure $line -fgstipple {}
304 }
754e5da2 305
335129a9
SG
306# If there's an assembly window, update that too
307
308 set win [asm_win_name $cfunc]
309 if [winfo exists $win] {
637b1661 310 $win tag configure [pc_to_line $pclist($cfunc) $pc] -fgstipple {}
335129a9 311 }
754e5da2
SG
312}
313
8532893d
SG
314#
315# Local procedure:
316#
317# disable_breakpoint (bpnum file line pc) - Record breakpoint info in TK land
318#
319# Description:
320#
321# GDB calls this indirectly (through gdbtk_tcl_breakpoint) to notify TK
322# land of a breakpoint being disabled. This consists of stippling the
323# specified breakpoint indicator.
324#
325
326proc disable_breakpoint {bpnum file line pc} {
327 global wins
335129a9
SG
328 global cfunc pclist
329
330 if [info exists wins($file)] {
331 $wins($file) tag configure $line -fgstipple gray50
332 }
754e5da2 333
335129a9
SG
334# If there's an assembly window, update that too
335
336 set win [asm_win_name $cfunc]
337 if [winfo exists $win] {
637b1661 338 $win tag configure [pc_to_line $pclist($cfunc) $pc] -fgstipple gray50
335129a9 339 }
8532893d
SG
340}
341
342#
343# Local procedure:
344#
345# insert_breakpoint_tag (win line) - Insert a breakpoint tag in WIN.
346#
347# Description:
348#
349# GDB calls this indirectly (through gdbtk_tcl_breakpoint) to insert a
350# breakpoint tag into window WIN at line LINE.
351#
754e5da2 352
8532893d
SG
353proc insert_breakpoint_tag {win line} {
354 $win configure -state normal
355 $win delete $line.0
356 $win insert $line.0 "B"
357 $win tag add $line $line.0
479f0f18
SG
358 $win tag add delete $line.0 "$line.0 lineend"
359 $win tag add margin $line.0 "$line.0 lineend"
8532893d
SG
360
361 $win configure -state disabled
362}
363
364#
365# Local procedure:
366#
367# delete_breakpoint_tag (win line) - Remove a breakpoint tag from WIN.
368#
369# Description:
370#
371# GDB calls this indirectly (through gdbtk_tcl_breakpoint) to remove a
372# breakpoint tag from window WIN at line LINE.
373#
374
375proc delete_breakpoint_tag {win line} {
376 $win configure -state normal
377 $win delete $line.0
746d1df4
SG
378 if {[string range $win 0 3] == ".src"} then {
379 $win insert $line.0 "\xa4"
380 } else {
381 $win insert $line.0 " "
382 }
8532893d 383 $win tag delete $line
479f0f18
SG
384 $win tag add delete $line.0 "$line.0 lineend"
385 $win tag add margin $line.0 "$line.0 lineend"
8532893d
SG
386 $win configure -state disabled
387}
754e5da2 388
479f0f18 389proc gdbtk_tcl_busy {} {
86db943c 390 if [winfo exists .src] {
546b8ca7
SG
391 catch {.src.start configure -state disabled}
392 catch {.src.stop configure -state normal}
393 catch {.src.step configure -state disabled}
394 catch {.src.next configure -state disabled}
395 catch {.src.continue configure -state disabled}
396 catch {.src.finish configure -state disabled}
397 catch {.src.up configure -state disabled}
398 catch {.src.down configure -state disabled}
399 catch {.src.bottom configure -state disabled}
86db943c
SG
400 }
401 if [winfo exists .asm] {
546b8ca7
SG
402 catch {.asm.stepi configure -state disabled}
403 catch {.asm.nexti configure -state disabled}
404 catch {.asm.continue configure -state disabled}
405 catch {.asm.finish configure -state disabled}
406 catch {.asm.up configure -state disabled}
407 catch {.asm.down configure -state disabled}
408 catch {.asm.bottom configure -state disabled}
409 catch {.asm.close configure -state disabled}
86db943c 410 }
479f0f18
SG
411}
412
413proc gdbtk_tcl_idle {} {
86db943c 414 if [winfo exists .src] {
546b8ca7
SG
415 catch {.src.start configure -state normal}
416 catch {.src.stop configure -state disabled}
417 catch {.src.step configure -state normal}
418 catch {.src.next configure -state normal}
419 catch {.src.continue configure -state normal}
420 catch {.src.finish configure -state normal}
421 catch {.src.up configure -state normal}
422 catch {.src.down configure -state normal}
423 catch {.src.bottom configure -state normal}
86db943c
SG
424 }
425
426 if [winfo exists .asm] {
546b8ca7
SG
427 catch {.asm.stepi configure -state normal}
428 catch {.asm.nexti configure -state normal}
429 catch {.asm.continue configure -state normal}
430 catch {.asm.finish configure -state normal}
431 catch {.asm.up configure -state normal}
432 catch {.asm.down configure -state normal}
433 catch {.asm.bottom configure -state normal}
434 catch {.asm.close configure -state normal}
86db943c 435 }
479f0f18
SG
436}
437
637b1661
SG
438#
439# Local procedure:
440#
441# decr (var val) - compliment to incr
442#
443# Description:
444#
445#
446proc decr {var {val 1}} {
447 upvar $var num
448 set num [expr $num - $val]
449 return $num
450}
451
452#
453# Local procedure:
454#
455# pc_to_line (pclist pc) - convert PC to a line number.
456#
457# Description:
458#
459# Convert PC to a line number from PCLIST. If exact line isn't found,
460# we return the first line that starts before PC.
461#
462proc pc_to_line {pclist pc} {
463 set line [lsearch -exact $pclist $pc]
464
465 if {$line >= 1} { return $line }
466
467 set line 1
468 foreach linepc [lrange $pclist 1 end] {
469 if {$pc < $linepc} { decr line ; return $line }
470 incr line
471 }
472 return [expr $line - 1]
473}
474
8532893d
SG
475#
476# Menu:
477#
478# file popup menu - Define the file popup menu.
479#
480# Description:
481#
482# This menu just contains a bunch of buttons that do various things to
483# the line under the cursor.
484#
485# Items:
486#
487# Edit - Run the editor (specified by the environment variable EDITOR) on
488# this file, at the current line.
489# Breakpoint - Set a breakpoint at the current line. This just shoves
490# a `break' command at GDB with the appropriate file and line
491# number. Eventually, GDB calls us back (at gdbtk_tcl_breakpoint)
492# to notify us of where the breakpoint needs to show up.
493#
494
495menu .file_popup -cursor hand2
496.file_popup add command -label "Not yet set" -state disabled
497.file_popup add separator
498.file_popup add command -label "Edit" -command {exec $editor +$selected_line $selected_file &}
499.file_popup add command -label "Set breakpoint" -command {gdb_cmd "break $selected_file:$selected_line"}
500
501#
502# Bindings:
503#
504# file popup menu - Define the file popup menu bindings.
505#
506# Description:
507#
508# This defines the binding for the file popup menu. Currently, there is
509# only one, which is activated when Button-1 is released. This causes
510# the menu to be unposted, releases the grab for the menu, and then
511# unhighlights the line under the cursor. After that, the selected menu
512# item is invoked.
513#
514
515bind .file_popup <Any-ButtonRelease-1> {
754e5da2
SG
516 global selected_win
517
518# First, remove the menu, and release the pointer
519
8532893d
SG
520 .file_popup unpost
521 grab release .file_popup
754e5da2
SG
522
523# Unhighlight the selected line
524
525 $selected_win tag delete breaktag
754e5da2
SG
526
527# Actually invoke the menubutton here!
528
529 tk_invokeMenu %W
754e5da2
SG
530}
531
8532893d
SG
532#
533# Local procedure:
534#
535# file_popup_menu (win x y xrel yrel) - Popup the file popup menu.
536#
537# Description:
538#
539# This procedure is invoked as a result of a command binding in the
540# listing window. It does several things:
541# o - It highlights the line under the cursor.
542# o - It pops up the file popup menu which is intended to do
543# various things to the aforementioned line.
544# o - Grabs the mouse for the file popup menu.
545#
546
754e5da2
SG
547# Button 1 has been pressed in a listing window. Pop up a menu.
548
8532893d 549proc file_popup_menu {win x y xrel yrel} {
754e5da2
SG
550 global wins
551 global win_to_file
552 global file_to_debug_file
553 global highlight
554 global selected_line
555 global selected_file
556 global selected_win
557
754e5da2
SG
558# Map TK window name back to file name.
559
560 set file $win_to_file($win)
561
562 set pos [$win index @$xrel,$yrel]
563
564# Record selected file and line for menu button actions
565
566 set selected_file $file_to_debug_file($file)
567 set selected_line [lindex [split $pos .] 0]
568 set selected_win $win
569
570# Highlight the selected line
571
572 eval $win tag config breaktag $highlight
573 $win tag add breaktag "$pos linestart" "$pos linestart + 1l"
574
575# Post the menu near the pointer, (and grab it)
576
8532893d
SG
577 .file_popup entryconfigure 0 -label "$selected_file:$selected_line"
578 .file_popup post [expr $x-[winfo width .file_popup]/2] [expr $y-10]
579 grab .file_popup
754e5da2
SG
580}
581
8532893d
SG
582#
583# Local procedure:
584#
585# listing_window_button_1 (win x y xrel yrel) - Handle button 1 in listing window
586#
587# Description:
588#
589# This procedure is invoked as a result of holding down button 1 in the
590# listing window. The action taken depends upon where the button was
591# pressed. If it was in the left margin (the breakpoint column), it
592# sets or clears a breakpoint. In the main text area, it will pop up a
593# menu.
594#
595
596proc listing_window_button_1 {win x y xrel yrel} {
597 global wins
598 global win_to_file
599 global file_to_debug_file
600 global highlight
601 global selected_line
602 global selected_file
603 global selected_win
604 global pos_to_breakpoint
605
606# Map TK window name back to file name.
607
608 set file $win_to_file($win)
609
610 set pos [split [$win index @$xrel,$yrel] .]
611
612# Record selected file and line for menu button actions
613
614 set selected_file $file_to_debug_file($file)
615 set selected_line [lindex $pos 0]
616 set selected_col [lindex $pos 1]
617 set selected_win $win
618
619# If we're in the margin, then toggle the breakpoint
620
621 if {$selected_col < 8} {
622 set pos_break $selected_file:$selected_line
623 set pos $file:$selected_line
624 set tmp pos_to_breakpoint($pos)
625 if [info exists $tmp] {
626 set bpnum [set $tmp]
627 gdb_cmd "delete $bpnum"
628 } else {
629 gdb_cmd "break $pos_break"
630 }
631 return
632 }
633
634# Post the menu near the pointer, (and grab it)
635
636 .file_popup entryconfigure 0 -label "$selected_file:$selected_line"
637 .file_popup post [expr $x-[winfo width .file_popup]/2] [expr $y-10]
638 grab .file_popup
639}
640
641#
642# Local procedure:
643#
644# asm_window_button_1 (win x y xrel yrel) - Handle button 1 in asm window
645#
646# Description:
647#
648# This procedure is invoked as a result of holding down button 1 in the
649# assembly window. The action taken depends upon where the button was
650# pressed. If it was in the left margin (the breakpoint column), it
651# sets or clears a breakpoint. In the main text area, it will pop up a
652# menu.
653#
654
655proc asm_window_button_1 {win x y xrel yrel} {
656 global wins
657 global win_to_file
658 global file_to_debug_file
659 global highlight
660 global selected_line
661 global selected_file
662 global selected_win
663 global pos_to_breakpoint
664 global pclist
665 global cfunc
666
667 set pos [split [$win index @$xrel,$yrel] .]
668
669# Record selected file and line for menu button actions
670
671 set selected_line [lindex $pos 0]
672 set selected_col [lindex $pos 1]
673 set selected_win $win
674
675# Figure out the PC
676
677 set pc [lindex $pclist($cfunc) $selected_line]
678
679# If we're in the margin, then toggle the breakpoint
680
746d1df4 681 if {$selected_col < 11} {
8532893d
SG
682 set tmp pos_to_breakpoint($pc)
683 if [info exists $tmp] {
684 set bpnum [set $tmp]
685 gdb_cmd "delete $bpnum"
686 } else {
687 gdb_cmd "break *$pc"
688 }
689 return
690 }
691
692# Post the menu near the pointer, (and grab it)
693
694# .file_popup entryconfigure 0 -label "$selected_file:$selected_line"
695# .file_popup post [expr $x-[winfo width .file_popup]/2] [expr $y-10]
696# grab .file_popup
697}
698
699#
700# Local procedure:
701#
e12533e3 702# do_nothing - Does absolutely nothing.
8532893d
SG
703#
704# Description:
705#
706# This procedure does nothing. It is used as a placeholder to allow
707# the disabling of bindings that would normally be inherited from the
708# parent widget. I can't think of any other way to do this.
709#
710
754e5da2
SG
711proc do_nothing {} {}
712
479f0f18
SG
713#
714# Local procedure:
715#
e12533e3
SS
716# not_implemented_yet - warn that a feature is unavailable
717#
718# Description:
719#
720# This procedure warns that something doesn't actually work yet.
721#
722
723proc not_implemented_yet {message} {
c4a5c37c
SS
724 tk_dialog .unimpl "gdb : unimpl" \
725 "$message: not implemented in the interface yet" \
e12533e3
SS
726 {} 1 "OK"
727}
728
729##
730# Local procedure:
731#
c4a5c37c 732# create_expr_win - Create expression display window
479f0f18
SG
733#
734# Description:
735#
736# Create the expression display window.
737#
738
09722039
SG
739set expr_num 0
740
741proc add_expr {expr} {
742 global expr_update_list
743 global expr_num
744
745 incr expr_num
746
747 set e .expr.e${expr_num}
748
749 frame $e
750
751 checkbutton $e.update -text " " -relief flat \
752 -variable expr_update_list($expr_num)
280c564c
SG
753 text $e.expr -width 20 -height 1
754 $e.expr insert 0.0 $expr
09722039 755 bind $e.expr <1> "update_expr $expr_num"
280c564c 756 text $e.val -width 20 -height 1
09722039
SG
757
758 update_expr $expr_num
759
760 pack $e.update -side left -anchor nw
280c564c 761 pack $e.expr $e.val -side left -expand yes -fill x
09722039
SG
762
763 pack $e -side top -fill x -anchor w
764}
765
766set delete_expr_flag 0
767
768# This is a krock!!!
769
770proc delete_expr {} {
771 global delete_expr_flag
772
773 if {$delete_expr_flag == 1} {
774 set delete_expr_flag 0
775 tk_butUp .expr.delete
776 bind .expr.delete <Any-Leave> {}
777 } else {
778 set delete_expr_flag 1
779 bind .expr.delete <Any-Leave> do_nothing
780 tk_butDown .expr.delete
781 }
782}
783
784proc update_expr {expr_num} {
785 global delete_expr_flag
280c564c 786 global expr_update_list
09722039
SG
787
788 set e .expr.e${expr_num}
789
790 if {$delete_expr_flag == 1} {
791 set delete_expr_flag 0
792 destroy $e
793 tk_butUp .expr.delete
794 tk_butLeave .expr.delete
795 bind .expr.delete <Any-Leave> {}
280c564c 796 unset expr_update_list($expr_num)
09722039
SG
797 return
798 }
799
280c564c
SG
800 set expr [$e.expr get 0.0 end]
801
802 $e.val delete 0.0 end
803 if [catch "gdb_eval $expr" val] {
804
805 } else {
806 $e.val insert 0.0 $val
807 }
808}
809
810proc update_exprs {} {
811 global expr_update_list
09722039 812
280c564c
SG
813 foreach expr_num [array names expr_update_list] {
814 if $expr_update_list($expr_num) {
815 update_expr $expr_num
816 }
817 }
09722039
SG
818}
819
479f0f18 820proc create_expr_win {} {
280c564c
SG
821
822 if [winfo exists .expr] {raise .expr ; return}
823
479f0f18
SG
824 toplevel .expr
825 wm minsize .expr 1 1
826 wm title .expr Expression
09722039 827 wm iconname .expr "Reg config"
479f0f18 828
09722039 829 frame .expr.entryframe
479f0f18 830
09722039
SG
831 entry .expr.entry -borderwidth 2 -relief sunken
832 bind .expr <Enter> {focus .expr.entry}
833 bind .expr.entry <Key-Return> {add_expr [.expr.entry get]
834 .expr.entry delete 0 end }
835
836 label .expr.entrylab -text "Expression: "
837
838 pack .expr.entrylab -in .expr.entryframe -side left
839 pack .expr.entry -in .expr.entryframe -side left -fill x -expand yes
840
841 frame .expr.buts
842
843 button .expr.delete -text Delete
844 bind .expr.delete <1> delete_expr
845
846 button .expr.close -text Close -command {destroy .expr}
847
848 pack .expr.delete -side left -fill x -expand yes -in .expr.buts
849 pack .expr.close -side right -fill x -expand yes -in .expr.buts
850
851 pack .expr.buts -side bottom -fill x
852 pack .expr.entryframe -side bottom -fill x
853
854 frame .expr.labels
855
856 label .expr.updlab -text Update
857 label .expr.exprlab -text Expression
858 label .expr.vallab -text Value
859
860 pack .expr.updlab -side left -in .expr.labels
861 pack .expr.exprlab .expr.vallab -side left -in .expr.labels -expand yes -anchor w
862
863 pack .expr.labels -side top -fill x -anchor w
479f0f18
SG
864}
865
866#
867# Local procedure:
868#
869# display_expression (expression) - Display EXPRESSION in display window
870#
871# Description:
872#
e12533e3 873# Display EXPRESSION and its value in the expression display window.
479f0f18
SG
874#
875
876proc display_expression {expression} {
280c564c 877 create_expr_win
479f0f18 878
09722039 879 add_expr $expression
479f0f18
SG
880}
881
8532893d
SG
882#
883# Local procedure:
884#
885# create_file_win (filename) - Create a win for FILENAME.
886#
887# Return value:
888#
889# The new text widget.
890#
891# Description:
892#
893# This procedure creates a text widget for FILENAME. It returns the
894# newly created widget. First, a text widget is created, and given basic
895# configuration info. Second, all the bindings are setup. Third, the
896# file FILENAME is read into the text widget. Fourth, margins and line
897# numbers are added.
898#
899
746d1df4 900proc create_file_win {filename debug_file} {
754e5da2
SG
901 global breakpoint_file
902 global breakpoint_line
86db943c 903 global line_numbers
754e5da2 904
8532893d
SG
905# Replace all the dirty characters in $filename with clean ones, and generate
906# a unique name for the text widget.
907
746d1df4 908 regsub -all {\.} $filename {} temp
006e71e9 909 set win .src.text$temp
8532893d 910
637b1661
SG
911# Open the file, and read it into the text widget
912
913 if [catch "open $filename" fh] {
746d1df4
SG
914# File can't be read. Put error message into .src.nofile window and return.
915
916 catch {destroy .src.nofile}
917 text .src.nofile -height 25 -width 88 -relief raised \
918 -borderwidth 2 -yscrollcommand textscrollproc \
919 -setgrid true -cursor hand2
920 .src.nofile insert 0.0 $fh
921 .src.nofile configure -state disabled
922 bind .src.nofile <1> do_nothing
923 bind .src.nofile <B1-Motion> do_nothing
924 return .src.nofile
637b1661
SG
925 }
926
8532893d
SG
927# Actually create and do basic configuration on the text widget.
928
746d1df4
SG
929 text $win -height 25 -width 88 -relief raised -borderwidth 2 \
930 -yscrollcommand textscrollproc -setgrid true -cursor hand2
8532893d
SG
931
932# Setup all the bindings
933
754e5da2 934 bind $win <Enter> {focus %W}
479f0f18
SG
935# bind $win <1> {listing_window_button_1 %W %X %Y %x %y}
936 bind $win <1> do_nothing
754e5da2 937 bind $win <B1-Motion> do_nothing
479f0f18 938
86db943c
SG
939 bind $win n {catch {gdb_cmd next} ; update_ptr}
940 bind $win s {catch {gdb_cmd step} ; update_ptr}
941 bind $win c {catch {gdb_cmd continue} ; update_ptr}
942 bind $win f {catch {gdb_cmd finish} ; update_ptr}
943 bind $win u {catch {gdb_cmd up} ; update_ptr}
944 bind $win d {catch {gdb_cmd down} ; update_ptr}
8532893d 945
754e5da2
SG
946 $win delete 0.0 end
947 $win insert 0.0 [read $fh]
948 close $fh
8532893d 949
86db943c 950# Add margins (for annotations) and a line number to each line (if requested)
8532893d 951
754e5da2
SG
952 set numlines [$win index end]
953 set numlines [lindex [split $numlines .] 0]
86db943c
SG
954 if $line_numbers {
955 for {set i 1} {$i <= $numlines} {incr i} {
956 $win insert $i.0 [format " %4d " $i]
957 $win tag add source $i.8 "$i.0 lineend"
958 }
959 } else {
960 for {set i 1} {$i <= $numlines} {incr i} {
961 $win insert $i.0 " "
962 $win tag add source $i.8 "$i.0 lineend"
963 }
964 }
479f0f18 965
746d1df4
SG
966# Add the breakdots
967
968 foreach i [gdb_sourcelines $debug_file] {
969 $win delete $i.0
970 $win insert $i.0 "\xa4"
971 $win tag add margin $i.0 $i.8
972 }
973
479f0f18
SG
974 $win tag bind margin <1> {listing_window_button_1 %W %X %Y %x %y}
975 $win tag bind source <1> {
976 %W mark set anchor "@%x,%y wordstart"
977 set last [%W index "@%x,%y wordend"]
978 %W tag remove sel 0.0 anchor
979 %W tag remove sel $last end
980 %W tag add sel anchor $last
981 }
982# $win tag bind source <Double-Button-1> {
983# %W mark set anchor "@%x,%y wordstart"
984# set last [%W index "@%x,%y wordend"]
985# %W tag remove sel 0.0 anchor
986# %W tag remove sel $last end
987# %W tag add sel anchor $last
988# echo "Selected [selection get]"
989# }
990 $win tag bind source <B1-Motion> {
991 %W tag remove sel 0.0 anchor
992 %W tag remove sel $last end
993 %W tag add sel anchor @%x,%y
754e5da2 994 }
479f0f18
SG
995 $win tag bind sel <1> do_nothing
996 $win tag bind sel <Double-Button-1> {display_expression [selection get]}
997 $win tag raise sel
998
754e5da2 999
8532893d
SG
1000# Scan though the breakpoint data base and install any destined for this file
1001
754e5da2
SG
1002 foreach bpnum [array names breakpoint_file] {
1003 if {$breakpoint_file($bpnum) == $filename} {
1004 insert_breakpoint_tag $win $breakpoint_line($bpnum)
1005 }
1006 }
1007
8532893d
SG
1008# Disable the text widget to prevent user modifications
1009
754e5da2
SG
1010 $win configure -state disabled
1011 return $win
1012}
1013
8532893d
SG
1014#
1015# Local procedure:
1016#
637b1661 1017# create_asm_win (funcname pc) - Create an assembly win for FUNCNAME.
8532893d
SG
1018#
1019# Return value:
1020#
1021# The new text widget.
1022#
1023# Description:
1024#
1025# This procedure creates a text widget for FUNCNAME. It returns the
1026# newly created widget. First, a text widget is created, and given basic
1027# configuration info. Second, all the bindings are setup. Third, the
1028# function FUNCNAME is read into the text widget.
1029#
1030
637b1661 1031proc create_asm_win {funcname pc} {
8532893d
SG
1032 global breakpoint_file
1033 global breakpoint_line
1034 global current_output_win
1035 global pclist
280c564c 1036 global disassemble_with_source
8532893d
SG
1037
1038# Replace all the dirty characters in $filename with clean ones, and generate
1039# a unique name for the text widget.
1040
335129a9 1041 set win [asm_win_name $funcname]
8532893d
SG
1042
1043# Actually create and do basic configuration on the text widget.
1044
09722039 1045 text $win -height 25 -width 80 -relief raised -borderwidth 2 \
8532893d
SG
1046 -setgrid true -cursor hand2 -yscrollcommand asmscrollproc
1047
1048# Setup all the bindings
1049
1050 bind $win <Enter> {focus %W}
1051 bind $win <1> {asm_window_button_1 %W %X %Y %x %y}
1052 bind $win <B1-Motion> do_nothing
86db943c
SG
1053 bind $win n {catch {gdb_cmd nexti} ; update_ptr}
1054 bind $win s {catch {gdb_cmd stepi} ; update_ptr}
1055 bind $win c {catch {gdb_cmd continue} ; update_ptr}
1056 bind $win f {catch {gdb_cmd finish} ; update_ptr}
1057 bind $win u {catch {gdb_cmd up} ; update_ptr}
1058 bind $win d {catch {gdb_cmd down} ; update_ptr}
8532893d
SG
1059
1060# Disassemble the code, and read it into the new text widget
1061
006e71e9 1062 set temp $current_output_win
8532893d 1063 set current_output_win $win
280c564c 1064 catch "gdb_disassemble $disassemble_with_source $pc"
006e71e9 1065 set current_output_win $temp
8532893d
SG
1066
1067 set numlines [$win index end]
1068 set numlines [lindex [split $numlines .] 0]
637b1661 1069 decr numlines
8532893d
SG
1070
1071# Delete the first and last lines, cuz these contain useless info
1072
09722039
SG
1073# $win delete 1.0 2.0
1074# $win delete {end - 1 lines} end
1075# decr numlines 2
8532893d
SG
1076
1077# Add margins (for annotations) and note the PC for each line
1078
637b1661 1079 catch "unset pclist($funcname)"
335129a9 1080 lappend pclist($funcname) Unused
8532893d
SG
1081 for {set i 1} {$i <= $numlines} {incr i} {
1082 scan [$win get $i.0 "$i.0 lineend"] "%s " pc
1083 lappend pclist($funcname) $pc
1084 $win insert $i.0 " "
1085 }
1086
8532893d
SG
1087# Scan though the breakpoint data base and install any destined for this file
1088
1089# foreach bpnum [array names breakpoint_file] {
1090# if {$breakpoint_file($bpnum) == $filename} {
1091# insert_breakpoint_tag $win $breakpoint_line($bpnum)
1092# }
1093# }
1094
1095# Disable the text widget to prevent user modifications
1096
1097 $win configure -state disabled
1098 return $win
1099}
1100
1101#
1102# Local procedure:
1103#
1104# asmscrollproc (WINHEIGHT SCREENHEIGHT SCREENTOP SCREENBOT) - Update the
1105# asm window scrollbar.
1106#
1107# Description:
1108#
1109# This procedure is called to update the assembler window's scrollbar.
1110#
1111
1112proc asmscrollproc {args} {
1113 global asm_screen_height asm_screen_top asm_screen_bot
1114
1115 eval ".asm.scroll set $args"
1116 set asm_screen_height [lindex $args 1]
1117 set asm_screen_top [lindex $args 2]
1118 set asm_screen_bot [lindex $args 3]
1119}
1120
1121#
1122# Local procedure:
1123#
1124# update_listing (linespec) - Update the listing window according to
1125# LINESPEC.
1126#
1127# Description:
1128#
1129# This procedure is called from various places to update the listing
1130# window based on LINESPEC. It is usually invoked with the result of
1131# gdb_loc.
1132#
1133# It will move the cursor, and scroll the text widget if necessary.
1134# Also, it will switch to another text widget if necessary, and update
1135# the label widget too.
1136#
1137# LINESPEC is a list of the form:
1138#
1139# { DEBUG_FILE FUNCNAME FILENAME LINE }, where:
1140#
1141# DEBUG_FILE - is the abbreviated form of the file name. This is usually
1142# the file name string given to the cc command. This is
1143# primarily needed for breakpoint commands, and when an
1144# abbreviated for of the filename is desired.
1145# FUNCNAME - is the name of the function.
1146# FILENAME - is the fully qualified (absolute) file name. It is usually
1147# the same as $PWD/$DEBUG_FILE, where PWD is the working dir
1148# at the time the cc command was given. This is used to
1149# actually locate the file to be displayed.
1150# LINE - The line number to be displayed.
1151#
1152# Usually, this procedure will just move the cursor one line down to the
1153# next line to be executed. However, if the cursor moves out of range
1154# or into another file, it will scroll the text widget so that the line
1155# of interest is in the middle of the viewable portion of the widget.
1156#
1157
754e5da2
SG
1158proc update_listing {linespec} {
1159 global pointers
1160 global screen_height
1161 global screen_top
1162 global screen_bot
1163 global wins cfile
1164 global current_label
1165 global win_to_file
1166 global file_to_debug_file
746d1df4 1167 global .src.label
754e5da2 1168
8532893d
SG
1169# Rip the linespec apart
1170
754e5da2
SG
1171 set line [lindex $linespec 3]
1172 set filename [lindex $linespec 2]
1173 set funcname [lindex $linespec 1]
1174 set debug_file [lindex $linespec 0]
1175
8532893d
SG
1176# Sometimes there's no source file for this location
1177
754e5da2
SG
1178 if {$filename == ""} {set filename Blank}
1179
8532893d
SG
1180# If we want to switch files, we need to unpack the current text widget, and
1181# stick in the new one.
1182
754e5da2
SG
1183 if {$filename != $cfile} then {
1184 pack forget $wins($cfile)
1185 set cfile $filename
8532893d
SG
1186
1187# Create a text widget for this file if necessary
1188
754e5da2 1189 if ![info exists wins($cfile)] then {
746d1df4
SG
1190 set wins($cfile) [create_file_win $cfile $debug_file]
1191 if {$wins($cfile) != ".src.nofile"} {
637b1661
SG
1192 set win_to_file($wins($cfile)) $cfile
1193 set file_to_debug_file($cfile) $debug_file
1194 set pointers($cfile) 1.1
1195 }
754e5da2
SG
1196 }
1197
8532893d
SG
1198# Pack the text widget into the listing widget, and scroll to the right place
1199
746d1df4
SG
1200 pack $wins($cfile) -side left -expand yes -in .src.info \
1201 -fill both -after .src.scroll
1202
1203# Make the scrollbar point at the new text widget
1204
1205 .src.scroll configure -command "$wins($cfile) yview"
1206
754e5da2
SG
1207 $wins($cfile) yview [expr $line - $screen_height / 2]
1208 }
1209
8532893d
SG
1210# Update the label widget in case the filename or function name has changed
1211
754e5da2
SG
1212 if {$current_label != "$filename.$funcname"} then {
1213 set tail [expr [string last / $filename] + 1]
746d1df4
SG
1214 set .src.label "[string range $filename $tail end] : ${funcname}()"
1215# .src.label configure -text "[string range $filename $tail end] : ${funcname}()"
754e5da2
SG
1216 set current_label $filename.$funcname
1217 }
1218
8532893d
SG
1219# Update the pointer, scrolling the text widget if necessary to keep the
1220# pointer in an acceptable part of the screen.
1221
754e5da2
SG
1222 if [info exists pointers($cfile)] then {
1223 $wins($cfile) configure -state normal
1224 set pointer_pos $pointers($cfile)
1225 $wins($cfile) configure -state normal
746d1df4
SG
1226 $wins($cfile) delete $pointer_pos "$pointer_pos + 2 char"
1227 $wins($cfile) insert $pointer_pos " "
754e5da2
SG
1228
1229 set pointer_pos [$wins($cfile) index $line.1]
1230 set pointers($cfile) $pointer_pos
1231
746d1df4
SG
1232 $wins($cfile) delete $pointer_pos "$pointer_pos + 2 char"
1233 $wins($cfile) insert $pointer_pos "->"
754e5da2
SG
1234
1235 if {$line < $screen_top + 1
1236 || $line > $screen_bot} then {
1237 $wins($cfile) yview [expr $line - $screen_height / 2]
1238 }
1239
1240 $wins($cfile) configure -state disabled
1241 }
1242}
1243
8532893d
SG
1244#
1245# Local procedure:
1246#
746d1df4 1247# create_asm_window - Open up the assembly window.
8532893d
SG
1248#
1249# Description:
1250#
1251# Create an assembly window if it doesn't exist.
1252#
1253
746d1df4 1254proc create_asm_window {} {
8532893d
SG
1255 global cfunc
1256
280c564c
SG
1257 if [winfo exists .asm] {raise .asm ; return}
1258
1259 set cfunc *None*
1260 set win [asm_win_name $cfunc]
335129a9 1261
280c564c 1262 build_framework .asm Assembly "*NIL*"
006e71e9 1263
09722039
SG
1264# First, delete all the old menu entries
1265
280c564c 1266 .asm.menubar.view.menu delete 0 last
09722039 1267
280c564c 1268 .asm.text configure -yscrollcommand asmscrollproc
8532893d 1269
280c564c
SG
1270 frame .asm.row1
1271 frame .asm.row2
8532893d 1272
280c564c
SG
1273 button .asm.stepi -width 6 -text Stepi \
1274 -command {catch {gdb_cmd stepi} ; update_ptr}
1275 button .asm.nexti -width 6 -text Nexti \
1276 -command {catch {gdb_cmd nexti} ; update_ptr}
1277 button .asm.continue -width 6 -text Cont \
1278 -command {catch {gdb_cmd continue} ; update_ptr}
1279 button .asm.finish -width 6 -text Finish \
1280 -command {catch {gdb_cmd finish} ; update_ptr}
1281 button .asm.up -width 6 -text Up -command {catch {gdb_cmd up} ; update_ptr}
1282 button .asm.down -width 6 -text Down \
1283 -command {catch {gdb_cmd down} ; update_ptr}
1284 button .asm.bottom -width 6 -text Bottom \
1285 -command {catch {gdb_cmd {frame 0}} ; update_ptr}
8532893d 1286
280c564c
SG
1287 pack .asm.stepi .asm.continue .asm.up .asm.bottom -side left -padx 3 -pady 5 -in .asm.row1
1288 pack .asm.nexti .asm.finish .asm.down -side left -padx 3 -pady 5 -in .asm.row2
006e71e9 1289
280c564c 1290 pack .asm.row2 .asm.row1 -side bottom -anchor w -before .asm.info
8532893d 1291
280c564c 1292 update
006e71e9 1293
280c564c 1294 update_assembly [gdb_loc]
09722039
SG
1295
1296# We do this update_assembly to get the proper value of disassemble-from-exec.
1297
1298# exec file menu item
280c564c
SG
1299 .asm.menubar.view.menu add radiobutton -label "Exec file" \
1300 -variable disassemble-from-exec -value 1
09722039 1301# target memory menu item
280c564c
SG
1302 .asm.menubar.view.menu add radiobutton -label "Target memory" \
1303 -variable disassemble-from-exec -value 0
1304
1305# Disassemble with source
1306 .asm.menubar.view.menu add checkbutton -label "Source" \
1307 -variable disassemble_with_source -onvalue source \
1308 -offvalue nosource -command {
1309 foreach asm [info command .asm.func_*] {
1310 destroy $asm
1311 }
1312 set cfunc NIL
1313 update_assembly [gdb_loc]
1314 }
8532893d
SG
1315}
1316
746d1df4 1317proc reg_config_menu {} {
746d1df4
SG
1318 catch {destroy .reg.config}
1319 toplevel .reg.config
1320 wm geometry .reg.config +300+300
1321 wm title .reg.config "Register configuration"
1322 wm iconname .reg.config "Reg config"
1323 set regnames [gdb_regnames]
1324 set num_regs [llength $regnames]
1325
86db943c
SG
1326 frame .reg.config.buts
1327
1328 button .reg.config.done -text " Done " -command "
1329 recompute_reg_display_list $num_regs
1330 populate_reg_window
1331 update_registers all
1332 destroy .reg.config "
1333
1334 button .reg.config.update -text Update -command "
1335 recompute_reg_display_list $num_regs
1336 populate_reg_window
1337 update_registers all "
1338
1339 pack .reg.config.buts -side bottom -fill x
746d1df4 1340
86db943c
SG
1341 pack .reg.config.done -side left -fill x -expand yes -in .reg.config.buts
1342 pack .reg.config.update -side right -fill x -expand yes -in .reg.config.buts
746d1df4
SG
1343
1344# Since there can be lots of registers, we build the window with no more than
1345# 32 rows, and as many columns as needed.
1346
1347# First, figure out how many columns we need and create that many column frame
1348# widgets
1349
1350 set ncols [expr ($num_regs + 31) / 32]
1351
1352 for {set col 0} {$col < $ncols} {incr col} {
1353 frame .reg.config.col$col
1354 pack .reg.config.col$col -side left -anchor n
1355 }
1356
1357# Now, create the checkbutton widgets and pack them in the appropriate columns
1358
1359 set col 0
1360 set row 0
1361 for {set regnum 0} {$regnum < $num_regs} {incr regnum} {
1362 set regname [lindex $regnames $regnum]
1363 checkbutton .reg.config.col$col.$row -text $regname -pady 0 \
86db943c 1364 -variable regena($regnum) -relief flat -anchor w -bd 1
746d1df4
SG
1365
1366 pack .reg.config.col$col.$row -side top -fill both
1367
1368 incr row
1369 if {$row >= 32} {
1370 incr col
1371 set row 0
1372 }
1373 }
1374}
1375
335129a9
SG
1376#
1377# Local procedure:
1378#
746d1df4 1379# create_registers_window - Open up the register display window.
335129a9
SG
1380#
1381# Description:
1382#
1383# Create the register display window, with automatic updates.
1384#
1385
746d1df4
SG
1386proc create_registers_window {} {
1387 global reg_format
1388
280c564c 1389 if [winfo exists .reg] {raise .reg ; return}
746d1df4
SG
1390
1391# Create an initial register display list consisting of all registers
1392
1393 if ![info exists reg_format] {
1394 global reg_display_list
1395 global changed_reg_list
cb3313c1 1396 global regena
746d1df4
SG
1397
1398 set reg_format {}
1399 set num_regs [llength [gdb_regnames]]
1400 for {set regnum 0} {$regnum < $num_regs} {incr regnum} {
cb3313c1 1401 set regena($regnum) 1
746d1df4
SG
1402 }
1403 recompute_reg_display_list $num_regs
1404 set changed_reg_list $reg_display_list
1405 }
1406
1407 build_framework .reg Registers
1408
86db943c
SG
1409# First, delete all the old menu entries
1410
1411 .reg.menubar.view.menu delete 0 last
746d1df4
SG
1412
1413# Hex menu item
86db943c
SG
1414 .reg.menubar.view.menu add radiobutton -variable reg_format \
1415 -label Hex -value x -command {update_registers all}
746d1df4 1416
746d1df4 1417# Decimal menu item
86db943c
SG
1418 .reg.menubar.view.menu add radiobutton -variable reg_format \
1419 -label Decimal -value d -command {update_registers all}
746d1df4 1420
746d1df4 1421# Octal menu item
86db943c
SG
1422 .reg.menubar.view.menu add radiobutton -variable reg_format \
1423 -label Octal -value o -command {update_registers all}
746d1df4 1424
746d1df4 1425# Natural menu item
86db943c
SG
1426 .reg.menubar.view.menu add radiobutton -variable reg_format \
1427 -label Natural -value {} -command {update_registers all}
746d1df4 1428
86db943c
SG
1429# Config menu item
1430 .reg.menubar.view.menu add separator
1431
1432 .reg.menubar.view.menu add command -label Config -command {
1433 reg_config_menu }
746d1df4
SG
1434
1435 destroy .reg.label
1436
1437# Install the reg names
1438
1439 populate_reg_window
86db943c 1440 update_registers all
746d1df4
SG
1441}
1442
cb3313c1 1443# Convert regena into a list of the enabled $regnums
746d1df4
SG
1444
1445proc recompute_reg_display_list {num_regs} {
1446 global reg_display_list
cb3313c1
SG
1447 global regmap
1448 global regena
746d1df4
SG
1449
1450 catch {unset reg_display_list}
cb3313c1
SG
1451
1452 set line 1
746d1df4 1453 for {set regnum 0} {$regnum < $num_regs} {incr regnum} {
746d1df4 1454
cb3313c1 1455 if {[set regena($regnum)] != 0} {
746d1df4 1456 lappend reg_display_list $regnum
cb3313c1
SG
1457 set regmap($regnum) $line
1458 incr line
746d1df4
SG
1459 }
1460 }
1461}
1462
1463# Fill out the register window with the names of the regs specified in
1464# reg_display_list.
1465
1466proc populate_reg_window {} {
1467 global max_regname_width
1468 global reg_display_list
1469
1470 .reg.text configure -state normal
1471
1472 .reg.text delete 0.0 end
1473
1474 set regnames [eval gdb_regnames $reg_display_list]
1475
1476# Figure out the longest register name
335129a9 1477
746d1df4 1478 set max_regname_width 0
335129a9 1479
746d1df4
SG
1480 foreach reg $regnames {
1481 set len [string length $reg]
1482 if {$len > $max_regname_width} {set max_regname_width $len}
1483 }
1484
1485 set width [expr $max_regname_width + 15]
1486
1487 set height [llength $regnames]
1488
1489 if {$height > 60} {set height 60}
335129a9 1490
746d1df4
SG
1491 .reg.text configure -height $height -width $width
1492
1493 foreach reg $regnames {
1494 .reg.text insert end [format "%-*s \n" $max_regname_width ${reg}]
335129a9 1495 }
746d1df4
SG
1496
1497 .reg.text yview 0
1498 .reg.text configure -state disabled
335129a9
SG
1499}
1500
1501#
1502# Local procedure:
1503#
1504# update_registers - Update the registers window.
1505#
1506# Description:
1507#
1508# This procedure updates the registers window.
1509#
1510
746d1df4
SG
1511proc update_registers {which} {
1512 global max_regname_width
1513 global reg_format
1514 global reg_display_list
1515 global changed_reg_list
1516 global highlight
cb3313c1 1517 global regmap
335129a9 1518
746d1df4 1519 set margin [expr $max_regname_width + 1]
006e71e9 1520 set win .reg.text
746d1df4
SG
1521 set winwidth [lindex [$win configure -width] 4]
1522 set valwidth [expr $winwidth - $margin]
335129a9
SG
1523
1524 $win configure -state normal
1525
746d1df4 1526 if {$which == "all"} {
cb3313c1 1527 set lineindex 1
746d1df4
SG
1528 foreach regnum $reg_display_list {
1529 set regval [gdb_fetch_registers $reg_format $regnum]
1530 set regval [format "%-*s" $valwidth $regval]
cb3313c1
SG
1531 $win delete $lineindex.$margin "$lineindex.0 lineend"
1532 $win insert $lineindex.$margin $regval
1533 incr lineindex
746d1df4
SG
1534 }
1535 $win configure -state disabled
1536 return
1537 }
335129a9 1538
746d1df4
SG
1539# Unhighlight the old values
1540
1541 foreach regnum $changed_reg_list {
1542 $win tag delete $win.$regnum
1543 }
1544
1545# Now, highlight the changed values of the interesting registers
1546
1547 set changed_reg_list [eval gdb_changed_register_list $reg_display_list]
1548
cb3313c1 1549 set lineindex 1
746d1df4
SG
1550 foreach regnum $changed_reg_list {
1551 set regval [gdb_fetch_registers $reg_format $regnum]
1552 set regval [format "%-*s" $valwidth $regval]
cb3313c1
SG
1553
1554 set lineindex $regmap($regnum)
746d1df4
SG
1555 $win delete $lineindex.$margin "$lineindex.0 lineend"
1556 $win insert $lineindex.$margin $regval
1557 $win tag add $win.$regnum $lineindex.0 "$lineindex.0 lineend"
1558 eval $win tag configure $win.$regnum $highlight
1559 }
335129a9 1560
335129a9
SG
1561 $win configure -state disabled
1562}
1563
8532893d
SG
1564#
1565# Local procedure:
1566#
1567# update_assembly - Update the assembly window.
1568#
1569# Description:
1570#
1571# This procedure updates the assembly window.
1572#
1573
1574proc update_assembly {linespec} {
1575 global asm_pointers
1576 global screen_height
1577 global screen_top
1578 global screen_bot
1579 global wins cfunc
1580 global current_label
1581 global win_to_file
1582 global file_to_debug_file
1583 global current_asm_label
1584 global pclist
1585 global asm_screen_height asm_screen_top asm_screen_bot
746d1df4 1586 global .asm.label
8532893d
SG
1587
1588# Rip the linespec apart
1589
1590 set pc [lindex $linespec 4]
1591 set line [lindex $linespec 3]
1592 set filename [lindex $linespec 2]
1593 set funcname [lindex $linespec 1]
1594 set debug_file [lindex $linespec 0]
1595
335129a9 1596 set win [asm_win_name $cfunc]
8532893d
SG
1597
1598# Sometimes there's no source file for this location
1599
1600 if {$filename == ""} {set filename Blank}
1601
1602# If we want to switch funcs, we need to unpack the current text widget, and
1603# stick in the new one.
1604
637b1661 1605 if {$funcname != $cfunc } {
546b8ca7 1606 set oldwin $win
8532893d
SG
1607 set cfunc $funcname
1608
335129a9 1609 set win [asm_win_name $cfunc]
8532893d
SG
1610
1611# Create a text widget for this func if necessary
1612
637b1661
SG
1613 if {![winfo exists $win]} {
1614 create_asm_win $cfunc $pc
8532893d
SG
1615 set asm_pointers($cfunc) 1.1
1616 set current_asm_label NIL
1617 }
1618
1619# Pack the text widget, and scroll to the right place
1620
546b8ca7 1621 pack forget $oldwin
8532893d 1622 pack $win -side left -expand yes -fill both \
006e71e9 1623 -after .asm.scroll
746d1df4 1624 .asm.scroll configure -command "$win yview"
637b1661 1625 set line [pc_to_line $pclist($cfunc) $pc]
0af608b8 1626 update
8532893d
SG
1627 $win yview [expr $line - $asm_screen_height / 2]
1628 }
1629
1630# Update the label widget in case the filename or function name has changed
1631
335129a9 1632 if {$current_asm_label != "$pc $funcname"} then {
746d1df4 1633 set .asm.label "$pc $funcname"
335129a9 1634 set current_asm_label "$pc $funcname"
8532893d
SG
1635 }
1636
1637# Update the pointer, scrolling the text widget if necessary to keep the
1638# pointer in an acceptable part of the screen.
1639
1640 if [info exists asm_pointers($cfunc)] then {
1641 $win configure -state normal
1642 set pointer_pos $asm_pointers($cfunc)
1643 $win configure -state normal
746d1df4
SG
1644 $win delete $pointer_pos "$pointer_pos + 2 char"
1645 $win insert $pointer_pos " "
8532893d
SG
1646
1647# Map the PC back to a line in the window
1648
637b1661 1649 set line [pc_to_line $pclist($cfunc) $pc]
8532893d
SG
1650
1651 if {$line == -1} {
1652 echo "Can't find PC $pc"
1653 return
1654 }
1655
8532893d
SG
1656 set pointer_pos [$win index $line.1]
1657 set asm_pointers($cfunc) $pointer_pos
1658
746d1df4
SG
1659 $win delete $pointer_pos "$pointer_pos + 2 char"
1660 $win insert $pointer_pos "->"
8532893d
SG
1661
1662 if {$line < $asm_screen_top + 1
1663 || $line > $asm_screen_bot} then {
1664 $win yview [expr $line - $asm_screen_height / 2]
1665 }
1666
8532893d
SG
1667 $win configure -state disabled
1668 }
1669}
1670
006e71e9
SG
1671#
1672# Local procedure:
1673#
1674# update_ptr - Update the listing window.
1675#
1676# Description:
1677#
1678# This routine will update the listing window using the result of
1679# gdb_loc.
1680#
1681
8532893d
SG
1682proc update_ptr {} {
1683 update_listing [gdb_loc]
1684 if [winfo exists .asm] {
1685 update_assembly [gdb_loc]
1686 }
335129a9 1687 if [winfo exists .reg] {
746d1df4 1688 update_registers changed
335129a9 1689 }
280c564c
SG
1690 if [winfo exists .expr] {
1691 update_exprs
1692 }
8532893d
SG
1693}
1694
006e71e9 1695# Make toplevel window disappear
754e5da2 1696
006e71e9 1697wm withdraw .
754e5da2 1698
754e5da2
SG
1699proc files_command {} {
1700 toplevel .files_window
1701
1702 wm minsize .files_window 1 1
1703# wm overrideredirect .files_window true
c81a3fa9
SG
1704 listbox .files_window.list -geometry 30x20 -setgrid true \
1705 -yscrollcommand {.files_window.scroll set} -relief raised \
1706 -borderwidth 2
1707 scrollbar .files_window.scroll -orient vertical \
1708 -command {.files_window.list yview}
754e5da2
SG
1709 button .files_window.close -text Close -command {destroy .files_window}
1710 tk_listboxSingleSelect .files_window.list
c81a3fa9
SG
1711
1712# Get the file list from GDB, sort it, and format it as one entry per line.
1713
1714 set filelist [join [lsort [gdb_listfiles]] "\n"]
1715
1716# Now, remove duplicates (by using uniq)
1717
1718 set fh [open "| uniq > /tmp/gdbtk.[pid]" w]
1719 puts $fh $filelist
1720 close $fh
1721 set fh [open /tmp/gdbtk.[pid]]
1722 set filelist [split [read $fh] "\n"]
1723 set filelist [lrange $filelist 0 [expr [llength $filelist] - 2]]
1724 close $fh
1725 exec rm /tmp/gdbtk.[pid]
1726
1727# Insert the file list into the widget
1728
1729 eval .files_window.list insert 0 $filelist
1730
754e5da2 1731 pack .files_window.close -side bottom -fill x -expand no -anchor s
c81a3fa9
SG
1732 pack .files_window.scroll -side right -fill both
1733 pack .files_window.list -side left -fill both -expand yes
754e5da2
SG
1734 bind .files_window.list <Any-ButtonRelease-1> {
1735 set file [%W get [%W curselection]]
1736 gdb_cmd "list $file:1,0"
1737 update_listing [gdb_loc $file:1]
1738 destroy .files_window}
1739}
1740
1741button .files -text Files -command files_command
1742
4604b34c
SG
1743proc apply_filespec {label default command} {
1744 set filename [FSBox $label $default]
1745 if {$filename != ""} {
1746 if [catch {gdb_cmd "$command $filename"} retval] {
1747 tk_dialog .filespec_error "gdb : $label error" \
1748 "Error in command \"$command $filename\"" {} 0 Dismiss
1749 return
1750 }
1751 update_ptr
1752 }
1753}
1754
754e5da2
SG
1755# Setup command window
1756
006e71e9 1757proc build_framework {win {title GDBtk} {label {}}} {
746d1df4 1758 global ${win}.label
006e71e9
SG
1759
1760 toplevel ${win}
04576ab6 1761 wm title ${win} $title
006e71e9
SG
1762 wm minsize ${win} 1 1
1763
1764 frame ${win}.menubar
1765
1766 menubutton ${win}.menubar.file -padx 12 -text File \
1767 -menu ${win}.menubar.file.menu -underline 0
1768
1769 menu ${win}.menubar.file.menu
e12533e3 1770 ${win}.menubar.file.menu add command -label File... \
4604b34c 1771 -command {apply_filespec File a.out file}
e12533e3 1772 ${win}.menubar.file.menu add command -label Target... \
c4a5c37c 1773 -command { not_implemented_yet "target" }
006e71e9
SG
1774 ${win}.menubar.file.menu add command -label Edit \
1775 -command {exec $editor +[expr ($screen_top + $screen_bot)/2] $cfile &}
e12533e3
SS
1776 ${win}.menubar.file.menu add separator
1777 ${win}.menubar.file.menu add command -label "Exec File..." \
4604b34c 1778 -command {apply_filespec {Exec File} a.out exec-file}
e12533e3 1779 ${win}.menubar.file.menu add command -label "Symbol File..." \
4604b34c 1780 -command {apply_filespec {Symbol File} a.out symbol-file}
e12533e3
SS
1781 ${win}.menubar.file.menu add command -label "Add Symbol File..." \
1782 -command { not_implemented_yet "menu item, add symbol file" }
1783 ${win}.menubar.file.menu add command -label "Core File..." \
4604b34c
SG
1784 -command {apply_filespec {Core File} core core-file}
1785
e12533e3 1786 ${win}.menubar.file.menu add separator
006e71e9
SG
1787 ${win}.menubar.file.menu add command -label Close \
1788 -command "destroy ${win}"
e12533e3 1789 ${win}.menubar.file.menu add separator
006e71e9 1790 ${win}.menubar.file.menu add command -label Quit \
e12533e3 1791 -command { catch { gdb_cmd quit } }
006e71e9 1792
c4a5c37c
SS
1793 menubutton ${win}.menubar.commands -padx 12 -text Commands \
1794 -menu ${win}.menubar.commands.menu -underline 0
1795
1796 menu ${win}.menubar.commands.menu
1797 ${win}.menubar.commands.menu add command -label Run \
1798 -command { catch {gdb_cmd run } ; update_ptr }
1799 ${win}.menubar.commands.menu add command -label Step \
1800 -command { catch { gdb_cmd step } ; update_ptr }
1801 ${win}.menubar.commands.menu add command -label Next \
1802 -command { catch { gdb_cmd next } ; update_ptr }
1803 ${win}.menubar.commands.menu add command -label Continue \
1804 -command { catch { gdb_cmd continue } ; update_ptr }
1805 ${win}.menubar.commands.menu add separator
1806 ${win}.menubar.commands.menu add command -label Stepi \
1807 -command { catch { gdb_cmd stepi } ; update_ptr }
1808 ${win}.menubar.commands.menu add command -label Nexti \
1809 -command { catch { gdb_cmd nexti } ; update_ptr }
1810
09722039 1811 menubutton ${win}.menubar.view -padx 12 -text Options \
006e71e9
SG
1812 -menu ${win}.menubar.view.menu -underline 0
1813
1814 menu ${win}.menubar.view.menu
c4a5c37c
SS
1815 ${win}.menubar.view.menu add command -label Hex \
1816 -command {echo Hex}
006e71e9
SG
1817 ${win}.menubar.view.menu add command -label Decimal \
1818 -command {echo Decimal}
c4a5c37c
SS
1819 ${win}.menubar.view.menu add command -label Octal \
1820 -command {echo Octal}
006e71e9
SG
1821
1822 menubutton ${win}.menubar.window -padx 12 -text Window \
1823 -menu ${win}.menubar.window.menu -underline 0
1824
1825 menu ${win}.menubar.window.menu
006e71e9 1826 ${win}.menubar.window.menu add command -label Command \
280c564c 1827 -command create_command_window
c4a5c37c
SS
1828 ${win}.menubar.window.menu add separator
1829 ${win}.menubar.window.menu add command -label Source \
280c564c 1830 -command {create_source_window ; update_ptr}
006e71e9 1831 ${win}.menubar.window.menu add command -label Assembly \
746d1df4 1832 -command {create_asm_window ; update_ptr}
c4a5c37c
SS
1833 ${win}.menubar.window.menu add separator
1834 ${win}.menubar.window.menu add command -label Registers \
746d1df4 1835 -command {create_registers_window ; update_ptr}
09722039
SG
1836 ${win}.menubar.window.menu add command -label Expressions \
1837 -command {create_expr_win ; update_ptr}
1838
280c564c
SG
1839# ${win}.menubar.window.menu add separator
1840# ${win}.menubar.window.menu add command -label Files \
1841# -command { not_implemented_yet "files window" }
006e71e9
SG
1842
1843 menubutton ${win}.menubar.help -padx 12 -text Help \
1844 -menu ${win}.menubar.help.menu -underline 0
1845
1846 menu ${win}.menubar.help.menu
1847 ${win}.menubar.help.menu add command -label "with GDBtk" \
1848 -command {echo "with GDBtk"}
1849 ${win}.menubar.help.menu add command -label "with this window" \
1850 -command {echo "with this window"}
c981300c
SG
1851 ${win}.menubar.help.menu add command -label "Report bug" \
1852 -command {exec send-pr}
006e71e9 1853
c4a5c37c
SS
1854 tk_menuBar ${win}.menubar \
1855 ${win}.menubar.file \
c4a5c37c
SS
1856 ${win}.menubar.view \
1857 ${win}.menubar.window \
1858 ${win}.menubar.help
1859 pack ${win}.menubar.file \
c4a5c37c
SS
1860 ${win}.menubar.view \
1861 ${win}.menubar.window -side left
1862 pack ${win}.menubar.help -side right
006e71e9
SG
1863
1864 frame ${win}.info
1865 text ${win}.text -height 25 -width 80 -relief raised -borderwidth 2 \
1866 -setgrid true -cursor hand2 -yscrollcommand "${win}.scroll set"
1867
746d1df4
SG
1868 set ${win}.label $label
1869 label ${win}.label -textvariable ${win}.label -borderwidth 2 -relief raised
754e5da2 1870
006e71e9
SG
1871 scrollbar ${win}.scroll -orient vertical -command "${win}.text yview"
1872
1873 pack ${win}.label -side bottom -fill x -in ${win}.info
1874 pack ${win}.scroll -side right -fill y -in ${win}.info
1875 pack ${win}.text -side left -expand yes -fill both -in ${win}.info
1876
1877 pack ${win}.menubar -side top -fill x
1878 pack ${win}.info -side top -fill both -expand yes
1879}
1880
746d1df4
SG
1881proc create_source_window {} {
1882 global wins
1883 global cfile
1884
280c564c
SG
1885 if [winfo exists .src] {raise .src ; return}
1886
746d1df4
SG
1887 build_framework .src Source "*No file*"
1888
86db943c
SG
1889# First, delete all the old view menu entries
1890
1891 .src.menubar.view.menu delete 0 last
1892
546b8ca7
SG
1893# Source file selection
1894 .src.menubar.view.menu add command -label "Select source file" \
1895 -command files_command
1896
86db943c
SG
1897# Line numbers enable/disable menu item
1898 .src.menubar.view.menu add checkbutton -variable line_numbers \
1899 -label "Line numbers" -onvalue 1 -offvalue 0 -command {
1900 foreach source [array names wins] {
1901 if {$source == "Blank"} continue
1902 destroy $wins($source)
1903 unset wins($source)
1904 }
1905 set cfile Blank
1906 update_listing [gdb_loc]
1907 }
1908
746d1df4
SG
1909 frame .src.row1
1910 frame .src.row2
1911
1912 button .src.start -width 6 -text Start -command \
86db943c
SG
1913 {catch {gdb_cmd {break main}}
1914 catch {gdb_cmd {enable delete $bpnum}}
1915 catch {gdb_cmd run}
746d1df4
SG
1916 update_ptr }
1917 button .src.stop -width 6 -text Stop -fg red -activeforeground red \
1918 -state disabled -command gdb_stop
1919 button .src.step -width 6 -text Step \
86db943c 1920 -command {catch {gdb_cmd step} ; update_ptr}
746d1df4 1921 button .src.next -width 6 -text Next \
86db943c 1922 -command {catch {gdb_cmd next} ; update_ptr}
746d1df4 1923 button .src.continue -width 6 -text Cont \
86db943c 1924 -command {catch {gdb_cmd continue} ; update_ptr}
746d1df4 1925 button .src.finish -width 6 -text Finish \
86db943c
SG
1926 -command {catch {gdb_cmd finish} ; update_ptr}
1927 button .src.up -width 6 -text Up \
1928 -command {catch {gdb_cmd up} ; update_ptr}
746d1df4 1929 button .src.down -width 6 -text Down \
86db943c 1930 -command {catch {gdb_cmd down} ; update_ptr}
746d1df4 1931 button .src.bottom -width 6 -text Bottom \
86db943c 1932 -command {catch {gdb_cmd {frame 0}} ; update_ptr}
746d1df4
SG
1933
1934 pack .src.start .src.step .src.continue .src.up .src.bottom \
1935 -side left -padx 3 -pady 5 -in .src.row1
1936 pack .src.stop .src.next .src.finish .src.down -side left -padx 3 \
1937 -pady 5 -in .src.row2
1938
86db943c 1939 pack .src.row2 .src.row1 -side bottom -anchor w -before .src.info
746d1df4
SG
1940
1941 $wins($cfile) insert 0.0 " This page intentionally left blank."
1942 $wins($cfile) configure -width 88 -state disabled \
1943 -yscrollcommand textscrollproc
1944
1945 proc textscrollproc {args} {global screen_height screen_top screen_bot
1946 eval ".src.scroll set $args"
1947 set screen_height [lindex $args 1]
1948 set screen_top [lindex $args 2]
1949 set screen_bot [lindex $args 3]}
1950}
754e5da2 1951
746d1df4 1952proc create_command_window {} {
754e5da2
SG
1953 global command_line
1954
280c564c
SG
1955 if [winfo exists .cmd] {raise .cmd ; return}
1956
746d1df4
SG
1957 build_framework .cmd Command "* Command Buffer *"
1958
754e5da2 1959 set command_line {}
746d1df4
SG
1960
1961 gdb_cmd {set language c}
1962 gdb_cmd {set height 0}
1963 gdb_cmd {set width 0}
1964
1965 bind .cmd.text <Enter> {focus %W}
1966 bind .cmd.text <Delete> {delete_char %W}
1967 bind .cmd.text <BackSpace> {delete_char %W}
1968 bind .cmd.text <Control-u> {delete_line %W}
1969 bind .cmd.text <Any-Key> {
1970 global command_line
1971
1972 %W insert end %A
1973 %W yview -pickplace end
1974 append command_line %A
1975 }
1976 bind .cmd.text <Key-Return> {
1977 global command_line
1978
1979 %W insert end \n
1980 %W yview -pickplace end
546b8ca7 1981 catch "gdb_cmd [list $command_line]"
746d1df4
SG
1982 set command_line {}
1983 update_ptr
1984 %W insert end "(gdb) "
1985 %W yview -pickplace end
1986 }
4604b34c
SG
1987 bind .cmd.text <Button-2> {
1988 global command_line
746d1df4 1989
4604b34c
SG
1990 %W insert end [selection get]
1991 %W yview -pickplace end
1992 append command_line [selection get]
1993 }
746d1df4
SG
1994 proc delete_char {win} {
1995 global command_line
1996
1997 tk_textBackspace $win
1998 $win yview -pickplace insert
1999 set tmp [expr [string length $command_line] - 2]
2000 set command_line [string range $command_line 0 $tmp]
754e5da2 2001 }
746d1df4
SG
2002 proc delete_line {win} {
2003 global command_line
754e5da2 2004
746d1df4
SG
2005 $win delete {end linestart + 6 chars} end
2006 $win yview -pickplace insert
2007 set command_line {}
2008 }
754e5da2
SG
2009}
2010
e12533e3
SS
2011#
2012# fileselect.tcl --
2013# simple file selector.
2014#
2015# Mario Jorge Silva msilva@cs.Berkeley.EDU
2016# University of California Berkeley Ph: +1(510)642-8248
2017# Computer Science Division, 571 Evans Hall Fax: +1(510)642-5775
2018# Berkeley CA 94720
2019#
2020#
2021# Copyright 1993 Regents of the University of California
2022# Permission to use, copy, modify, and distribute this
2023# software and its documentation for any purpose and without
2024# fee is hereby granted, provided that this copyright
2025# notice appears in all copies. The University of California
2026# makes no representations about the suitability of this
2027# software for any purpose. It is provided "as is" without
2028# express or implied warranty.
2029#
2030
2031
2032# names starting with "fileselect" are reserved by this module
2033# no other names used.
2034# Hack - FSBox is defined instead of fileselect for backwards compatibility
2035
2036
2037# this is the proc that creates the file selector box
2038# purpose - comment string
2039# defaultName - initial value for name
2040# cmd - command to eval upon OK
2041# errorHandler - command to eval upon Cancel
2042# If neither cmd or errorHandler are specified, the return value
2043# of the FSBox procedure is the selected file name.
2044
2045proc FSBox {{purpose "Select file:"} {defaultName ""} {cmd ""} {errorHandler
2046""}} {
2047 global fileselect
2048 set w .fileSelect
2049 if [Exwin_Toplevel $w "Select File" FileSelect] {
2050 # path independent names for the widgets
2051
2052 set fileselect(list) $w.file.sframe.list
2053 set fileselect(scroll) $w.file.sframe.scroll
2054 set fileselect(direntry) $w.file.f1.direntry
2055 set fileselect(entry) $w.file.f2.entry
2056 set fileselect(ok) $w.but.ok
2057 set fileselect(cancel) $w.but.cancel
2058 set fileselect(msg) $w.label
2059
2060 set fileselect(result) "" ;# value to return if no callback procedures
2061
2062 # widgets
2063 Widget_Label $w label {top fillx pady 10 padx 20} -anchor w -width 24
2064 Widget_Frame $w file Dialog {left expand fill} -bd 10
2065
2066 Widget_Frame $w.file f1 Exmh {top fillx}
2067 Widget_Label $w.file.f1 label {left} -text "Dir"
2068 Widget_Entry $w.file.f1 direntry {right fillx expand} -width 30
2069
2070 Widget_Frame $w.file sframe
2071
2072 scrollbar $w.file.sframe.yscroll -relief sunken \
2073 -command [list $w.file.sframe.list yview]
2074 listbox $w.file.sframe.list -relief sunken \
2075 -yscroll [list $w.file.sframe.yscroll set] -setgrid 1
2076 pack append $w.file.sframe \
2077 $w.file.sframe.yscroll {right filly} \
2078 $w.file.sframe.list {left expand fill}
2079
2080 Widget_Frame $w.file f2 Exmh {top fillx}
2081 Widget_Label $w.file.f2 label {left} -text Name
2082 Widget_Entry $w.file.f2 entry {right fillx expand}
2083
2084 # buttons
2085 $w.but.quit configure -text Cancel \
2086 -command [list fileselect.cancel.cmd $w]
2087
2088 Widget_AddBut $w.but ok OK \
2089 [list fileselect.ok.cmd $w $cmd $errorHandler] {left padx 1}
2090
2091 Widget_AddBut $w.but list List \
2092 [list fileselect.list.cmd $w] {left padx 1}
2093 Widget_CheckBut $w.but listall "List all" fileselect(pattern)
2094 $w.but.listall configure -onvalue "{*,.*}" -offvalue "*" \
2095 -command {fileselect.list.cmd $fileselect(direntry)}
2096 $w.but.listall deselect
2097
2098 # Set up bindings for the browser.
2099 foreach ww [list $w $fileselect(entry)] {
2100 bind $ww <Return> [list $fileselect(ok) invoke]
2101 bind $ww <Control-c> [list $fileselect(cancel) invoke]
2102 }
2103 bind $fileselect(direntry) <Return> [list fileselect.list.cmd %W]
2104 bind $fileselect(direntry) <Tab> [list fileselect.tab.dircmd]
2105 bind $fileselect(entry) <Tab> [list fileselect.tab.filecmd]
2106
2107 tk_listboxSingleSelect $fileselect(list)
2108
2109
2110 bind $fileselect(list) <Button-1> {
2111 # puts stderr "button 1 release"
2112 %W select from [%W nearest %y]
2113 $fileselect(entry) delete 0 end
2114 $fileselect(entry) insert 0 [%W get [%W nearest %y]]
2115 }
2116
2117 bind $fileselect(list) <Key> {
2118 %W select from [%W nearest %y]
2119 $fileselect(entry) delete 0 end
2120 $fileselect(entry) insert 0 [%W get [%W nearest %y]]
2121 }
2122
2123 bind $fileselect(list) <Double-ButtonPress-1> {
2124 # puts stderr "double button 1"
2125 %W select from [%W nearest %y]
2126 $fileselect(entry) delete 0 end
2127 $fileselect(entry) insert 0 [%W get [%W nearest %y]]
2128 $fileselect(ok) invoke
2129 }
2130
2131 bind $fileselect(list) <Return> {
2132 %W select from [%W nearest %y]
2133 $fileselect(entry) delete 0 end
2134 $fileselect(entry) insert 0 [%W get [%W nearest %y]]
2135 $fileselect(ok) invoke
2136 }
2137 }
2138 set fileselect(text) $purpose
2139 $fileselect(msg) configure -text $purpose
2140 $fileselect(entry) delete 0 end
2141 $fileselect(entry) insert 0 [file tail $defaultName]
2142
2143 if {[info exists fileselect(lastDir)] && ![string length $defaultName]} {
2144 set dir $fileselect(lastDir)
2145 } else {
2146 set dir [file dirname $defaultName]
2147 }
2148 set fileselect(pwd) [pwd]
2149 fileselect.cd $dir
2150 $fileselect(direntry) delete 0 end
2151 $fileselect(direntry) insert 0 [pwd]/
2152
2153 $fileselect(list) delete 0 end
2154 $fileselect(list) insert 0 "Big directory:"
2155 $fileselect(list) insert 1 $dir
2156 $fileselect(list) insert 2 "Press Return for Listing"
2157
2158 fileselect.list.cmd $fileselect(direntry) startup
2159
2160 # set kbd focus to entry widget
2161
2162# Exwin_ToplevelFocus $w $fileselect(entry)
2163
2164 # Wait for button hits if no callbacks are defined
2165
2166 if {"$cmd" == "" && "$errorHandler" == ""} {
2167 # wait for the box to be destroyed
2168 update idletask
2169 grab $w
2170 tkwait variable fileselect(result)
2171 grab release $w
2172
2173 set path $fileselect(result)
2174 set fileselect(lastDir) [pwd]
2175 fileselect.cd $fileselect(pwd)
2176 return [string trimright [string trim $path] /]
2177 }
2178 fileselect.cd $fileselect(pwd)
2179 return ""
2180}
2181
2182proc fileselect.cd { dir } {
2183 global fileselect
2184 if [catch {cd $dir} err] {
2185 fileselect.yck $dir
2186 cd
2187 }
2188}
2189# auxiliary button procedures
2190
2191proc fileselect.yck { {tag {}} } {
2192 global fileselect
2193 $fileselect(msg) configure -text "Yck! $tag"
2194}
2195proc fileselect.ok {} {
2196 global fileselect
2197 $fileselect(msg) configure -text $fileselect(text)
2198}
2199
2200proc fileselect.cancel.cmd {w} {
2201 global fileselect
2202 set fileselect(result) {}
4604b34c 2203 destroy $w
e12533e3
SS
2204}
2205
2206proc fileselect.list.cmd {w {state normal}} {
2207 global fileselect
2208 set seldir [$fileselect(direntry) get]
2209 if {[catch {glob $seldir} dir]} {
2210 fileselect.yck "glob failed"
2211 return
2212 }
2213 if {[llength $dir] > 1} {
2214 set dir [file dirname $seldir]
2215 set pat [file tail $seldir]
2216 } else {
2217 set pat $fileselect(pattern)
2218 }
2219 fileselect.ok
2220 update idletasks
2221 if [file isdirectory $dir] {
2222 fileselect.getfiles $dir $pat $state
2223 focus $fileselect(entry)
2224 } else {
2225 fileselect.yck "not a dir"
2226 }
2227}
2228
2229proc fileselect.ok.cmd {w cmd errorHandler} {
2230 global fileselect
2231 set selname [$fileselect(entry) get]
2232 set seldir [$fileselect(direntry) get]
2233
2234 if [string match /* $selname] {
2235 set selected $selname
2236 } else {
2237 if [string match ~* $selname] {
2238 set selected $selname
2239 } else {
2240 set selected $seldir/$selname
2241 }
2242 }
2243
2244 # some nasty file names may cause "file isdirectory" to return an error
2245 if [catch {file isdirectory $selected} isdir] {
2246 fileselect.yck "isdirectory failed"
2247 return
2248 }
2249 if [catch {glob $selected} globlist] {
2250 if ![file isdirectory [file dirname $selected]] {
2251 fileselect.yck "bad pathname"
2252 return
2253 }
2254 set globlist $selected
2255 }
2256 fileselect.ok
2257 update idletasks
2258
2259 if {[llength $globlist] > 1} {
2260 set dir [file dirname $selected]
2261 set pat [file tail $selected]
2262 fileselect.getfiles $dir $pat
2263 return
2264 } else {
2265 set selected $globlist
2266 }
2267 if [file isdirectory $selected] {
2268 fileselect.getfiles $selected $fileselect(pattern)
2269 $fileselect(entry) delete 0 end
2270 return
2271 }
2272
2273 if {$cmd != {}} {
2274 $cmd $selected
2275 } else {
2276 set fileselect(result) $selected
2277 }
4604b34c 2278 destroy $w
e12533e3
SS
2279}
2280
2281proc fileselect.getfiles { dir {pat *} {state normal} } {
2282 global fileselect
2283 $fileselect(msg) configure -text Listing...
2284 update idletasks
2285
2286 set currentDir [pwd]
2287 fileselect.cd $dir
2288 if [catch {set files [lsort [glob -nocomplain $pat]]} err] {
2289 $fileselect(msg) configure -text $err
2290 $fileselect(list) delete 0 end
2291 update idletasks
2292 return
2293 }
2294 switch -- $state {
2295 normal {
2296 # Normal case - show current directory
2297 $fileselect(direntry) delete 0 end
2298 $fileselect(direntry) insert 0 [pwd]/
2299 }
2300 opt {
2301 # Directory already OK (tab related)
2302 }
2303 newdir {
2304 # Changing directory (tab related)
2305 fileselect.cd $currentDir
2306 }
2307 startup {
2308 # Avoid listing huge directories upon startup.
2309 $fileselect(direntry) delete 0 end
2310 $fileselect(direntry) insert 0 [pwd]/
2311 if {[llength $files] > 32} {
2312 fileselect.ok
2313 return
2314 }
2315 }
2316 }
2317
2318 # build a reordered list of the files: directories are displayed first
2319 # and marked with a trailing "/"
2320 if [string compare $dir /] {
2321 fileselect.putfiles $files [expr {($pat == "*") ? 1 : 0}]
2322 } else {
2323 fileselect.putfiles $files
2324 }
2325 fileselect.ok
2326}
2327
2328proc fileselect.putfiles {files {dotdot 0} } {
2329 global fileselect
2330
2331 $fileselect(list) delete 0 end
2332 if {$dotdot} {
2333 $fileselect(list) insert end "../"
2334 }
2335 foreach i $files {
2336 if {[file isdirectory $i]} {
2337 $fileselect(list) insert end $i/
2338 } else {
2339 $fileselect(list) insert end $i
2340 }
2341 }
2342}
2343
2344proc FileExistsDialog { name } {
2345 set w .fileExists
2346 global fileExists
2347 set fileExists(ok) 0
2348 {
2349 message $w.msg -aspect 1000
2350 pack $w.msg -side top -fill both -padx 20 -pady 20
2351 $w.but.quit config -text Cancel -command {FileExistsCancel}
2352 button $w.but.ok -text OK -command {FileExistsOK}
2353 pack $w.but.ok -side left
2354 bind $w.msg <Return> {FileExistsOK}
2355 }
2356 $w.msg config -text "Warning: file exists
2357$name
2358OK to overwrite it?"
2359
2360 set fileExists(focus) [focus]
2361 focus $w.msg
2362 grab $w
2363 tkwait variable fileExists(ok)
2364 grab release $w
4604b34c 2365 destroy $w
e12533e3
SS
2366 return $fileExists(ok)
2367}
2368proc FileExistsCancel {} {
2369 global fileExists
2370 set fileExists(ok) 0
2371}
2372proc FileExistsOK {} {
2373 global fileExists
2374 set fileExists(ok) 1
2375}
2376
2377proc fileselect.getfiledir { dir {basedir [pwd]} } {
2378 global fileselect
2379
2380 set path [$fileselect(direntry) get]
2381 set returnList {}
2382
2383 if {$dir != 0} {
2384 if {[string index $path 0] == "~"} {
2385 set path $path/
2386 }
2387 } else {
2388 set path [$fileselect(entry) get]
2389 }
2390 if [catch {set listFile [glob -nocomplain $path*]}] {
2391 return $returnList
2392 }
2393 foreach el $listFile {
2394 if {$dir != 0} {
2395 if [file isdirectory $el] {
2396 lappend returnList [file tail $el]
2397 }
2398 } elseif ![file isdirectory $el] {
2399 lappend returnList [file tail $el]
2400 }
2401 }
2402
2403 return $returnList
2404}
2405
2406proc fileselect.gethead { list } {
2407 set returnHead ""
2408
2409 for {set i 0} {[string length [lindex $list 0]] > $i}\
2410 {incr i; set returnHead $returnHead$thisChar} {
2411 set thisChar [string index [lindex $list 0] $i]
2412 foreach el $list {
2413 if {[string length $el] < $i} {
2414 return $returnHead
2415 }
2416 if {$thisChar != [string index $el $i]} {
2417 return $returnHead
2418 }
2419 }
2420 }
2421 return $returnHead
2422}
2423
2424proc fileselect.expand.tilde { } {
2425 global fileselect
2426
2427 set entry [$fileselect(direntry) get]
2428 set dir [string range $entry 1 [string length $entry]]
2429
2430 if {$dir == ""} {
2431 return
2432 }
2433
2434 set listmatch {}
2435
2436 ## look in /etc/passwd
2437 if [file exists /etc/passwd] {
2438 if [catch {set users [exec cat /etc/passwd | sed s/:.*//]} err] {
2439 puts "Error\#1 $err"
2440 return
2441 }
2442 set list [split $users "\n"]
2443 }
2444 if {[lsearch -exact $list "+"] != -1} {
2445 if [catch {set users [exec ypcat passwd | sed s/:.*//]} err] {
2446 puts "Error\#2 $err"
2447 return
2448 }
2449 set list [concat $list [split $users "\n"]]
2450 }
2451 $fileselect(list) delete 0 end
2452 foreach el $list {
2453 if [string match $dir* $el] {
2454 lappend listmatch $el
2455 $fileselect(list) insert end $el
2456 }
2457 }
2458 set addings [fileselect.gethead $listmatch]
2459 if {$addings == ""} {
2460 return
2461 }
2462 $fileselect(direntry) delete 0 end
2463 if {[llength $listmatch] == 1} {
2464 $fileselect(direntry) insert 0 [file dirname ~$addings/]
2465 fileselect.getfiles [$fileselect(direntry) get]
2466 } else {
2467 $fileselect(direntry) insert 0 ~$addings
2468 }
2469}
2470
2471proc fileselect.tab.dircmd { } {
2472 global fileselect
2473
2474 set dir [$fileselect(direntry) get]
2475 if {$dir == ""} {
2476 $fileselect(direntry) delete 0 end
2477 $fileselect(direntry) insert 0 [pwd]
2478 if [string compare [pwd] "/"] {
2479 $fileselect(direntry) insert end /
2480 }
2481 return
2482 }
2483 if [catch {set tmp [file isdirectory [file dirname $dir]]}] {
2484 if {[string index $dir 0] == "~"} {
2485 fileselect.expand.tilde
2486 }
2487 return
2488 }
2489 if {!$tmp} {
2490 return
2491 }
2492 set dirFile [fileselect.getfiledir 1 $dir]
2493 if ![llength $dirFile] {
2494 return
2495 }
2496 if {[llength $dirFile] == 1} {
2497 $fileselect(direntry) delete 0 end
2498 $fileselect(direntry) insert 0 [file dirname $dir]
2499 if [string compare [file dirname $dir] /] {
2500 $fileselect(direntry) insert end /[lindex $dirFile 0]/
2501 } else {
2502 $fileselect(direntry) insert end [lindex $dirFile 0]/
2503 }
2504 fileselect.getfiles [$fileselect(direntry) get] \
2505 "[file tail [$fileselect(direntry) get]]$fileselect(pattern)" opt
2506 return
2507 }
2508 set headFile [fileselect.gethead $dirFile]
2509 $fileselect(direntry) delete 0 end
2510 $fileselect(direntry) insert 0 [file dirname $dir]
2511 if [string compare [file dirname $dir] /] {
2512 $fileselect(direntry) insert end /$headFile
2513 } else {
2514 $fileselect(direntry) insert end $headFile
2515 }
2516 if {$headFile == "" && [file isdirectory $dir]} {
2517 fileselect.getfiles $dir\
2518 "[file tail [$fileselect(direntry) get]]$fileselect(pattern)" opt
2519 } else {
2520 fileselect.getfiles [file dirname $dir]\
2521 "[file tail [$fileselect(direntry) get]]*" newdir
2522 }
2523}
2524
2525proc fileselect.tab.filecmd { } {
2526 global fileselect
2527
2528 set dir [$fileselect(direntry) get]
2529 if {$dir == ""} {
2530 set dir [pwd]
2531 }
2532 if {![file isdirectory $dir]} {
2533 error "dir $dir doesn't exist"
2534 }
2535 set listFile [fileselect.getfiledir 0 $dir]
2536 puts $listFile
2537 if ![llength $listFile] {
2538 return
2539 }
2540 if {[llength $listFile] == 1} {
2541 $fileselect(entry) delete 0 end
2542 $fileselect(entry) insert 0 [lindex $listFile 0]
2543 return
2544 }
2545 set headFile [fileselect.gethead $listFile]
2546 $fileselect(entry) delete 0 end
2547 $fileselect(entry) insert 0 $headFile
2548 fileselect.getfiles $dir "[$fileselect(entry) get]$fileselect(pattern)" opt
2549}
2550
2551proc Exwin_Toplevel { path name {class Dialog} {dismiss yes}} {
2552 global exwin
2553 if [catch {wm state $path} state] {
2554 set t [Widget_Toplevel $path $name $class]
2555 if ![info exists exwin(toplevels)] {
2556 set exwin(toplevels) [option get . exwinPaths {}]
2557 }
2558 set ix [lsearch $exwin(toplevels) $t]
2559 if {$ix < 0} {
2560 lappend exwin(toplevels) $t
2561 }
2562 if {$dismiss == "yes"} {
2563 set f [Widget_Frame $t but Menubar {top fill}]
2564 Widget_AddBut $f quit "Dismiss" [list Exwin_Dismiss $path]
2565 }
2566 return 1
2567 } else {
2568 if {$state != "normal"} {
2569 catch {
2570 wm geometry $path $exwin(geometry,$path)
2571# Exmh_Debug Exwin_Toplevel $path $exwin(geometry,$path)
2572 }
2573 wm deiconify $path
2574 } else {
2575 catch {raise $path}
2576 }
2577 return 0
2578 }
2579}
2580
2581proc Exwin_Dismiss { path {geo ok} } {
2582 global exwin
2583 case $geo {
2584 "ok" {
2585 set exwin(geometry,$path) [wm geometry $path]
2586 }
2587 "nosize" {
2588 set exwin(geometry,$path) [string trimleft [wm geometry $path] 0123456789x]
2589 }
2590 default {
2591 catch {unset exwin(geometry,$path)}
2592 }
2593 }
2594 wm withdraw $path
2595}
2596
2597proc Widget_Toplevel { path name {class Dialog} {x {}} {y {}} } {
2598 set self [toplevel $path -class $class]
2599 set usergeo [option get $path position Position]
2600 if {$usergeo != {}} {
2601 if [catch {wm geometry $self $usergeo} err] {
2602# Exmh_Debug Widget_Toplevel $self $usergeo => $err
2603 }
2604 } else {
2605 if {($x != {}) && ($y != {})} {
2606# Exmh_Debug Event position $self +$x+$y
2607 wm geometry $self +$x+$y
2608 }
2609 }
2610 wm title $self $name
2611 wm group $self .
2612 return $self
2613}
2614
2615proc Widget_Frame {par child {class GDB} {where {top expand fill}} args } {
2616 if {$par == "."} {
2617 set self .$child
2618 } else {
2619 set self $par.$child
2620 }
2621 eval {frame $self -class $class} $args
2622 pack append $par $self $where
2623 return $self
2624}
2625
2626proc Widget_AddBut {par but txt cmd {where {right padx 1}} } {
2627 # Create a Packed button. Return the button pathname
2628 set cmd2 [list button $par.$but -text $txt -command $cmd]
2629 if [catch $cmd2 t] {
2630 puts stderr "Widget_AddBut (warning) $t"
2631 eval $cmd2 {-font fixed}
2632 }
2633 pack append $par $par.$but $where
2634 return $par.$but
2635}
2636proc Widget_CheckBut {par but txt var {where {right padx 1}} } {
2637 # Create a check button. Return the button pathname
2638 set cmd [list checkbutton $par.$but -text $txt -variable $var]
2639 if [catch $cmd t] {
2640 puts stderr "Widget_CheckBut (warning) $t"
2641 eval $cmd {-font fixed}
2642 }
2643 pack append $par $par.$but $where
2644 return $par.$but
2645}
2646
2647proc Widget_Label { frame {name label} {where {left fill}} args} {
2648 set cmd [list label $frame.$name ]
2649 if [catch [concat $cmd $args] t] {
2650 puts stderr "Widget_Label (warning) $t"
2651 eval $cmd $args {-font fixed}
2652 }
2653 pack append $frame $frame.$name $where
2654 return $frame.$name
2655}
2656proc Widget_Entry { frame {name entry} {where {left fill}} args} {
2657 set cmd [list entry $frame.$name ]
2658 if [catch [concat $cmd $args] t] {
2659 puts stderr "Widget_Entry (warning) $t"
2660 eval $cmd $args {-font fixed}
2661 }
2662 pack append $frame $frame.$name $where
2663 return $frame.$name
2664}
2665
2666# End of fileselect.tcl.
2667
746d1df4 2668# Setup the initial windows
a5cffdc4 2669
746d1df4
SG
2670create_source_window
2671
2672if {[tk colormodel .src.text] == "color"} {
2673 set highlight "-background red2 -borderwidth 2 -relief sunk"
2674} else {
2675 set fg [lindex [.src.text config -foreground] 4]
2676 set bg [lindex [.src.text config -background] 4]
2677 set highlight "-foreground $bg -background $fg -borderwidth 0"
a5cffdc4 2678}
746d1df4
SG
2679
2680create_command_window
09722039
SG
2681
2682# Create a copyright window
2683
2684toplevel .c
2685wm geometry .c +300+300
2686wm overrideredirect .c true
2687
2688text .t
2689set temp $current_output_win
2690set current_output_win .t
2691gdb_cmd "show version"
2692set current_output_win $temp
2693
280c564c 2694message .c.m -text [.t get 0.0 end] -aspect 500 -relief raised
09722039
SG
2695destroy .t
2696pack .c.m
2697bind .c.m <Leave> {destroy .c}
2698
6bd7d9fa
SG
2699if [file exists ~/.gdbtkinit] {
2700 source ~/.gdbtkinit
2701}
2702
746d1df4 2703update
This page took 0.307518 seconds and 4 git commands to generate.