* defs.h (QUIT): Call interactive_hook to allow GUI to interrupt.
authorStu Grossman <grossman@cygnus>
Fri, 16 Sep 1994 22:57:37 +0000 (22:57 +0000)
committerStu Grossman <grossman@cygnus>
Fri, 16 Sep 1994 22:57:37 +0000 (22:57 +0000)
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.

gdb/ChangeLog
gdb/defs.h
gdb/gdbtk.c
gdb/gdbtk.tcl
gdb/top.c

index 398bd4c4e46f0d4f2f17e583ab5452a30e05fc67..8e8c8d12386c8fc5486f6790f74cdd20023a1215 100644 (file)
@@ -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.
index 4e98e2129346c7f37e4d0e2a3e71da398e3811a2..36baf7f4a361e1d7745b7d1469497b66dd66bab9 100644 (file)
@@ -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. */
 
index e3a2ce7359cc87ce5d642aa85f10021b38f6076e..9843b430774de0ce7192e06e9d40b86998f1408b 100644 (file)
@@ -129,6 +129,7 @@ gdbtk_query (args)
   return val;
 }
 \f
+#if 0
 static char *
 full_filename(symtab)
      struct symtab *symtab;
@@ -163,6 +164,7 @@ full_filename(symtab)
 
   return filename;
 }
+#endif
 \f
 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;
 }
 \f
@@ -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);
 
index a164faea15c33bf370926587078a83f236803055..a142c3d8f9b549865a501e04a82e946019659db2 100644 (file)
@@ -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
        }
 }
 
@@ -351,6 +345,43 @@ proc delete_breakpoint_tag {win line} {
        $win configure -state disabled
 }
 
+#
+# 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:
 #
@@ -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"
index 2b5e9afe7a948dcd3c87dfda5e6e0761c5028cf5..c052302f2f524b99e890ee8e6054e6f3ddd29d94 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -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));
+
 \f
 /* Where to go for return_to_top_level (RETURN_ERROR).  */
 jmp_buf error_return;