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.
PTR arg;
};
+/* Needed for various prototypes */
+
+#ifdef __STDC__
+struct symtab;
+struct breakpoint;
+#endif
+
/* From blockframe.c */
extern int inside_entry_func PARAMS ((CORE_ADDR));
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 *));
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). */
{
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));
/* 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));
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. */
return val;
}
\f
+#if 0
static char *
full_filename(symtab)
struct symtab *symtab;
return filename;
}
+#endif
\f
static void
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);
gdbtk_fputs (interp->result);
gdbtk_fputs ("\n");
}
-
- if (filename)
- free (filename);
}
static void
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);
sprintf (buf, "0x%x", pc);
Tcl_AppendElement (interp, buf); /* PC */
- if (filename)
- free(filename);
-
return TCL_OK;
}
\f
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 ()
{
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);
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]
}
}
# 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)
# 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]
}
}
}
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 {}
}
}
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
}
}
$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:
#
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
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
#
# 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:
#
# 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
# 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
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
# 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
# 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
}
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]
}
# 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"