diff options
-rw-r--r-- | gdb/ChangeLog | 20 | ||||
-rw-r--r-- | gdb/defs.h | 40 | ||||
-rw-r--r-- | gdb/gdbtk.c | 22 | ||||
-rw-r--r-- | gdb/gdbtk.tcl | 108 | ||||
-rw-r--r-- | gdb/top.c | 8 |
5 files changed, 129 insertions, 69 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 398bd4c..8e8c8d1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +Fri Sep 16 15:40:34 1994 Stu Grossman (grossman@cygnus.com) + + * defs.h (QUIT): Call interactive_hook to allow GUI to interrupt. + Also, add decl for symtab_to_filename. + * gdbtk.c: Replace calls to full_filename with symtab_to_filename. + * gdbtk.tcl: New routine pc_to_line replaces in line code. New + routine decr replaces in line code. + * (create_file_win): Use catch to handle open failures more + elegantly. Also, create special window to display file open + failure message. Move opening of file prior to creation of text + widget. + * (create_asm_win): Add PC as argument. We now base disassembly + on PC instead of function name, since function names can be + ambiguous (usually seen with shared libs). Also, use catch to + simplify code where we don't care about failures. + * source.c (symtab_to_filename): New. Returns the file + associated with a symtab. + * top.c: Define interactive_hook. Called during QUIT to animate + the GUI. + Fri Sep 16 00:14:40 1994 Per Bothner (bothner@kalessin.cygnus.com) * stabsread.c (read_type): Handle stub types for bitstrings. @@ -66,7 +66,7 @@ extern int sevenbit_strings; extern void quit PARAMS ((void)); -#define QUIT { if (quit_flag) quit (); } +#define QUIT { if (quit_flag) quit (); if (interactive_hook) interactive_hook (); } /* Command classes are top-level categories into which commands are broken down for "help" purposes. @@ -119,6 +119,13 @@ struct cleanup PTR arg; }; +/* Needed for various prototypes */ + +#ifdef __STDC__ +struct symtab; +struct breakpoint; +#endif + /* From blockframe.c */ extern int inside_entry_func PARAMS ((CORE_ADDR)); @@ -310,6 +317,8 @@ extern void directory_command PARAMS ((char *, int)); extern void init_source_path PARAMS ((void)); +extern char *symtab_to_filename PARAMS ((struct symtab *)); + /* From findvar.c */ extern int read_relative_register_raw_bytes PARAMS ((int, char *)); @@ -318,26 +327,6 @@ extern int read_relative_register_raw_bytes PARAMS ((int, char *)); extern char *tilde_expand PARAMS ((char *)); -/* Control types for commands */ - -enum misc_command_type -{ - ok_command, - end_command, - else_command, - nop_command, -}; - -enum command_control_type -{ - simple_control, - break_control, - continue_control, - while_control, - if_control, - invalid_control -}; - /* Structure for saved commands lines (for breakpoints, defined commands, etc). */ @@ -345,9 +334,6 @@ struct command_line { struct command_line *next; char *line; - enum command_control_type control_type; - int body_count; - struct command_line **body_list; }; extern struct command_line *read_command_lines PARAMS ((void)); @@ -832,11 +818,6 @@ extern CORE_ADDR push_word PARAMS ((CORE_ADDR, unsigned LONGEST)); /* Hooks for alternate command interfaces. */ -#ifdef __STDC__ -struct symtab; -struct breakpoint; -#endif - extern void (*init_ui_hook) PARAMS ((void)); extern void (*command_loop_hook) PARAMS ((void)); extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer)); @@ -848,6 +829,7 @@ extern void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b)); extern void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); extern void (*enable_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); extern void (*disable_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); +extern void (*interactive_hook) PARAMS ((void)); /* Inhibit window interface if non-zero. */ diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c index e3a2ce7..9843b43 100644 --- a/gdb/gdbtk.c +++ b/gdb/gdbtk.c @@ -129,6 +129,7 @@ gdbtk_query (args) return val; } +#if 0 static char * full_filename(symtab) struct symtab *symtab; @@ -163,6 +164,7 @@ full_filename(symtab) return filename; } +#endif static void breakpoint_notify(b, action) @@ -180,7 +182,7 @@ breakpoint_notify(b, action) sal = find_pc_line (b->address, 0); - filename = full_filename (sal.symtab); + filename = symtab_to_filename (sal.symtab); sprintf (bpnum, "%d", b->number); sprintf (line, "%d", sal.line); @@ -200,9 +202,6 @@ breakpoint_notify(b, action) gdbtk_fputs (interp->result); gdbtk_fputs ("\n"); } - - if (filename) - free (filename); } static void @@ -293,7 +292,7 @@ gdb_loc (clientData, interp, argc, argv) find_pc_partial_function (pc, &funcname, NULL, NULL); Tcl_AppendElement (interp, funcname); - filename = full_filename (sal.symtab); + filename = symtab_to_filename (sal.symtab); Tcl_AppendElement (interp, filename); sprintf (buf, "%d", sal.line); @@ -302,9 +301,6 @@ gdb_loc (clientData, interp, argc, argv) sprintf (buf, "0x%x", pc); Tcl_AppendElement (interp, buf); /* PC */ - if (filename) - free(filename); - return TCL_OK; } @@ -396,6 +392,15 @@ cleanup_init (ignored) interp = NULL; } +/* Come here during long calculations to check for GUI events. Usually invoked + via the QUIT macro. */ + +static void +gdbtk_interactive () +{ + /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */ +} + static void gdbtk_init () { @@ -445,6 +450,7 @@ gdbtk_init () delete_breakpoint_hook = gdbtk_delete_breakpoint; enable_breakpoint_hook = gdbtk_enable_breakpoint; disable_breakpoint_hook = gdbtk_disable_breakpoint; + interactive_hook = gdbtk_interactive; discard_cleanups (old_chain); diff --git a/gdb/gdbtk.tcl b/gdb/gdbtk.tcl index a164fae..a142c3d 100644 --- a/gdb/gdbtk.tcl +++ b/gdb/gdbtk.tcl @@ -183,8 +183,7 @@ proc create_breakpoint {bpnum file line pc} { set win [asm_win_name $cfunc] if [winfo exists $win] { - set line [lsearch -exact $pclist($cfunc) $pc] - insert_breakpoint_tag $win $line + insert_breakpoint_tag $win [pc_to_line $pclist($cfunc) $pc] } } @@ -219,12 +218,11 @@ proc delete_breakpoint {bpnum file line pc} { # Reset breakpoint annotation info if {$pos_to_bpcount($file:$line) > 0} { - incr pos_to_bpcount($file:$line) -1 + decr pos_to_bpcount($file:$line) if {$pos_to_bpcount($file:$line) == 0} { - if [info exists pos_to_breakpoint($file:$line)] { - unset pos_to_breakpoint($file:$line) - } + catch "unset pos_to_breakpoint($file:$line)" + unset breakpoint_file($bpnum) unset breakpoint_line($bpnum) @@ -239,16 +237,14 @@ proc delete_breakpoint {bpnum file line pc} { # If there's an assembly window, update that too if {$pos_to_bpcount($pc) > 0} { - incr pos_to_bpcount($pc) -1 + decr pos_to_bpcount($pc) if {$pos_to_bpcount($pc) == 0} { - if [info exists pos_to_breakpoint($pc)] { - unset pos_to_breakpoint($pc) - } + catch "unset pos_to_breakpoint($pc)" + set win [asm_win_name $cfunc] if [winfo exists $win] { - set line [lsearch -exact $pclist($cfunc) $pc] - delete_breakpoint_tag $win $line + delete_breakpoint_tag $win [pc_to_line $pclist($cfunc) $pc] } } } @@ -278,8 +274,7 @@ proc enable_breakpoint {bpnum file line pc} { set win [asm_win_name $cfunc] if [winfo exists $win] { - set line [lsearch -exact $pclist($cfunc) $pc] - $win tag configure $line -fgstipple {} + $win tag configure [pc_to_line $pclist($cfunc) $pc] -fgstipple {} } } @@ -307,8 +302,7 @@ proc disable_breakpoint {bpnum file line pc} { set win [asm_win_name $cfunc] if [winfo exists $win] { - set line [lsearch -exact $pclist($cfunc) $pc] - $win tag configure $line -fgstipple gray50 + $win tag configure [pc_to_line $pclist($cfunc) $pc] -fgstipple gray50 } } @@ -352,6 +346,43 @@ proc delete_breakpoint_tag {win line} { } # +# Local procedure: +# +# decr (var val) - compliment to incr +# +# Description: +# +# +proc decr {var {val 1}} { + upvar $var num + set num [expr $num - $val] + return $num +} + +# +# Local procedure: +# +# pc_to_line (pclist pc) - convert PC to a line number. +# +# Description: +# +# Convert PC to a line number from PCLIST. If exact line isn't found, +# we return the first line that starts before PC. +# +proc pc_to_line {pclist pc} { + set line [lsearch -exact $pclist $pc] + + if {$line >= 1} { return $line } + + set line 1 + foreach linepc [lrange $pclist 1 end] { + if {$pc < $linepc} { decr line ; return $line } + incr line + } + return [expr $line - 1] +} + +# # Menu: # # file popup menu - Define the file popup menu. @@ -617,6 +648,20 @@ proc create_file_win {filename} { regsub -all {\.|/} $filename {} temp set win .text$temp +# Open the file, and read it into the text widget + + if [catch "open $filename" fh] { +# File can't be read. Put error message into .nofile window and return. + + catch {destroy .nofile} + text .nofile -height 25 -width 80 -relief raised -borderwidth 2 -yscrollcommand textscrollproc -setgrid true -cursor hand2 + .nofile insert 0.0 $fh + .nofile configure -state disabled + bind .nofile <1> do_nothing + bind .nofile <B1-Motion> do_nothing + return .nofile + } + # Actually create and do basic configuration on the text widget. text $win -height 25 -width 80 -relief raised -borderwidth 2 -yscrollcommand textscrollproc -setgrid true -cursor hand2 @@ -633,9 +678,6 @@ proc create_file_win {filename} { bind $win u {gdb_cmd up ; update_ptr} bind $win d {gdb_cmd down ; update_ptr} -# Open the file, and read it into the text widget - - set fh [open $filename] $win delete 0.0 end $win insert 0.0 [read $fh] close $fh @@ -665,7 +707,7 @@ proc create_file_win {filename} { # # Local procedure: # -# create_asm_win (funcname) - Create an assembly win for FUNCNAME. +# create_asm_win (funcname pc) - Create an assembly win for FUNCNAME. # # Return value: # @@ -679,7 +721,7 @@ proc create_file_win {filename} { # function FUNCNAME is read into the text widget. # -proc create_asm_win {funcname} { +proc create_asm_win {funcname pc} { global breakpoint_file global breakpoint_line global current_output_win @@ -710,20 +752,22 @@ proc create_asm_win {funcname} { # Disassemble the code, and read it into the new text widget set current_output_win $win - gdb_cmd "disassemble '$funcname'" + gdb_cmd "disassemble $pc" set current_output_win .command.text set numlines [$win index end] set numlines [lindex [split $numlines .] 0] + decr numlines # Delete the first and last lines, cuz these contain useless info $win delete 1.0 2.0 $win delete {end - 1 lines} end + decr numlines 2 # Add margins (for annotations) and note the PC for each line - if [info exists pclist($funcname)] { unset pclist($funcname) } + catch "unset pclist($funcname)" lappend pclist($funcname) Unused for {set i 1} {$i <= $numlines} {incr i} { scan [$win get $i.0 "$i.0 lineend"] "%s " pc @@ -835,9 +879,11 @@ proc update_listing {linespec} { if ![info exists wins($cfile)] then { set wins($cfile) [create_file_win $cfile] - set win_to_file($wins($cfile)) $cfile - set file_to_debug_file($cfile) $debug_file - set pointers($cfile) 1.1 + if {$wins($cfile) != ".nofile"} { + set win_to_file($wins($cfile)) $cfile + set file_to_debug_file($cfile) $debug_file + set pointers($cfile) 1.1 + } } # Pack the text widget into the listing widget, and scroll to the right place @@ -1042,7 +1088,7 @@ proc update_assembly {linespec} { # If we want to switch funcs, we need to unpack the current text widget, and # stick in the new one. - if {$funcname != $cfunc} then { + if {$funcname != $cfunc } { pack forget $win set cfunc $funcname @@ -1050,8 +1096,8 @@ proc update_assembly {linespec} { # Create a text widget for this func if necessary - if ![winfo exists $win] then { - create_asm_win $cfunc + if {![winfo exists $win]} { + create_asm_win $cfunc $pc set asm_pointers($cfunc) 1.1 set current_asm_label NIL } @@ -1060,7 +1106,7 @@ proc update_assembly {linespec} { pack $win -side left -expand yes -fill both \ -after .asm.buts - set line [lsearch -exact $pclist($cfunc) $pc] + set line [pc_to_line $pclist($cfunc) $pc] $win yview [expr $line - $asm_screen_height / 2] } @@ -1083,7 +1129,7 @@ proc update_assembly {linespec} { # Map the PC back to a line in the window - set line [lsearch -exact $pclist($cfunc) $pc] + set line [pc_to_line $pclist($cfunc) $pc] if {$line == -1} { echo "Can't find PC $pc" @@ -349,10 +349,16 @@ void (*flush_hook) PARAMS ((FILE *stream)); /* Called as appropriate to notify the interface of the specified breakpoint conditions. */ -void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b)); +void (*create_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); void (*enable_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); void (*disable_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); + +/* Called during long calculations to allow GUI to repair window damage, and to + check for stop buttons, etc... */ + +void (*interactive_hook) PARAMS ((void)); + /* Where to go for return_to_top_level (RETURN_ERROR). */ jmp_buf error_return; |