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