mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 13:09:48 +00:00
Wed Jul 1 11:07:21 1998 Jim Ingham <jingham@cygnus.com>
* main.tcl (gdbtk_preloop): Call gdbtk_idle on spec. If there was an error in loading an executible specified on the command line, then the pre_add_symbol hook would have called gdbtk_busy but the corresponding call to gdbtk_idle would not have occured. Also changed some catch calls so they didn't use "catch {set foo [real_command]}" but rather the more efficient: "catch {real_command} foo" * register.tcl: more catch cleanups * src.tcl: more catch cleanups * stack.tcl: more catch cleanups * target.tcl: more catch cleanups * tdump.tcl: more catch cleanups * variables.tcl: more catch cleanups * watch.tcl: more catch cleanups * gdbtk.c (gdbtk_init): Fixed a bug in the startup code on Windows that caused gdbtk not to find the share directory unless GDBTK_LIBRARY was set. * gdbtk.c: removed all the commands and hooks from this file so now it contains only the startup code. * gdbtk_cmds.c: New file - this contains all the Tcl commands that gdb defines. All the old commands were moved here, the string-based commands were converted to object commands, and the object-based commands were all converted to uniformly use the call_wrapper. A new function, Gdbtk_Init was added to centralize initializing the gdb package. Also added gdbtk as a package into gdbtk_interp. * gdbtk_hooks.c: New file - All the hooks were moved here, and a new function, gdbtk_add_hooks was added to centralize adding all these hook functions. gdbtk_fputs was also modified to handle the new result_ptr structure. See the comments in gdbtk.h for more details. * gdbtk.h: New file - this contains all the defines and globals shared by gdbtk.c, gdbtk_cmds.c & gdbtk_hooks.c * Makefile.in, configure.in & configure: mutatis mutandi for the new files.
This commit is contained in:
parent
a95d955c68
commit
ca4e7e143d
@ -1,3 +1,27 @@
|
||||
Wed Jul 1 11:07:21 1998 Jim Ingham <jingham@cygnus.com>
|
||||
|
||||
* gdbtk.c: removed all the commands and hooks from this file so
|
||||
now it contains only the startup code.
|
||||
* gdbtk.c (gdbtk_init): Fixed a bug in the startup code on Windows
|
||||
that caused gdbtk not to find the share directory unless
|
||||
GDBTK_LIBRARY was set.
|
||||
* gdbtk_cmds.c: New file - this contains all the Tcl commands that
|
||||
gdb defines. All the old commands were moved here, the
|
||||
string-based commands were converted to object commands, and the
|
||||
object-based commands were all converted to uniformly use the
|
||||
call_wrapper. A new function, Gdbtk_Init was added to centralize
|
||||
initializing the gdb package.
|
||||
* gdbtk_hooks.c: New file - All the hooks were moved here, and a new
|
||||
function, gdbtk_add_hooks was added to centralize adding all these
|
||||
hook functions. gdbtk_fputs was also modified to handle the new
|
||||
result_ptr structure. See the comments in gdbtk.h for more
|
||||
details.
|
||||
* gdbtk.h: New file - this contains all the defines and globals
|
||||
shared by gdbtk.c, gdbtk_cmds.c & gdbtk_hooks.c
|
||||
* Makefile.in, configure.in & configure: mutatis mutandi for the
|
||||
new files.
|
||||
|
||||
|
||||
Mon Jun 29 11:49:17 1998 Keith Seitz <keiths@cygnus.com>
|
||||
|
||||
* main.c (main): Don't include gdbtk test code if GDBTK is
|
||||
|
@ -618,9 +618,10 @@ install-only:
|
||||
$(datadir)/gdbtcl/images \
|
||||
$(datadir)/gdbtcl/images2 ; \
|
||||
$(SHELL) $(srcdir)/../mkinstalldirs $(datadir)/gdbtcl/help \
|
||||
$(datadir)/gdbtcl/help/images; \
|
||||
$(datadir)/gdbtcl/help/images \
|
||||
$(datadir)/gdbtcl/help/trace ; \
|
||||
cd $(srcdir)/gdbtcl2 ; \
|
||||
for i in *.tcl images/*.gif images2/*.gif images/icons.txt images2/icons.txt tclIndex help/*.html help/index.toc help/images/*.gif; \
|
||||
for i in *.tcl images/*.gif images2/*.gif images/icons.txt images2/icons.txt tclIndex help/*.html help/index.toc help/trace/*.html help/trace/index.toc help/images/*.gif; \
|
||||
do \
|
||||
$(INSTALL_DATA) $$i $(datadir)/gdbtcl/$$i ; \
|
||||
done ;
|
||||
@ -1174,12 +1175,24 @@ fork-child.o: fork-child.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
||||
gdbres.o: gdb.rc gdbtool.ico
|
||||
$(WINDRES) --include $(srcdir) $(srcdir)/gdb.rc gdbres.o
|
||||
|
||||
gdbtk.o: gdbtk.c $(defs_h) $(symtab_h) $(inferior_h) $(command_h) \
|
||||
gdbtk.o: gdbtk.c gdbtk.h $(defs_h) $(symtab_h) $(inferior_h) $(command_h) \
|
||||
$(bfd_h) symfile.h objfiles.h target.h gdb_string.h $(tracepoint_h)
|
||||
$(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) $(TIX_CFLAGS) \
|
||||
$(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) \
|
||||
$(srcdir)/gdbtk.c -DGDBTK_LIBRARY=\"$(datadir)/gdbtcl\"
|
||||
|
||||
gdbtk_cmds.o: gdbtk_cmds.c gdbtk.h $(defs_h) $(symtab_h) $(inferior_h) $(command_h) \
|
||||
$(bfd_h) symfile.h objfiles.h target.h gdb_string.h $(tracepoint_h)
|
||||
$(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) $(TIX_CFLAGS) \
|
||||
$(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) \
|
||||
$(srcdir)/gdbtk_cmds.c -DGDBTK_LIBRARY=\"$(datadir)/gdbtcl\"
|
||||
|
||||
gdbtk_hooks.o: gdbtk_hooks.c gdbtk.h $(defs_h) $(symtab_h) $(inferior_h) $(command_h) \
|
||||
$(bfd_h) symfile.h objfiles.h target.h gdb_string.h $(tracepoint_h)
|
||||
$(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) $(TIX_CFLAGS) \
|
||||
$(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) \
|
||||
$(srcdir)/gdbtk_hooks.c -DGDBTK_LIBRARY=\"$(datadir)/gdbtcl\"
|
||||
|
||||
tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(tracepoint_h) \
|
||||
$(gdbtypes_h) $(expression_h) $(gdbcmd_h) $(value_h) target.h \
|
||||
language.h gdb_string.h $(readline_headers)
|
||||
|
2
gdb/configure
vendored
2
gdb/configure
vendored
@ -5213,7 +5213,7 @@ fi
|
||||
# were in LIBS then any link tests after this point would
|
||||
# try to include things like `$(LIBGUI)', which wouldn't work.
|
||||
GDBTKLIBS="${TCL_LIBS} ${TK_LIBS}"
|
||||
CONFIG_OBS="${CONFIG_OBS} gdbtk.o"
|
||||
CONFIG_OBS="${CONFIG_OBS} gdbtk.o gdbtk_cmds.o gdbtk_hooks.o"
|
||||
|
||||
if test x$gdb_cv_os_cygwin32 = xyes; then
|
||||
WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32 -luser32"
|
||||
|
@ -425,7 +425,7 @@ if test "${enable_gdbtk}" = "yes"; then
|
||||
# were in LIBS then any link tests after this point would
|
||||
# try to include things like `$(LIBGUI)', which wouldn't work.
|
||||
GDBTKLIBS="${TCL_LIBS} ${TK_LIBS}"
|
||||
CONFIG_OBS="${CONFIG_OBS} gdbtk.o"
|
||||
CONFIG_OBS="${CONFIG_OBS} gdbtk.o gdbtk_cmds.o gdbtk_hooks.o"
|
||||
|
||||
if test x$gdb_cv_os_cygwin32 = xyes; then
|
||||
WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32 -luser32"
|
||||
|
3227
gdb/gdbtk.c
3227
gdb/gdbtk.c
File diff suppressed because it is too large
Load Diff
145
gdb/gdbtk.h
Normal file
145
gdb/gdbtk.h
Normal file
@ -0,0 +1,145 @@
|
||||
/* Tcl/Tk interface routines header file.
|
||||
Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
|
||||
|
||||
This file is part of GDB. It contains the public data that is shared between
|
||||
the gdbtk startup code and the gdbtk commands.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef WINNT
|
||||
#define GDBTK_PATH_SEP ";"
|
||||
#else
|
||||
#define GDBTK_PATH_SEP ":"
|
||||
#endif
|
||||
|
||||
/* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
|
||||
gdbtk wants to use it... */
|
||||
#ifdef __linux__
|
||||
#undef SIOCSPGRP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These are the version numbers for GDBTK. There is a package require
|
||||
* statement in main.tcl that checks the version. If you make an incompatible
|
||||
* change to the gdb commands, or add any new commands, be sure to bump the
|
||||
* version number both here and in main.tcl. This will save us the trouble of
|
||||
* having a version of gdb find the wrong versions of the Tcl libraries.
|
||||
*/
|
||||
|
||||
#define GDBTK_MAJOR_VERSION "1"
|
||||
#define GDBTK_MINOR_VERSION "0"
|
||||
#define GDBTK_VERSION "1.0"
|
||||
|
||||
/*
|
||||
* These are variables that are needed in gdbtk commands.
|
||||
*/
|
||||
|
||||
/* This variable determines where memory used for disassembly is read from.
|
||||
If > 0, then disassembly comes from the exec file rather than the
|
||||
target (which might be at the other end of a slow serial link). If
|
||||
== 0 then disassembly comes from target. If < 0 disassembly is
|
||||
automatically switched to the target if it's an inferior process,
|
||||
otherwise the exec file is used. It is defined in gdbtk.c */
|
||||
|
||||
|
||||
extern int disassemble_from_exec;
|
||||
|
||||
/* This variable is true when the inferior is running. Although it's
|
||||
possible to disable most input from widgets and thus prevent
|
||||
attempts to do anything while the inferior is running, any commands
|
||||
that get through - even a simple memory read - are Very Bad, and
|
||||
may cause GDB to crash or behave strangely. So, this variable
|
||||
provides an extra layer of defense. It is defined in gdbtk.c */
|
||||
|
||||
extern int running_now;
|
||||
|
||||
/* These two control how the GUI behaves when tracing or loading
|
||||
They are defined in gdbtk_cmds.c */
|
||||
|
||||
extern int No_Update;
|
||||
extern int load_in_progress;
|
||||
|
||||
/* This is the main gdbtk interpreter. It is defined and initialized
|
||||
in gdbtk.c */
|
||||
|
||||
extern Tcl_Interp *gdbtk_interp;
|
||||
|
||||
/*
|
||||
* This structure controls how the gdb output is fed into call_wrapper invoked
|
||||
* commands. See the explanation of gdbtk_fputs in gdbtk_hooks.c for more details.
|
||||
*/
|
||||
|
||||
typedef struct gdbtk_result {
|
||||
Tcl_Obj *obj_ptr; /* This will eventually be copied over to the
|
||||
Tcl result */
|
||||
int flags; /* Flag vector to control how the result is
|
||||
used. */
|
||||
} gdbtk_result;
|
||||
|
||||
/* These defines give the allowed values for the gdbtk_result.flags field. */
|
||||
|
||||
#define GDBTK_TO_RESULT 1 /* This controls whether output from
|
||||
gdbtk_fputs goes to the command result, or
|
||||
to gdbtk_tcl_fputs. */
|
||||
#define GDBTK_MAKES_LIST 2 /* whether gdbtk_fputs adds the
|
||||
element it is outputting as a string, or
|
||||
as a separate list element. */
|
||||
#define GDBTK_IN_TCL_RESULT 4 /* Indicates that the result is already in the
|
||||
Tcl result. You can use this to preserve
|
||||
error messages from functions like
|
||||
Tcl_GetIntFromObj. You can also store the
|
||||
output of a call wrapped command directly in
|
||||
the Tcl result if you want, but beware, it will
|
||||
not then be preserved across recursive
|
||||
call_wrapper invocations. */
|
||||
#define GDBTK_ERROR_STARTED 8 /* This one is just used in gdbtk_fputs. If we
|
||||
see some output on stderr, we need to clear
|
||||
the result we have been accumulating, or the
|
||||
error and the previous successful output
|
||||
will get mixed, which would be confusing. */
|
||||
|
||||
|
||||
/* This is a pointer to the gdbtk_result struct that
|
||||
we are currently filling. We use the C stack to make a stack of these
|
||||
structures for nested calls to gdbtk commands that are invoked through
|
||||
the call_wrapper mechanism. See that function for more details. */
|
||||
|
||||
extern gdbtk_result *result_ptr;
|
||||
|
||||
/*
|
||||
* These functions are used in all the modules of Gdbtk.
|
||||
*
|
||||
*/
|
||||
|
||||
extern int Gdbtk_Init(Tcl_Interp *interp);
|
||||
extern void gdbtk_stop_timer PARAMS ((void));
|
||||
extern void gdbtk_start_timer PARAMS ((void));
|
||||
extern void gdbtk_ignorable_warning PARAMS ((const char *));
|
||||
extern void gdbtk_interactive PARAMS ((void));
|
||||
extern void x_event PARAMS ((int));
|
||||
extern int gdbtk_two_elem_cmd PARAMS ((char *, char *));
|
||||
|
||||
#ifdef _WIN32
|
||||
extern void close_bfds ();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
extern void
|
||||
#ifdef ANSI_PROTOTYPES
|
||||
TclDebug (const char *fmt, ...);
|
||||
#else
|
||||
TclDebug (va_alist);
|
||||
#endif
|
3075
gdb/gdbtk_cmds.c
Normal file
3075
gdb/gdbtk_cmds.c
Normal file
File diff suppressed because it is too large
Load Diff
689
gdb/gdbtk_hooks.c
Normal file
689
gdb/gdbtk_hooks.c
Normal file
@ -0,0 +1,689 @@
|
||||
/* Startup code for gdbtk.
|
||||
Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "inferior.h"
|
||||
#include "command.h"
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
#include "target.h"
|
||||
#include "gdbcore.h"
|
||||
#include "tracepoint.h"
|
||||
#include "demangle.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winuser.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <tcl.h>
|
||||
#include <tk.h>
|
||||
#include <itcl.h>
|
||||
#include <tix.h>
|
||||
#include "guitcl.h"
|
||||
#include "gdbtk.h"
|
||||
|
||||
#ifdef IDE
|
||||
/* start-sanitize-ide */
|
||||
#include "event.h"
|
||||
#include "idetcl.h"
|
||||
#include "ilutk.h"
|
||||
/* end-sanitize-ide */
|
||||
#endif
|
||||
|
||||
#ifdef ANSI_PROTOTYPES
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include "top.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include "gdb_string.h"
|
||||
#include "dis-asm.h"
|
||||
#include <stdio.h>
|
||||
#include "gdbcmd.h"
|
||||
|
||||
#include "annotate.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
int in_fputs = 0;
|
||||
|
||||
int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
|
||||
void (*pre_add_symbol_hook) PARAMS ((char *));
|
||||
void (*post_add_symbol_hook) PARAMS ((void));
|
||||
|
||||
#ifdef __CYGWIN32__
|
||||
extern void (*ui_loop_hook) PARAMS ((int));
|
||||
#endif
|
||||
static void gdbtk_create_tracepoint PARAMS ((struct tracepoint *));
|
||||
static void gdbtk_delete_tracepoint PARAMS ((struct tracepoint *));
|
||||
static void gdbtk_modify_tracepoint PARAMS ((struct tracepoint *));
|
||||
static void gdbtk_create_breakpoint PARAMS ((struct breakpoint *));
|
||||
static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *));
|
||||
static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *));
|
||||
static void tk_command_loop PARAMS ((void));
|
||||
static void gdbtk_call_command PARAMS ((struct cmd_list_element *, char *, int));
|
||||
static int gdbtk_wait PARAMS ((int, struct target_waitstatus *));
|
||||
void x_event PARAMS ((int));
|
||||
static int gdbtk_query PARAMS ((const char *, va_list));
|
||||
static void gdbtk_warning PARAMS ((const char *, va_list));
|
||||
void gdbtk_ignorable_warning PARAMS ((const char *));
|
||||
static char* gdbtk_readline PARAMS ((char *));
|
||||
static void
|
||||
#ifdef ANSI_PROTOTYPES
|
||||
gdbtk_readline_begin (char *format, ...);
|
||||
#else
|
||||
gdbtk_readline_begin ();
|
||||
#endif
|
||||
static void gdbtk_readline_end PARAMS ((void));
|
||||
static void gdbtk_flush PARAMS ((FILE *));
|
||||
static void gdbtk_pre_add_symbol PARAMS ((char *));
|
||||
static void gdbtk_print_frame_info PARAMS ((struct symtab *, int, int, int));
|
||||
static void gdbtk_post_add_symbol PARAMS ((void));
|
||||
static void pc_changed PARAMS ((void));
|
||||
static void tracepoint_notify PARAMS ((struct tracepoint *, const char *));
|
||||
|
||||
/*
|
||||
* gdbtk_fputs can't be static, because we need to call it in gdbtk.c.
|
||||
* See note there for details.
|
||||
*/
|
||||
|
||||
void gdbtk_fputs PARAMS ((const char *, FILE *));
|
||||
int gdbtk_load_hash PARAMS ((char *, unsigned long));
|
||||
static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
|
||||
|
||||
/*
|
||||
* gdbtk_add_hooks - add all the hooks to gdb. This will get called by the
|
||||
* startup code to fill in the hooks needed by core gdb.
|
||||
*/
|
||||
|
||||
void
|
||||
gdbtk_add_hooks(void)
|
||||
{
|
||||
command_loop_hook = tk_command_loop;
|
||||
call_command_hook = gdbtk_call_command;
|
||||
readline_begin_hook = gdbtk_readline_begin;
|
||||
readline_hook = gdbtk_readline;
|
||||
readline_end_hook = gdbtk_readline_end;
|
||||
|
||||
print_frame_info_listing_hook = gdbtk_print_frame_info;
|
||||
query_hook = gdbtk_query;
|
||||
warning_hook = gdbtk_warning;
|
||||
flush_hook = gdbtk_flush;
|
||||
|
||||
create_breakpoint_hook = gdbtk_create_breakpoint;
|
||||
delete_breakpoint_hook = gdbtk_delete_breakpoint;
|
||||
modify_breakpoint_hook = gdbtk_modify_breakpoint;
|
||||
|
||||
interactive_hook = gdbtk_interactive;
|
||||
target_wait_hook = gdbtk_wait;
|
||||
ui_load_progress_hook = gdbtk_load_hash;
|
||||
#ifdef __CYGWIN32__
|
||||
ui_loop_hook = x_event;
|
||||
#endif
|
||||
pre_add_symbol_hook = gdbtk_pre_add_symbol;
|
||||
post_add_symbol_hook = gdbtk_post_add_symbol;
|
||||
|
||||
create_tracepoint_hook = gdbtk_create_tracepoint;
|
||||
delete_tracepoint_hook = gdbtk_delete_tracepoint;
|
||||
modify_tracepoint_hook = gdbtk_modify_tracepoint;
|
||||
pc_changed_hook = pc_changed;
|
||||
|
||||
}
|
||||
|
||||
/* These control where to put the gdb output which is created by
|
||||
{f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
|
||||
lowest level of these routines and capture all output from the rest of GDB.
|
||||
|
||||
The reason to use the result_ptr rather than the gdbtk_interp's result
|
||||
directly is so that a call_wrapper invoked function can preserve its result
|
||||
across calls into Tcl which might be made in the course of the function's
|
||||
execution.
|
||||
|
||||
* result_ptr->obj_ptr is where to accumulate the result.
|
||||
* GDBTK_TO_RESULT flag means the output goes to the gdbtk_tcl_fputs proc
|
||||
instead of to the result_ptr.
|
||||
* GDBTK_MAKES_LIST flag means add to the result as a list element.
|
||||
|
||||
*/
|
||||
|
||||
gdbtk_result *result_ptr = NULL;
|
||||
|
||||
|
||||
/* This allows you to Tcl_Eval a tcl command which takes
|
||||
a command word, and then a single argument. */
|
||||
|
||||
int gdbtk_two_elem_cmd (cmd_name, argv1)
|
||||
char *cmd_name;
|
||||
char * argv1;
|
||||
{
|
||||
char *command;
|
||||
int result, flags_ptr, arg_len, cmd_len;
|
||||
|
||||
arg_len = Tcl_ScanElement (argv1, &flags_ptr);
|
||||
cmd_len = strlen (cmd_name);
|
||||
command = malloc(arg_len + cmd_len + 2);
|
||||
strcpy (command, cmd_name);
|
||||
strcat (command, " ");
|
||||
|
||||
Tcl_ConvertElement (argv1, command + cmd_len + 1, flags_ptr);
|
||||
|
||||
result = Tcl_Eval (gdbtk_interp, command);
|
||||
free (command);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_flush (stream)
|
||||
FILE *stream;
|
||||
{
|
||||
#if 0
|
||||
/* Force immediate screen update */
|
||||
|
||||
Tcl_VarEval (gdbtk_interp, "gdbtk_tcl_flush", NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This handles all the output from gdb. All the gdb printf_xxx functions
|
||||
* eventually end up here. The output is either passed to the result_ptr
|
||||
* where it will go to the result of some gdbtk command, or passed to the
|
||||
* Tcl proc gdbtk_tcl_fputs (where it is usually just dumped to the console
|
||||
* window.
|
||||
*
|
||||
* The cases are:
|
||||
*
|
||||
* 1) result_ptr == NULL - This happens when some output comes from gdb which
|
||||
* is not generated by a command in gdbtk_cmds, usually startup stuff.
|
||||
* In this case we just route the data to gdbtk_tcl_fputs.
|
||||
* 2) The GDBTK_TO_RESULT flag is set - The result is supposed to go to Tcl.
|
||||
* We place the data into the result_ptr, either as a string,
|
||||
* or a list, depending whether the GDBTK_MAKES_LIST bit is set.
|
||||
* 3) The GDBTK_TO_RESULT flag is unset - We route the data to gdbtk_tcl_fputs
|
||||
* UNLESS it was coming to stderr. Then we place it in the result_ptr
|
||||
* anyway, so it can be dealt with.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
gdbtk_fputs (ptr, stream)
|
||||
const char *ptr;
|
||||
FILE *stream;
|
||||
{
|
||||
in_fputs = 1;
|
||||
|
||||
if (result_ptr != NULL)
|
||||
{
|
||||
if (result_ptr->flags & GDBTK_TO_RESULT)
|
||||
{
|
||||
if (result_ptr->flags & GDBTK_MAKES_LIST)
|
||||
Tcl_ListObjAppendElement(NULL, result_ptr->obj_ptr,
|
||||
Tcl_NewStringObj((char *) ptr, -1));
|
||||
else
|
||||
Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1);
|
||||
}
|
||||
else if (stream == gdb_stderr)
|
||||
{
|
||||
if (result_ptr->flags & GDBTK_ERROR_STARTED)
|
||||
Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1);
|
||||
else
|
||||
{
|
||||
Tcl_SetStringObj (result_ptr->obj_ptr, (char *) ptr, -1);
|
||||
result_ptr->flags |= GDBTK_ERROR_STARTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr);
|
||||
if (result_ptr->flags & GDBTK_MAKES_LIST)
|
||||
gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", " ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr);
|
||||
}
|
||||
|
||||
in_fputs = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routes all warnings to the Tcl function "gdbtk_tcl_warning".
|
||||
*/
|
||||
|
||||
static void
|
||||
gdbtk_warning (warning, args)
|
||||
const char *warning;
|
||||
va_list args;
|
||||
{
|
||||
char buf[200];
|
||||
|
||||
vsprintf (buf, warning, args);
|
||||
gdbtk_two_elem_cmd ("gdbtk_tcl_warning", buf);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This routes all ignorable warnings to the Tcl function
|
||||
* "gdbtk_tcl_ignorable_warning".
|
||||
*/
|
||||
|
||||
void
|
||||
gdbtk_ignorable_warning (warning)
|
||||
const char *warning;
|
||||
{
|
||||
char buf[200], *merge[2];
|
||||
char *command;
|
||||
|
||||
sprintf (buf, warning);
|
||||
gdbtk_two_elem_cmd ("gdbtk_tcl_ignorable_warning", buf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
pc_changed()
|
||||
{
|
||||
Tcl_Eval (gdbtk_interp, "gdbtk_pc_changed");
|
||||
}
|
||||
|
||||
|
||||
/* This function is called instead of gdb's internal command loop. This is the
|
||||
last chance to do anything before entering the main Tk event loop.
|
||||
At the end of the command, we enter the main loop. */
|
||||
|
||||
static void
|
||||
tk_command_loop ()
|
||||
{
|
||||
extern GDB_FILE *instream;
|
||||
|
||||
/* We no longer want to use stdin as the command input stream */
|
||||
instream = NULL;
|
||||
|
||||
if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_preloop") != TCL_OK)
|
||||
{
|
||||
char *msg;
|
||||
|
||||
/* Force errorInfo to be set up propertly. */
|
||||
Tcl_AddErrorInfo (gdbtk_interp, "");
|
||||
|
||||
msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY);
|
||||
#ifdef _WIN32
|
||||
MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
|
||||
#else
|
||||
fputs_unfiltered (msg, gdb_stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
close_bfds ();
|
||||
#endif
|
||||
|
||||
Tk_MainLoop ();
|
||||
}
|
||||
|
||||
/* Come here when there is activity on the X file descriptor. */
|
||||
|
||||
void
|
||||
x_event (signo)
|
||||
int signo;
|
||||
{
|
||||
static int in_x_event = 0;
|
||||
static Tcl_Obj *varname = NULL;
|
||||
if (in_x_event || in_fputs)
|
||||
return;
|
||||
|
||||
in_x_event = 1;
|
||||
|
||||
#ifdef __CYGWIN32__
|
||||
if (signo == -2)
|
||||
gdbtk_stop_timer ();
|
||||
#endif
|
||||
|
||||
/* Process pending events */
|
||||
while (Tcl_DoOneEvent (TCL_DONT_WAIT|TCL_ALL_EVENTS) != 0)
|
||||
;
|
||||
|
||||
if (load_in_progress)
|
||||
{
|
||||
int val;
|
||||
if (varname == NULL)
|
||||
{
|
||||
Tcl_Obj *varnamestrobj = Tcl_NewStringObj("download_cancel_ok",-1);
|
||||
varname = Tcl_ObjGetVar2(gdbtk_interp,varnamestrobj,NULL,TCL_GLOBAL_ONLY);
|
||||
}
|
||||
if ((Tcl_GetIntFromObj(gdbtk_interp,varname,&val) == TCL_OK) && val)
|
||||
{
|
||||
quit_flag = 1;
|
||||
#ifdef REQUEST_QUIT
|
||||
REQUEST_QUIT;
|
||||
#else
|
||||
if (immediate_quit)
|
||||
quit ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
in_x_event = 0;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
#ifdef ANSI_PROTOTYPES
|
||||
gdbtk_readline_begin (char *format, ...)
|
||||
#else
|
||||
gdbtk_readline_begin (va_alist)
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
char buf[200], *merge[2];
|
||||
char *command;
|
||||
|
||||
#ifdef ANSI_PROTOTYPES
|
||||
va_start (args, format);
|
||||
#else
|
||||
char *format;
|
||||
va_start (args);
|
||||
format = va_arg (args, char *);
|
||||
#endif
|
||||
|
||||
vsprintf (buf, format, args);
|
||||
gdbtk_two_elem_cmd ("gdbtk_tcl_readline_begin", buf);
|
||||
|
||||
}
|
||||
|
||||
static char *
|
||||
gdbtk_readline (prompt)
|
||||
char *prompt;
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef _WIN32
|
||||
close_bfds ();
|
||||
#endif
|
||||
|
||||
result = gdbtk_two_elem_cmd ("gdbtk_tcl_readline", prompt);
|
||||
|
||||
if (result == TCL_OK)
|
||||
{
|
||||
return (strdup (gdbtk_interp -> result));
|
||||
}
|
||||
else
|
||||
{
|
||||
gdbtk_fputs (gdbtk_interp -> result, gdb_stdout);
|
||||
gdbtk_fputs ("\n", gdb_stdout);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_readline_end ()
|
||||
{
|
||||
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_readline_end");
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_call_command (cmdblk, arg, from_tty)
|
||||
struct cmd_list_element *cmdblk;
|
||||
char *arg;
|
||||
int from_tty;
|
||||
{
|
||||
running_now = 0;
|
||||
if (cmdblk->class == class_run || cmdblk->class == class_trace)
|
||||
{
|
||||
|
||||
/* HACK! HACK! This is to get the gui to update the tstart/tstop
|
||||
button only incase of tstart/tstop commands issued from the console
|
||||
We don't want to update the src window, so we need to have specific
|
||||
procedures to do tstart and tstop
|
||||
Unfortunately this will not display errors from tstart or tstop in the
|
||||
console window itself, but as dialogs.*/
|
||||
|
||||
if (!strcmp(cmdblk->name, "tstart") && !No_Update)
|
||||
{
|
||||
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_tstart");
|
||||
(*cmdblk->function.cfunc)(arg, from_tty);
|
||||
}
|
||||
else if (!strcmp(cmdblk->name, "tstop") && !No_Update)
|
||||
{
|
||||
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_tstop");
|
||||
(*cmdblk->function.cfunc)(arg, from_tty);
|
||||
}
|
||||
/* end of hack */
|
||||
else
|
||||
{
|
||||
running_now = 1;
|
||||
if (!No_Update)
|
||||
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_busy");
|
||||
(*cmdblk->function.cfunc)(arg, from_tty);
|
||||
running_now = 0;
|
||||
if (!No_Update)
|
||||
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_idle");
|
||||
}
|
||||
}
|
||||
else
|
||||
(*cmdblk->function.cfunc)(arg, from_tty);
|
||||
}
|
||||
|
||||
/* The next three functions use breakpoint_notify to allow the GUI
|
||||
* to handle creating, deleting and modifying breakpoints. These three
|
||||
* functions are put into the appropriate gdb hooks in gdbtk_init.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdbtk_create_breakpoint(b)
|
||||
struct breakpoint *b;
|
||||
{
|
||||
breakpoint_notify (b, "create");
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_delete_breakpoint(b)
|
||||
struct breakpoint *b;
|
||||
{
|
||||
breakpoint_notify (b, "delete");
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_modify_breakpoint(b)
|
||||
struct breakpoint *b;
|
||||
{
|
||||
breakpoint_notify (b, "modify");
|
||||
}
|
||||
|
||||
/* This is the generic function for handling changes in
|
||||
* a breakpoint. It routes the information to the Tcl
|
||||
* command "gdbtk_tcl_breakpoint" in the form:
|
||||
* gdbtk_tcl_breakpoint action b_number b_address b_line b_file
|
||||
* On error, the error string is written to gdb_stdout.
|
||||
*/
|
||||
|
||||
static void
|
||||
breakpoint_notify(b, action)
|
||||
struct breakpoint *b;
|
||||
const char *action;
|
||||
{
|
||||
char buf[256];
|
||||
int v;
|
||||
struct symtab_and_line sal;
|
||||
char *filename;
|
||||
|
||||
if (b->type != bp_breakpoint)
|
||||
return;
|
||||
|
||||
/* We ensure that ACTION contains no special Tcl characters, so we
|
||||
can do this. */
|
||||
sal = find_pc_line (b->address, 0);
|
||||
filename = symtab_to_filename (sal.symtab);
|
||||
if (filename == NULL)
|
||||
filename = "";
|
||||
|
||||
sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action, b->number,
|
||||
(long)b->address, b->line_number, filename);
|
||||
|
||||
v = Tcl_Eval (gdbtk_interp, buf);
|
||||
|
||||
if (v != TCL_OK)
|
||||
{
|
||||
gdbtk_fputs (Tcl_GetStringResult (gdbtk_interp), gdb_stdout);
|
||||
gdbtk_fputs ("\n", gdb_stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
gdbtk_load_hash (section, num)
|
||||
char *section;
|
||||
unsigned long num;
|
||||
{
|
||||
char buf[128];
|
||||
sprintf (buf, "download_hash %s %ld", section, num);
|
||||
Tcl_Eval (gdbtk_interp, buf);
|
||||
return atoi (gdbtk_interp->result);
|
||||
}
|
||||
|
||||
|
||||
/* This hook is called whenever we are ready to load a symbol file so that
|
||||
the UI can notify the user... */
|
||||
static void
|
||||
gdbtk_pre_add_symbol (name)
|
||||
char *name;
|
||||
{
|
||||
|
||||
gdbtk_two_elem_cmd("gdbtk_tcl_pre_add_symbol", name);
|
||||
|
||||
}
|
||||
|
||||
/* This hook is called whenever we finish loading a symbol file. */
|
||||
static void
|
||||
gdbtk_post_add_symbol ()
|
||||
{
|
||||
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_post_add_symbol");
|
||||
}
|
||||
|
||||
/* This hook function is called whenever we want to wait for the
|
||||
target. */
|
||||
|
||||
static int
|
||||
gdbtk_wait (pid, ourstatus)
|
||||
int pid;
|
||||
struct target_waitstatus *ourstatus;
|
||||
{
|
||||
gdbtk_start_timer ();
|
||||
pid = target_wait (pid, ourstatus);
|
||||
gdbtk_stop_timer ();
|
||||
return pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* This handles all queries from gdb.
|
||||
* The first argument is a printf style format statement, the rest are its
|
||||
* arguments. The resultant formatted string is passed to the Tcl function
|
||||
* "gdbtk_tcl_query".
|
||||
* It returns the users response to the query, as well as putting the value
|
||||
* in the result field of the Tcl interpreter.
|
||||
*/
|
||||
|
||||
static int
|
||||
gdbtk_query (query, args)
|
||||
const char *query;
|
||||
va_list args;
|
||||
{
|
||||
char buf[200];
|
||||
long val;
|
||||
|
||||
vsprintf (buf, query, args);
|
||||
gdbtk_two_elem_cmd ("gdbtk_tcl_query", buf);
|
||||
|
||||
val = atol (gdbtk_interp->result);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdbtk_print_frame_info (s, line, stopline, noerror)
|
||||
struct symtab *s;
|
||||
int line;
|
||||
int stopline;
|
||||
int noerror;
|
||||
{
|
||||
current_source_symtab = s;
|
||||
current_source_line = line;
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_create_tracepoint (tp)
|
||||
struct tracepoint *tp;
|
||||
{
|
||||
tracepoint_notify (tp, "create");
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_delete_tracepoint (tp)
|
||||
struct tracepoint *tp;
|
||||
{
|
||||
tracepoint_notify (tp, "delete");
|
||||
}
|
||||
|
||||
static void
|
||||
gdbtk_modify_tracepoint (tp)
|
||||
struct tracepoint *tp;
|
||||
{
|
||||
tracepoint_notify (tp, "modify");
|
||||
}
|
||||
|
||||
static void
|
||||
tracepoint_notify(tp, action)
|
||||
struct tracepoint *tp;
|
||||
const char *action;
|
||||
{
|
||||
char buf[256];
|
||||
int v;
|
||||
struct symtab_and_line sal;
|
||||
char *filename;
|
||||
|
||||
/* We ensure that ACTION contains no special Tcl characters, so we
|
||||
can do this. */
|
||||
sal = find_pc_line (tp->address, 0);
|
||||
|
||||
filename = symtab_to_filename (sal.symtab);
|
||||
if (filename == NULL)
|
||||
filename = "N/A";
|
||||
sprintf (buf, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s}", action, tp->number,
|
||||
(long)tp->address, sal.line, filename, tp->pass_count);
|
||||
|
||||
v = Tcl_Eval (gdbtk_interp, buf);
|
||||
|
||||
if (v != TCL_OK)
|
||||
{
|
||||
gdbtk_fputs (gdbtk_interp->result, gdb_stdout);
|
||||
gdbtk_fputs ("\n", gdb_stdout);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user