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