* symtab.h (enum namespace): Add new namespaces FUNCTIONS_NAMESPACE,

TYPES_NAMESPACE, METHODS_NAMESPACE, and VARIABLES_NAMESPACE used by
        new search_symbols.
        Add prototype for search_symbols and free_search_symbols.

        * symtab.c (list_symbols): Rewrite to use new search_symbols.
        (file_matches): New helper function for search_symbols.
        (free_search_symbols): New function which frees data returned from
        search_symbols.
        (print_symbol_info): New helper function which prints info about a
        matched symbol to stdout. Extracted from old list_symbols.
        (print_msymbol_info): New helper function which prints info about
        a matched msymbol to stdout. Extracted from old list_symbols.
        (symtab_symbol_info): Extracted from old list_symbols.
        (variables_info): Use symtab_symbol_info.
        (functions_info): Use symtab_symbol_info.
        (types_info): Use symtab_symbol_info.
        (rbreak_command): Rewrite to use new search_symbols.

        * gdbtk.c: Change all references to static global "interp" to
        "gdbtk_interp" and export this global.
        (gdbtk_init): If gdbtk_source_filename is not NULL, source this file
        into the interpreter when it goes idle.
        Add new command "gdb_search".
        (gdb_search): New function which searches the symbol table.
        (gdbtk_test): New function called by main when the --tclcommand
        option is used.

        * main.c (main): Add a new option "--tclcommand" which is used
        by the testsuite to source a file into the interpreter when it
        goes idle.
This commit is contained in:
Keith Seitz 1998-06-27 00:45:20 +00:00
parent 6cddf7d967
commit 7f6cb62ee6
5 changed files with 843 additions and 444 deletions

View file

@ -1,3 +1,24 @@
Fri Jun 26 14:03:01 1998 Keith Seitz <keiths@cygnus.com>
* symtab.h (enum namespace): Add new namespaces FUNCTIONS_NAMESPACE,
TYPES_NAMESPACE, METHODS_NAMESPACE, and VARIABLES_NAMESPACE used by
new search_symbols.
Add prototype for search_symbols and free_search_symbols.
* symtab.c (list_symbols): Rewrite to use new search_symbols.
(file_matches): New helper function for search_symbols.
(free_search_symbols): New function which frees data returned from
search_symbols.
(print_symbol_info): New helper function which prints info about a
matched symbol to stdout. Extracted from old list_symbols.
(print_msymbol_info): New helper function which prints info about
a matched msymbol to stdout. Extracted from old list_symbols.
(symtab_symbol_info): Extracted from old list_symbols.
(variables_info): Use symtab_symbol_info.
(functions_info): Use symtab_symbol_info.
(types_info): Use symtab_symbol_info.
(rbreak_command): Rewrite to use new search_symbols.
Thu Jun 25 22:38:32 1998 Frank Ch. Eigler <fche@cygnus.com>
* mips-tdep.c (mips_push_arguments): Use 128-bit stack frame

View file

@ -1,3 +1,18 @@
Fri Jun 26 13:56:07 1998 Keith Seitz <keiths@cygnus.com>
* gdbtk.c: Change all references to static global "interp" to
"gdbtk_interp" and export this global.
(gdbtk_init): If gdbtk_source_filename is not NULL, source this file
into the interpreter when it goes idle.
Add new command "gdb_search".
(gdb_search): New function which searches the symbol table.
(gdbtk_test): New function called by main when the --tclcommand
option is used.
* main.c (main): Add a new option "--tclcommand" which is used
by the testsuite to source a file into the interpreter when it
goes idle.
Wed Jun 17 19:12:23 1998 Jeff Holcomb <jeffh@cygnus.com>
* Makefile.in (install-only): Install tracing help files.

View file

@ -99,6 +99,7 @@ extern void (*ui_loop_hook) PARAMS ((int));
char * get_prompt PARAMS ((void));
int gdbtk_test PARAMS ((char *));
static void null_routine PARAMS ((int));
static void gdbtk_flush PARAMS ((FILE *));
static void gdbtk_fputs PARAMS ((const char *, FILE *));
@ -174,10 +175,11 @@ static int gdb_loadfile PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST o
static int gdb_set_bp PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
static struct symtab *full_lookup_symtab PARAMS ((char *file));
static int gdb_get_mem PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
static int gdb_search PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
static int gdb_get_trace_frame_num PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
/* Handle for TCL interpreter */
static Tcl_Interp *interp = NULL;
Tcl_Interp *gdbtk_interp = NULL;
static int gdbtk_timer_going = 0;
static void gdbtk_start_timer PARAMS ((void));
@ -201,6 +203,10 @@ static int running_now;
static int disassemble_from_exec = -1;
/* This variable holds the name of a Tcl file which should be sourced by the
interpreter when it goes idle at startup. Used with the testsuite. */
static char *gdbtk_source_filename = NULL;
#ifndef _WIN32
/* Supply malloc calls for tcl/tk. We do not want to do this on
@ -292,7 +298,7 @@ gdbtk_flush (stream)
#if 0
/* Force immediate screen update */
Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
Tcl_VarEval (gdbtk_interp, "gdbtk_tcl_flush", NULL);
#endif
}
@ -319,7 +325,7 @@ gdbtk_fputs (ptr, stream)
merge[0] = "gdbtk_tcl_fputs";
merge[1] = (char *)ptr;
command = Tcl_Merge (2, merge);
Tcl_Eval (interp, command);
Tcl_Eval (gdbtk_interp, command);
Tcl_Free (command);
}
in_fputs = 0;
@ -337,7 +343,7 @@ gdbtk_warning (warning, args)
merge[0] = "gdbtk_tcl_warning";
merge[1] = buf;
command = Tcl_Merge (2, merge);
Tcl_Eval (interp, command);
Tcl_Eval (gdbtk_interp, command);
Tcl_Free (command);
}
@ -352,7 +358,7 @@ gdbtk_ignorable_warning (warning)
merge[0] = "gdbtk_tcl_ignorable_warning";
merge[1] = buf;
command = Tcl_Merge (2, merge);
Tcl_Eval (interp, command);
Tcl_Eval (gdbtk_interp, command);
Tcl_Free (command);
}
@ -369,10 +375,10 @@ gdbtk_query (query, args)
merge[0] = "gdbtk_tcl_query";
merge[1] = buf;
command = Tcl_Merge (2, merge);
Tcl_Eval (interp, command);
Tcl_Eval (gdbtk_interp, command);
Tcl_Free (command);
val = atol (interp->result);
val = atol (gdbtk_interp->result);
return val;
}
@ -401,7 +407,7 @@ gdbtk_readline_begin (va_alist)
merge[0] = "gdbtk_tcl_readline_begin";
merge[1] = buf;
command = Tcl_Merge (2, merge);
Tcl_Eval (interp, command);
Tcl_Eval (gdbtk_interp, command);
Tcl_Free (command);
}
@ -420,15 +426,15 @@ gdbtk_readline (prompt)
merge[0] = "gdbtk_tcl_readline";
merge[1] = prompt;
command = Tcl_Merge (2, merge);
result = Tcl_Eval (interp, command);
result = Tcl_Eval (gdbtk_interp, command);
Tcl_Free (command);
if (result == TCL_OK)
{
return (strdup (interp -> result));
return (strdup (gdbtk_interp -> result));
}
else
{
gdbtk_fputs (interp -> result, gdb_stdout);
gdbtk_fputs (gdbtk_interp -> result, gdb_stdout);
gdbtk_fputs ("\n", gdb_stdout);
return (NULL);
}
@ -437,13 +443,13 @@ gdbtk_readline (prompt)
static void
gdbtk_readline_end ()
{
Tcl_Eval (interp, "gdbtk_tcl_readline_end");
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_readline_end");
}
static void
pc_changed()
{
Tcl_Eval (interp, "gdbtk_pc_changed");
Tcl_Eval (gdbtk_interp, "gdbtk_pc_changed");
}
@ -610,11 +616,11 @@ breakpoint_notify(b, action)
sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action, b->number,
(long)b->address, b->line_number, filename);
v = Tcl_Eval (interp, buf);
v = Tcl_Eval (gdbtk_interp, buf);
if (v != TCL_OK)
{
gdbtk_fputs (interp->result, gdb_stdout);
gdbtk_fputs (gdbtk_interp->result, gdb_stdout);
gdbtk_fputs ("\n", gdb_stdout);
}
}
@ -1873,9 +1879,9 @@ tk_command (cmd, from_tty)
if (cmd == NULL)
error_no_arg ("tcl command to interpret");
retval = Tcl_Eval (interp, cmd);
retval = Tcl_Eval (gdbtk_interp, cmd);
result = strdup (interp->result);
result = strdup (gdbtk_interp->result);
old_chain = make_cleanup (free, result);
@ -1891,9 +1897,9 @@ static void
cleanup_init (ignored)
int ignored;
{
if (interp != NULL)
Tcl_DeleteInterp (interp);
interp = NULL;
if (gdbtk_interp != NULL)
Tcl_DeleteInterp (gdbtk_interp);
gdbtk_interp = NULL;
}
/* Come here during long calculations to check for GUI events. Usually invoked
@ -1934,9 +1940,9 @@ x_event (signo)
if (varname == NULL)
{
Tcl_Obj *varnamestrobj = Tcl_NewStringObj ("download_cancel_ok",-1);
varname = Tcl_ObjGetVar2(interp,varnamestrobj,NULL,TCL_GLOBAL_ONLY);
varname = Tcl_ObjGetVar2 (gdbtk_interp,varnamestrobj,NULL,TCL_GLOBAL_ONLY);
}
if ((Tcl_GetIntFromObj(interp,varname,&val) == TCL_OK) && val)
if ((Tcl_GetIntFromObj (gdbtk_interp,varname,&val) == TCL_OK) && val)
{
quit_flag = 1;
#ifdef REQUEST_QUIT
@ -2047,12 +2053,12 @@ gdbtk_call_command (cmdblk, arg, from_tty)
if (!strcmp(cmdblk->name, "tstart") && !No_Update)
{
Tcl_Eval (interp, "gdbtk_tcl_tstart");
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_tstart");
(*cmdblk->function.cfunc)(arg, from_tty);
}
else if (!strcmp(cmdblk->name, "tstop") && !No_Update)
{
Tcl_Eval (interp, "gdbtk_tcl_tstop");
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_tstop");
(*cmdblk->function.cfunc)(arg, from_tty);
}
/* end of hack */
@ -2060,11 +2066,11 @@ gdbtk_call_command (cmdblk, arg, from_tty)
{
running_now = 1;
if (!No_Update)
Tcl_Eval (interp, "gdbtk_tcl_busy");
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_busy");
(*cmdblk->function.cfunc)(arg, from_tty);
running_now = 0;
if (!No_Update)
Tcl_Eval (interp, "gdbtk_tcl_idle");
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_idle");
}
}
else
@ -2082,14 +2088,14 @@ tk_command_loop ()
/* We no longer want to use stdin as the command input stream */
instream = NULL;
if (Tcl_Eval (interp, "gdbtk_tcl_preloop") != TCL_OK)
if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_preloop") != TCL_OK)
{
char *msg;
/* Force errorInfo to be set up propertly. */
Tcl_AddErrorInfo (interp, "");
Tcl_AddErrorInfo (gdbtk_interp, "");
msg = Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY);
msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY);
#ifdef _WIN32
MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
@ -2153,17 +2159,17 @@ gdbtk_init ( argv0 )
/* First init tcl and tk. */
Tcl_FindExecutable (argv0);
interp = Tcl_CreateInterp ();
gdbtk_interp = Tcl_CreateInterp ();
#ifdef TCL_MEM_DEBUG
Tcl_InitMemory (interp);
#endif
if (!interp)
if (!gdbtk_interp)
error ("Tcl_CreateInterp failed");
if (Tcl_Init(interp) != TCL_OK)
error ("Tcl_Init failed: %s", interp->result);
if (Tcl_Init(gdbtk_interp) != TCL_OK)
error ("Tcl_Init failed: %s", gdbtk_interp->result);
#ifndef IDE
/* For the IDE we register the cleanup later, after we've
@ -2172,14 +2178,14 @@ gdbtk_init ( argv0 )
#endif
/* Initialize the Paths variable. */
if (ide_initialize_paths (interp, "gdbtcl") != TCL_OK)
error ("ide_initialize_paths failed: %s", interp->result);
if (ide_initialize_paths (gdbtk_interp, "gdbtcl") != TCL_OK)
error ("ide_initialize_paths failed: %s", gdbtk_interp->result);
#ifdef IDE
/* start-sanitize-ide */
/* Find the directory where we expect to find idemanager. We ignore
errors since it doesn't really matter if this fails. */
libexecdir = Tcl_GetVar2 (interp, "Paths", "libexecdir", TCL_GLOBAL_ONLY);
libexecdir = Tcl_GetVar2 (gdbtk_interp, "Paths", "libexecdir", TCL_GLOBAL_ONLY);
IluTk_Init ();
@ -2187,152 +2193,153 @@ gdbtk_init ( argv0 )
make_final_cleanup (gdbtk_cleanup, h);
if (h == NULL)
{
Tcl_AppendResult (interp, "can't initialize event system: ", errmsg,
Tcl_AppendResult (gdbtk_interp, "can't initialize event system: ", errmsg,
(char *) NULL);
fprintf(stderr, "WARNING: ide_event_init_client failed: %s\n", interp->result);
fprintf(stderr, "WARNING: ide_event_init_client failed: %s\n", gdbtk_interp->result);
Tcl_SetVar (interp, "IDE_ENABLED", "0", 0);
Tcl_SetVar (gdbtk_interp, "IDE_ENABLED", "0", 0);
}
else
{
if (ide_create_tclevent_command (interp, h) != TCL_OK)
error ("ide_create_tclevent_command failed: %s", interp->result);
if (ide_create_tclevent_command (gdbtk_interp, h) != TCL_OK)
error ("ide_create_tclevent_command failed: %s", gdbtk_interp->result);
if (ide_create_edit_command (interp, h) != TCL_OK)
error ("ide_create_edit_command failed: %s", interp->result);
if (ide_create_edit_command (gdbtk_interp, h) != TCL_OK)
error ("ide_create_edit_command failed: %s", gdbtk_interp->result);
if (ide_create_property_command (interp, h) != TCL_OK)
error ("ide_create_property_command failed: %s", interp->result);
if (ide_create_property_command (gdbtk_interp, h) != TCL_OK)
error ("ide_create_property_command failed: %s", gdbtk_interp->result);
if (ide_create_build_command (interp, h) != TCL_OK)
error ("ide_create_build_command failed: %s", interp->result);
if (ide_create_build_command (gdbtk_interp, h) != TCL_OK)
error ("ide_create_build_command failed: %s", gdbtk_interp->result);
if (ide_create_window_register_command (interp, h, "gdb-restore")
if (ide_create_window_register_command (gdbtk_interp, h, "gdb-restore")
!= TCL_OK)
error ("ide_create_window_register_command failed: %s",
interp->result);
gdbtk_interp->result);
if (ide_create_window_command (interp, h) != TCL_OK)
error ("ide_create_window_command failed: %s", interp->result);
if (ide_create_window_command (gdbtk_interp, h) != TCL_OK)
error ("ide_create_window_command failed: %s", gdbtk_interp->result);
if (ide_create_exit_command (interp, h) != TCL_OK)
error ("ide_create_exit_command failed: %s", interp->result);
if (ide_create_exit_command (gdbtk_interp, h) != TCL_OK)
error ("ide_create_exit_command failed: %s", gdbtk_interp->result);
if (ide_create_help_command (interp) != TCL_OK)
error ("ide_create_help_command failed: %s", interp->result);
if (ide_create_help_command (gdbtk_interp) != TCL_OK)
error ("ide_create_help_command failed: %s", gdbtk_interp->result);
/*
if (ide_initialize (interp, "gdb") != TCL_OK)
error ("ide_initialize failed: %s", interp->result);
if (ide_initialize (gdbtk_interp, "gdb") != TCL_OK)
error ("ide_initialize failed: %s", gdbtk_interp->result);
*/
Tcl_SetVar (interp, "IDE_ENABLED", "1", 0);
Tcl_SetVar (gdbtk_interp, "IDE_ENABLED", "1", 0);
}
/* end-sanitize-ide */
#else
Tcl_SetVar (interp, "IDE_ENABLED", "0", 0);
Tcl_SetVar (gdbtk_interp, "IDE_ENABLED", "0", 0);
#endif /* IDE */
/* We don't want to open the X connection until we've done all the
IDE initialization. Otherwise, goofy looking unfinished windows
pop up when ILU drops into the TCL event loop. */
if (Tk_Init(interp) != TCL_OK)
error ("Tk_Init failed: %s", interp->result);
if (Tk_Init(gdbtk_interp) != TCL_OK)
error ("Tk_Init failed: %s", gdbtk_interp->result);
if (Itcl_Init(interp) == TCL_ERROR)
error ("Itcl_Init failed: %s", interp->result);
if (Itcl_Init(gdbtk_interp) == TCL_ERROR)
error ("Itcl_Init failed: %s", gdbtk_interp->result);
if (Tix_Init(interp) != TCL_OK)
error ("Tix_Init failed: %s", interp->result);
if (Tix_Init(gdbtk_interp) != TCL_OK)
error ("Tix_Init failed: %s", gdbtk_interp->result);
if (Tktable_Init(interp) != TCL_OK)
error ("Tktable_Init failed: %s", interp->result);
Tcl_StaticPackage(interp, "Tktable", Tktable_Init,
if (Tktable_Init(gdbtk_interp) != TCL_OK)
error ("Tktable_Init failed: %s", gdbtk_interp->result);
Tcl_StaticPackage(gdbtk_interp, "Tktable", Tktable_Init,
(Tcl_PackageInitProc *) NULL);
#ifdef __CYGWIN32__
if (ide_create_messagebox_command (interp) != TCL_OK)
if (ide_create_messagebox_command (gdbtk_interp) != TCL_OK)
error ("messagebox command initialization failed");
/* On Windows, create a sizebox widget command */
if (ide_create_sizebox_command (interp) != TCL_OK)
if (ide_create_sizebox_command (gdbtk_interp) != TCL_OK)
error ("sizebox creation failed");
if (ide_create_winprint_command (interp) != TCL_OK)
if (ide_create_winprint_command (gdbtk_interp) != TCL_OK)
error ("windows print code initialization failed");
/* start-sanitize-ide */
/* An interface to ShellExecute. */
if (ide_create_shell_execute_command (interp) != TCL_OK)
if (ide_create_shell_execute_command (gdbtk_interp) != TCL_OK)
error ("shell execute command initialization failed");
/* end-sanitize-ide */
if (ide_create_win_grab_command (interp) != TCL_OK)
if (ide_create_win_grab_command (gdbtk_interp) != TCL_OK)
error ("grab support command initialization failed");
/* Path conversion functions. */
if (ide_create_cygwin_path_command (interp) != TCL_OK)
if (ide_create_cygwin_path_command (gdbtk_interp) != TCL_OK)
error ("cygwin path command initialization failed");
#endif
Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
Tcl_CreateCommand (interp, "gdb_immediate", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
Tcl_CreateCommand (gdbtk_interp, "gdb_immediate", call_wrapper,
gdb_immediate_command, NULL);
Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
Tcl_CreateCommand (interp, "gdb_path_conv", call_wrapper, gdb_path_conv, NULL);
Tcl_CreateObjCommand (interp, "gdb_listfiles", call_obj_wrapper, gdb_listfiles, NULL);
Tcl_CreateCommand (interp, "gdb_listfuncs", call_wrapper, gdb_listfuncs,
Tcl_CreateCommand (gdbtk_interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
Tcl_CreateCommand (gdbtk_interp, "gdb_path_conv", call_wrapper, gdb_path_conv, NULL);
Tcl_CreateObjCommand (gdbtk_interp, "gdb_listfiles", call_obj_wrapper, gdb_listfiles, NULL);
Tcl_CreateCommand (gdbtk_interp, "gdb_listfuncs", call_wrapper, gdb_listfuncs,
NULL);
Tcl_CreateCommand (interp, "gdb_get_mem", call_wrapper, gdb_get_mem,
Tcl_CreateCommand (gdbtk_interp, "gdb_get_mem", call_wrapper, gdb_get_mem,
NULL);
Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
Tcl_CreateCommand (gdbtk_interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
Tcl_CreateCommand (gdbtk_interp, "gdb_fetch_registers", call_wrapper,
gdb_fetch_registers, NULL);
Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_changed_register_list", call_wrapper,
gdb_changed_register_list, NULL);
Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_disassemble", call_wrapper,
gdb_disassemble, NULL);
Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
Tcl_CreateCommand (interp, "gdb_get_breakpoint_list", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
Tcl_CreateCommand (gdbtk_interp, "gdb_get_breakpoint_list", call_wrapper,
gdb_get_breakpoint_list, NULL);
Tcl_CreateCommand (interp, "gdb_get_breakpoint_info", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_get_breakpoint_info", call_wrapper,
gdb_get_breakpoint_info, NULL);
Tcl_CreateCommand (interp, "gdb_clear_file", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_clear_file", call_wrapper,
gdb_clear_file, NULL);
Tcl_CreateCommand (interp, "gdb_confirm_quit", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_confirm_quit", call_wrapper,
gdb_confirm_quit, NULL);
Tcl_CreateCommand (interp, "gdb_force_quit", call_wrapper,
Tcl_CreateCommand (gdbtk_interp, "gdb_force_quit", call_wrapper,
gdb_force_quit, NULL);
Tcl_CreateCommand (interp, "gdb_target_has_execution",
Tcl_CreateCommand (gdbtk_interp, "gdb_target_has_execution",
gdb_target_has_execution_command,
NULL, NULL);
Tcl_CreateCommand (interp, "gdb_is_tracing",
Tcl_CreateCommand (gdbtk_interp, "gdb_is_tracing",
gdb_trace_status,
NULL, NULL);
Tcl_CreateObjCommand (interp, "gdb_load_info", call_obj_wrapper, gdb_load_info, NULL);
Tcl_CreateObjCommand (interp, "gdb_get_locals", call_obj_wrapper, gdb_get_locals_command,
Tcl_CreateObjCommand (gdbtk_interp, "gdb_load_info", call_obj_wrapper, gdb_load_info, NULL);
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_locals", call_obj_wrapper, gdb_get_locals_command,
NULL);
Tcl_CreateObjCommand (interp, "gdb_get_args", call_obj_wrapper, gdb_get_args_command,
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_args", call_obj_wrapper, gdb_get_args_command,
NULL);
Tcl_CreateObjCommand (interp, "gdb_get_function", call_obj_wrapper, gdb_get_function_command,
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_function", call_obj_wrapper, gdb_get_function_command,
NULL);
Tcl_CreateObjCommand (interp, "gdb_get_line", call_obj_wrapper, gdb_get_line_command,
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_line", call_obj_wrapper, gdb_get_line_command,
NULL);
Tcl_CreateObjCommand (interp, "gdb_get_file", call_obj_wrapper, gdb_get_file_command,
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_file", call_obj_wrapper, gdb_get_file_command,
NULL);
Tcl_CreateObjCommand (interp, "gdb_tracepoint_exists",
Tcl_CreateObjCommand (gdbtk_interp, "gdb_tracepoint_exists",
call_obj_wrapper, gdb_tracepoint_exists_command, NULL);
Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_info",
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_tracepoint_info",
call_obj_wrapper, gdb_get_tracepoint_info, NULL);
Tcl_CreateObjCommand (interp, "gdb_actions",
Tcl_CreateObjCommand (gdbtk_interp, "gdb_actions",
call_obj_wrapper, gdb_actions_command, NULL);
Tcl_CreateObjCommand (interp, "gdb_prompt",
Tcl_CreateObjCommand (gdbtk_interp, "gdb_prompt",
call_obj_wrapper, gdb_prompt_command, NULL);
Tcl_CreateObjCommand (interp, "gdb_find_file",
Tcl_CreateObjCommand (gdbtk_interp, "gdb_find_file",
call_obj_wrapper, gdb_find_file_command, NULL);
Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_list",
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_tracepoint_list",
call_obj_wrapper, gdb_get_tracepoint_list, NULL);
Tcl_CreateCommand (interp, "gdb_pc_reg", get_pc_register, NULL, NULL);
Tcl_CreateObjCommand (interp, "gdb_loadfile", call_obj_wrapper, gdb_loadfile, NULL);
Tcl_CreateObjCommand (interp, "gdb_set_bp", call_obj_wrapper, gdb_set_bp, NULL);
Tcl_CreateObjCommand (interp, "gdb_get_trace_frame_num",
Tcl_CreateCommand (gdbtk_interp, "gdb_pc_reg", get_pc_register, NULL, NULL);
Tcl_CreateObjCommand (gdbtk_interp, "gdb_loadfile", call_obj_wrapper, gdb_loadfile, NULL);
Tcl_CreateObjCommand (gdbtk_interp, "gdb_set_bp", call_obj_wrapper, gdb_set_bp, NULL);
Tcl_CreateObjCommand (gdbtk_interp, "gdb_search", call_obj_wrapper, gdb_search, NULL);
Tcl_CreateObjCommand (gdbtk_interp, "gdb_get_trace_frame_num",
call_obj_wrapper, gdb_get_trace_frame_num, NULL);
command_loop_hook = tk_command_loop;
@ -2363,7 +2370,7 @@ gdbtk_init ( argv0 )
add_com ("tk", class_obscure, tk_command,
"Send a command directly into tk.");
Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
Tcl_LinkVar (gdbtk_interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
TCL_LINK_INT);
/* find the gdb tcl library and source main.tcl */
@ -2386,10 +2393,10 @@ gdbtk_init ( argv0 )
do
{
Tcl_SetStringObj (auto_path_elem, lib, -1);
if (Tcl_ObjSetVar2 (interp, auto_path_name, NULL, auto_path_elem,
if (Tcl_ObjSetVar2 (gdbtk_interp, auto_path_name, NULL, auto_path_elem,
TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT ) == NULL)
{
fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
fputs_unfiltered (Tcl_GetVar (gdbtk_interp, "errorInfo", 0), gdb_stderr);
error ("");
}
if (!found_main)
@ -2398,7 +2405,7 @@ gdbtk_init ( argv0 )
if (access (gdbtk_file, R_OK) == 0)
{
found_main++;
Tcl_SetVar (interp, "GDBTK_LIBRARY", lib, 0);
Tcl_SetVar (gdbtk_interp, "GDBTK_LIBRARY", lib, 0);
}
}
}
@ -2426,15 +2433,15 @@ proc gdbtk_find_main {} {\n\
}\n\
gdbtk_find_main";
if (Tcl_GlobalEval (interp, (char *) script) != TCL_OK)
if (Tcl_GlobalEval (gdbtk_interp, (char *) script) != TCL_OK)
{
fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
fputs_unfiltered (Tcl_GetVar (gdbtk_interp, "errorInfo", 0), gdb_stderr);
error ("");
}
if (interp->result[0] != '\0')
if (gdbtk_interp->result[0] != '\0')
{
gdbtk_file = xstrdup (interp->result);
gdbtk_file = xstrdup (gdbtk_interp->result);
found_main++;
}
}
@ -2474,10 +2481,10 @@ gdbtk_find_main";
Tcl_DStringAppend (&source_cmd, "}}} else {source {", -1);
Tcl_DStringAppend (&source_cmd, gdbtk_file, -1);
Tcl_DStringAppend (&source_cmd, "}}", -1);
if (Tcl_GlobalEval (interp, Tcl_DStringValue (&source_cmd)) != TCL_OK)
if (Tcl_GlobalEval (gdbtk_interp, Tcl_DStringValue (&source_cmd)) != TCL_OK)
#else
/* end-sanitize-tclpro */
if (Tcl_EvalFile (interp, gdbtk_file) != TCL_OK)
if (Tcl_EvalFile (gdbtk_interp, gdbtk_file) != TCL_OK)
/* start-sanitize-tclpro */
#endif
/* end-sanitize-tclpro */
@ -2485,9 +2492,9 @@ gdbtk_find_main";
char *msg;
/* Force errorInfo to be set up propertly. */
Tcl_AddErrorInfo (interp, "");
Tcl_AddErrorInfo (gdbtk_interp, "");
msg = Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY);
msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY);
fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
@ -2510,12 +2517,20 @@ gdbtk_find_main";
/* start-sanitize-ide */
/* Don't do this until we have initialized. Otherwise, we may get a
run command before we are ready for one. */
if (ide_run_server_init (interp, h) != TCL_OK)
error ("ide_run_server_init failed: %s", interp->result);
if (ide_run_server_init (gdbtk_interp, h) != TCL_OK)
error ("ide_run_server_init failed: %s", gdbtk_interp->result);
/* end-sanitize-ide */
#endif
free (gdbtk_file);
if (gdbtk_source_filename != NULL)
{
char *s = "after idle source ";
char *script = concat (s, gdbtk_source_filename, (char *) NULL);
Tcl_Eval (gdbtk_interp, script);
free (gdbtk_source_filename);
free (script);
}
discard_cleanups (old_chain);
}
@ -2611,8 +2626,8 @@ gdbtk_load_hash (section, num)
{
char buf[128];
sprintf (buf, "download_hash %s %ld", section, num);
Tcl_Eval (interp, buf);
return atoi (interp->result);
Tcl_Eval (gdbtk_interp, buf);
return atoi (gdbtk_interp->result);
}
/* gdb_get_locals -
@ -2952,7 +2967,7 @@ TclDebug (va_alist)
va_end (args);
merge = Tcl_Merge (2, v);
Tcl_Eval (interp, merge);
Tcl_Eval (gdbtk_interp, merge);
Tcl_Free (merge);
}
@ -3028,11 +3043,11 @@ tracepoint_notify(tp, action)
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 (interp, buf);
v = Tcl_Eval (gdbtk_interp, buf);
if (v != TCL_OK)
{
gdbtk_fputs (interp->result, gdb_stdout);
gdbtk_fputs (gdbtk_interp->result, gdb_stdout);
gdbtk_fputs ("\n", gdb_stdout);
}
}
@ -3214,7 +3229,7 @@ gdbtk_pre_add_symbol (name)
v[0] = "gdbtk_tcl_pre_add_symbol";
v[1] = name;
merge = Tcl_Merge (2, v);
Tcl_Eval (interp, merge);
Tcl_Eval (gdbtk_interp, merge);
Tcl_Free (merge);
}
@ -3222,7 +3237,7 @@ gdbtk_pre_add_symbol (name)
void
gdbtk_post_add_symbol ()
{
Tcl_Eval (interp, "gdbtk_tcl_post_add_symbol");
Tcl_Eval (gdbtk_interp, "gdbtk_tcl_post_add_symbol");
}
@ -3555,6 +3570,138 @@ gdb_set_bp (clientData, interp, objc, objv)
return ret;
}
static int
gdb_search (clientData, interp, objc, objv)
ClientData clientData;
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
{
struct symbol_search *ss;
struct symbol_search *p;
struct cleanup *old_chain;
Tcl_Obj *list, *result, *CONST *switch_objv;
int index, switch_objc, i;
namespace_enum space;
char *regexp, *val;
int static_only, nfiles;
Tcl_Obj **file_list;
char **files;
static char *search_options[] = { "functions", "variables", "types", (char *) NULL };
static char *switches[] = { "-files", "-static" };
enum search_opts { SEARCH_FUNCTIONS, SEARCH_VARIABLES, SEARCH_TYPES };
enum switches_opts { SWITCH_FILES, SWITCH_STATIC_ONLY };
if (objc < 3)
{
Tcl_WrongNumArgs (interp, 1, objv, "option regexp ?arg ...?");
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj (interp, objv[1], search_options, "option", 0,
&index) != TCL_OK)
return TCL_ERROR;
/* Unfortunately, we cannot teach search_symbols to search on
multiple regexps, so we have to do a two-tier search for
any searches which choose to narrow the playing field. */
switch ((enum search_opts) index)
{
case SEARCH_FUNCTIONS:
space = FUNCTIONS_NAMESPACE; break;
case SEARCH_VARIABLES:
space = VARIABLES_NAMESPACE; break;
case SEARCH_TYPES:
space = TYPES_NAMESPACE; break;
}
regexp = Tcl_GetStringFromObj (objv[2], NULL);
/* Process any switches that refine the search */
switch_objc = objc - 3;
switch_objv = objv + 3;
static_only = 0;
nfiles = 0;
files = (char **) NULL;
while (switch_objc > 0)
{
if (Tcl_GetIndexFromObj (interp, switch_objv[0], switches,
"option", 0, &index) != TCL_OK)
return TCL_ERROR;
switch ((enum switches_opts) index)
{
case SWITCH_FILES:
if (switch_objc < 2)
{
Tcl_WrongNumArgs (interp, 2, objv, "[-files fileList -static 1|0]");
return TCL_ERROR;
}
Tcl_ListObjGetElements (interp, switch_objv[1], &nfiles, &file_list);
files = (char **) xmalloc (nfiles);
old_chain = make_cleanup (free, files);
for (i = 0; i < nfiles; i++)
files[i] = Tcl_GetStringFromObj (file_list[i], NULL);
switch_objc--;
switch_objv++;
break;
case SWITCH_STATIC_ONLY:
if (switch_objc < 2)
{
Tcl_WrongNumArgs (interp, 2, objv, "[-files fileList] [-static 1|0]");
return TCL_ERROR;
}
Tcl_GetIntFromObj (interp, switch_objv[1], &static_only);
switch_objc--;
switch_objv++;
}
switch_objc--;
switch_objv++;
}
search_symbols (regexp, space, nfiles, files, &ss);
if (files != NULL && ss != NULL)
do_cleanups (old_chain);
old_chain = make_cleanup (free_search_symbols, ss);
list = Tcl_NewListObj (0, NULL);
for (p = ss; p != NULL; p = p->next)
{
Tcl_Obj *elem;
if (static_only && p->block != STATIC_BLOCK)
continue;
elem = Tcl_NewListObj (0, NULL);
if (p->msymbol == NULL)
Tcl_ListObjAppendElement (interp, elem,
Tcl_NewStringObj (SYMBOL_SOURCE_NAME (p->symbol), -1));
else
Tcl_ListObjAppendElement (interp, elem,
Tcl_NewStringObj (SYMBOL_SOURCE_NAME (p->msymbol), -1));
Tcl_ListObjAppendElement (interp, list, elem);
}
Tcl_SetObjResult (interp, list);
do_cleanups (old_chain);
return TCL_OK;
}
int
gdbtk_test (filename)
char *filename;
{
if (access (filename, R_OK) != 0)
return 0;
else
gdbtk_source_filename = xstrdup (filename);
return 1;
}
/* Come here during initialize_all_files () */
void

View file

@ -61,6 +61,9 @@ extern void gdb_init PARAMS ((char *));
extern void cygwin32_conv_to_posix_path (const char *, char *);
#endif
extern void (*pre_add_symbol_hook) PARAMS ((char *));
extern void (*post_add_symbol_hook) PARAMS ((void));
int
main (argc, argv)
int argc;
@ -176,6 +179,9 @@ main (argc, argv)
{"command", required_argument, 0, 'x'},
{"version", no_argument, &print_version, 1},
{"x", required_argument, 0, 'x'},
/* start-sanitize-gdbtk */
{"tclcommand", required_argument, 0, 'z'},
/* end-sanitize-gdbtk */
{"directory", required_argument, 0, 'd'},
{"cd", required_argument, 0, 11},
{"tty", required_argument, 0, 't'},
@ -250,6 +256,19 @@ main (argc, argv)
cmdsize * sizeof (*cmdarg));
}
break;
/* start-sanitize-gdbtk */
case 'z':
{
extern int gdbtk_test PARAMS ((char *));
if (!gdbtk_test (optarg))
{
fprintf_unfiltered (gdb_stderr, "%s: unable to load tclcommand file \"%s\"",
argv[0], optarg);
exit (1);
}
break;
}
/* end-sanitize-gdbtk */
case 'd':
dirarg[ndir++] = optarg;
if (ndir >= dirsize)
@ -445,8 +464,12 @@ main (argc, argv)
it, better only print one error message. */
if (!SET_TOP_LEVEL ())
{
if (pre_add_symbol_hook)
pre_add_symbol_hook (symarg);
exec_file_command (execarg, !batch);
symbol_file_command (symarg, 0);
if (post_add_symbol_hook)
post_add_symbol_hook ();
}
}
else

View file

@ -45,7 +45,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Prototypes for local functions */
extern int
static int
find_methods PARAMS ((struct type *, char *, struct symbol **));
static void
@ -72,9 +72,6 @@ variables_info PARAMS ((char *, int));
static void
sources_info PARAMS ((char *, int));
static void
list_symbols PARAMS ((char *, int, int, int));
static void
output_source_filename PARAMS ((char *, int *));
@ -263,20 +260,22 @@ char *name;
return (NULL);
}
/* Demangle a GDB method stub type.
Note that this function is g++ specific. */
/* Mangle a GDB method stub type. This actually reassembles the pieces of the
full method name, which consist of the class name (from T), the unadorned
method name from METHOD_ID, and the signature for the specific overload,
specified by SIGNATURE_ID. Note that this function is g++ specific. */
char *
gdb_mangle_name (type, i, j)
gdb_mangle_name (type, method_id, signature_id)
struct type *type;
int i, j;
int method_id, signature_id;
{
int mangled_name_len;
char *mangled_name;
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
struct fn_field *method = &f[j];
char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
struct fn_field *method = &f[signature_id];
char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id);
char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
char *newname = type_name_no_tag (type);
/* Does the form of physname indicate that it is the full mangled name
@ -833,7 +832,12 @@ lookup_partial_symbol (pst, name, global, namespace)
center = bottom + (top - bottom) / 2;
if (!(center < top))
abort ();
if (!do_linear_search && SYMBOL_LANGUAGE (*center) == language_cplus)
if (!do_linear_search
&& (SYMBOL_LANGUAGE (*center) == language_cplus
/* start-sanitize-java */
|| SYMBOL_LANGUAGE (*center) == language_java
/* end-sanitize-java */
))
{
do_linear_search = 1;
}
@ -946,7 +950,12 @@ lookup_block_symbol (block, name, namespace)
}
inc = (inc >> 1) + bot;
sym = BLOCK_SYM (block, inc);
if (!do_linear_search && SYMBOL_LANGUAGE (sym) == language_cplus)
if (!do_linear_search
&& (SYMBOL_LANGUAGE (sym) == language_cplus
/* start-sanitize-java */
|| SYMBOL_LANGUAGE (sym) == language_java
/* end-sanitize-java */
))
{
do_linear_search = 1;
}
@ -1550,22 +1559,28 @@ find_line_symtab (symtab, line, linetable, index, exact_match)
return 1;
}
/* Find the PC value for a given source file and line number.
Returns zero for invalid line number.
/* Set the PC value for a given source file and line number and return true.
Returns zero for invalid line number (and sets the PC to 0).
The source file is specified with a struct symtab. */
CORE_ADDR
find_line_pc (symtab, line)
int
find_line_pc (symtab, line, pc)
struct symtab *symtab;
int line;
CORE_ADDR *pc;
{
struct linetable *l;
int ind;
*pc = 0;
if (symtab == 0)
return 0;
if (find_line_symtab (symtab, line, &l, &ind, NULL))
return l->item[ind].pc;
{
*pc = l->item[ind].pc;
return 1;
}
else
return 0;
}
@ -1585,11 +1600,7 @@ find_line_pc_range (sal, startptr, endptr)
struct symtab_and_line found_sal;
startaddr = sal.pc;
if (startaddr == 0)
{
startaddr = find_line_pc (sal.symtab, sal.line);
}
if (startaddr == 0)
if (startaddr==0 && !find_line_pc (sal.symtab, sal.line, &startaddr))
return 0;
/* This whole function is based on address. For example, if line 10 has
@ -1851,7 +1862,7 @@ total_number_of_methods (type)
a size of total_number_of_methods (T) * sizeof (struct symbol *).
Note that this function is g++ specific. */
int
static int
find_methods (t, name, sym_arr)
struct type *t;
char *name;
@ -1861,6 +1872,7 @@ find_methods (t, name, sym_arr)
int ibase;
struct symbol *sym_class;
char *class_name = type_name_no_tag (t);
/* Ignore this class if it doesn't have a name. This is ugly, but
unless we figure out how to get the physname without the name of
the class, then the loop can't do any good. */
@ -1872,36 +1884,55 @@ find_methods (t, name, sym_arr)
(struct symtab **)NULL)))
{
int method_counter;
/* FIXME: Shouldn't this just be CHECK_TYPEDEF (t)? */
t = SYMBOL_TYPE (sym_class);
/* Loop over each method name. At this level, all overloads of a name
are counted as a single name. There is an inner loop which loops over
each overload. */
for (method_counter = TYPE_NFN_FIELDS (t) - 1;
method_counter >= 0;
--method_counter)
{
int field_counter;
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, method_counter);
char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter);
char dem_opname[64];
if (strncmp (method_name, "__", 2) == 0 ||
strncmp (method_name, "op", 2) == 0 ||
strncmp (method_name, "type", 4) == 0)
{
if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI))
method_name = dem_opname;
else if (cplus_demangle_opname (method_name, dem_opname, 0))
method_name = dem_opname;
}
if (STREQ (name, method_name))
/* Find all the fields with that name. */
/* Find all the overloaded methods with that name. */
for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
field_counter >= 0;
--field_counter)
{
struct fn_field *f;
char *phys_name;
f = TYPE_FN_FIELDLIST1 (t, method_counter);
if (TYPE_FN_FIELD_STUB (f, field_counter))
check_stub_method (t, method_counter, field_counter);
{
char *tmp_name;
tmp_name = gdb_mangle_name (t,
method_counter,
field_counter);
phys_name = alloca (strlen (tmp_name) + 1);
strcpy (phys_name, tmp_name);
free (tmp_name);
}
else
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
/* Destructor is handled by caller, dont add it to the list */
if (DESTRUCTOR_PREFIX_P (phys_name))
continue;
@ -1914,11 +1945,14 @@ find_methods (t, name, sym_arr)
i1++;
else
{
/* This error message gets printed, but the method
still seems to be found
fputs_filtered("(Cannot find method ", gdb_stdout);
fprintf_symbol_filtered (gdb_stdout, phys_name,
language_cplus,
DMGL_PARAMS | DMGL_ANSI);
fputs_filtered(" - possibly inlined.)\n", gdb_stdout);
*/
}
}
}
@ -1935,11 +1969,10 @@ find_methods (t, name, sym_arr)
rather than hiding without any problem, and gcc 2.4.5 does overload
rather than hiding in this case). */
if (i1)
return i1;
if (i1 == 0)
for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
i1 += find_methods(TYPE_BASECLASS(t, ibase), name,
sym_arr + i1);
i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1);
return i1;
}
@ -2064,9 +2097,6 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
#endif
register char *p, *p1;
char *q, *pp;
#if 0
char *q1;
#endif
register struct symtab *s;
register struct symbol *sym;
@ -2076,11 +2106,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
register CORE_ADDR pc;
register struct minimal_symbol *msymbol;
char *copy;
struct symbol *sym_class;
int i1;
int is_quoted, has_parens;
struct symbol **sym_arr;
struct type *t;
char *saved_arg = *argptr;
extern char *gdb_completer_quote_characters;
@ -2100,10 +2126,15 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
{
(*argptr)++;
pc = parse_and_eval_address_1 (argptr);
values.sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
values.nelts = 1;
values.sals[0] = find_pc_line (pc, 0);
values.sals[0].pc = pc;
values.sals[0].section = find_pc_overlay (pc);
return values;
}
@ -2127,6 +2158,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
}
if (p[0] == ':' || p[0] == ' ' || p[0] == '\t')
break;
/* start-sanitize-java */
if (p[0] == '.' && strchr (p, ':') == NULL) /* Java qualified method. */
{
/* Find the *last* '.', since the others are package qualifiers. */
@ -2137,16 +2169,21 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
}
break;
}
/* end-sanitize-java */
}
while (p[0] == ' ' || p[0] == '\t') p++;
if ((p[0] == ':' || p[0] == '.') && !has_parens)
{
/* C++ or Java */
/* C++ */
/* start-sanitize-java */
/* ... or Java */
/* end-sanitize-java */
if (is_quoted) *argptr = *argptr+1;
if (p[0] == '.' || p[1] ==':')
{
struct symbol *sym_class;
/* Extract the class name. */
p1 = p;
while (p != *argptr && p[-1] == ' ') --p;
@ -2163,10 +2200,15 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
(struct symtab **)NULL);
if (sym_class &&
(t = check_typedef (SYMBOL_TYPE (sym_class)),
(TYPE_CODE (t) == TYPE_CODE_STRUCT
|| TYPE_CODE (t) == TYPE_CODE_UNION)))
(TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT
|| TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_UNION))
{
struct symbol **sym_arr;
struct type *t;
int i1;
t = check_typedef (SYMBOL_TYPE (sym_class));
/* Arg token is not digits => try it as a function name
Find the next token(everything up to end or next blank). */
if (**argptr
@ -2784,22 +2826,62 @@ sources_info (ignore, from_tty)
printf_filtered ("\n");
}
/* List all symbols (if REGEXP is NULL) or all symbols matching REGEXP.
If CLASS is zero, list all symbols except functions, type names, and
constants (enums).
If CLASS is 1, list only functions.
If CLASS is 2, list only type names.
If CLASS is 3, list only method names.
static int
file_matches (file, files, nfiles)
char *file;
char *files[];
int nfiles;
{
int i;
BPT is non-zero if we should set a breakpoint at the functions
we find. */
if (file != NULL && nfiles != 0)
{
for (i = 0; i < nfiles; i++)
{
if (strcmp (files[i], basename (file)) == 0)
return 1;
}
}
else if (nfiles == 0)
return 1;
return 0;
}
static void
list_symbols (regexp, class, bpt, from_tty)
/* Free any memory associated with a search. */
void
free_search_symbols (symbols)
struct symbol_search *symbols;
{
struct symbol_search *p;
struct symbol_search *next;
for (p = symbols; p != NULL; p = next)
{
next = p->next;
free (p);
}
}
/* Search the symbol table for matches to the regular expression REGEXP,
returning the results in *MATCHES.
Only symbols of KIND are searched:
FUNCTIONS_NAMESPACE - search all functions
TYPES_NAMESPACE - search all type names
METHODS_NAMESPACE - search all methods NOT IMPLEMENTED
VARIABLES_NAMESPACE - search all symbols, excluding functions, type names,
and constants (enums)
free_search_symbols should be called when *MATCHES is no longer needed.
*/
void
search_symbols (regexp, kind, nfiles, files, matches)
char *regexp;
int class;
int bpt;
int from_tty;
namespace_enum kind;
int nfiles;
char *files[];
struct symbol_search **matches;
{
register struct symtab *s;
register struct partial_symtab *ps;
@ -2812,9 +2894,6 @@ list_symbols (regexp, class, bpt, from_tty)
struct objfile *objfile;
struct minimal_symbol *msymbol;
char *val;
static char *classnames[]
= {"variable", "function", "type", "method"};
int found_in_file = 0;
int found_misc = 0;
static enum minimal_symbol_type types[]
= {mst_data, mst_text, mst_abs, mst_unknown};
@ -2824,10 +2903,25 @@ list_symbols (regexp, class, bpt, from_tty)
= {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
static enum minimal_symbol_type types4[]
= {mst_file_bss, mst_text, mst_abs, mst_unknown};
enum minimal_symbol_type ourtype = types[class];
enum minimal_symbol_type ourtype2 = types2[class];
enum minimal_symbol_type ourtype3 = types3[class];
enum minimal_symbol_type ourtype4 = types4[class];
enum minimal_symbol_type ourtype;
enum minimal_symbol_type ourtype2;
enum minimal_symbol_type ourtype3;
enum minimal_symbol_type ourtype4;
struct symbol_search *sr;
struct symbol_search *psr;
struct symbol_search *tail;
struct cleanup *old_chain = NULL;
if (kind < LABEL_NAMESPACE)
error ("must search on specific namespace");
ourtype = types[(int) (kind - LABEL_NAMESPACE)];
ourtype2 = types2[(int) (kind - LABEL_NAMESPACE)];
ourtype3 = types3[(int) (kind - LABEL_NAMESPACE)];
ourtype4 = types4[(int) (kind - LABEL_NAMESPACE)];
sr = *matches = NULL;
tail = NULL;
if (regexp != NULL)
{
@ -2902,12 +2996,13 @@ list_symbols (regexp, class, bpt, from_tty)
/* If it would match (logic taken from loop below)
load the file and go on to the next one */
if ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
&& ((class == 0 && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
if (file_matches (ps->filename, files, nfiles)
&& ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
&& ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
&& SYMBOL_CLASS (*psym) != LOC_BLOCK)
|| (class == 1 && SYMBOL_CLASS (*psym) == LOC_BLOCK)
|| (class == 2 && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
|| (class == 3 && SYMBOL_CLASS (*psym) == LOC_BLOCK)))
|| (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)
|| (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
|| (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
{
PSYMTAB_TO_SYMTAB(ps);
keep_going = 0;
@ -2930,7 +3025,7 @@ list_symbols (regexp, class, bpt, from_tty)
any matching symbols without debug info.
*/
if (class == 0 || class == 1)
if (nfiles == 0 && (kind == VARIABLES_NAMESPACE || kind == FUNCTIONS_NAMESPACE))
{
ALL_MSYMBOLS (objfile, msymbol)
{
@ -2943,7 +3038,7 @@ list_symbols (regexp, class, bpt, from_tty)
{
if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
{
if (class == 1
if (kind == FUNCTIONS_NAMESPACE
|| lookup_symbol (SYMBOL_NAME (msymbol),
(struct block *) NULL,
VAR_NAMESPACE,
@ -2955,18 +3050,8 @@ list_symbols (regexp, class, bpt, from_tty)
}
}
/* Printout here so as to get after the "Reading in symbols"
messages which will be generated above. */
if (!bpt)
printf_filtered (regexp
? "All %ss matching regular expression \"%s\":\n"
: "All defined %ss:\n",
classnames[class],
regexp);
ALL_SYMTABS (objfile, s)
{
found_in_file = 0;
bv = BLOCKVECTOR (s);
/* Often many files share a blockvector.
Scan each blockvector only once so that
@ -2984,56 +3069,115 @@ list_symbols (regexp, class, bpt, from_tty)
{
QUIT;
sym = BLOCK_SYM (b, j);
if ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
&& ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
if (file_matches (s->filename, files, nfiles)
&& ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
&& ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_BLOCK
&& SYMBOL_CLASS (sym) != LOC_CONST)
|| (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
|| (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|| (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK)))
|| (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)
|| (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|| (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK))))
{
if (bpt)
/* match */
psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
psr->block = i;
psr->symtab = s;
psr->symbol = sym;
psr->msymbol = NULL;
psr->next = NULL;
if (tail == NULL)
{
/* Set a breakpoint here, if it's a function */
if (class == 1)
{
/* There may be more than one function with the
same name but in different files. In order to
set breakpoints on all of them, we must give
both the file name and the function name to
break_command.
Quoting the symbol name gets rid of problems
with mangled symbol names that contain
CPLUS_MARKER characters. */
char *string =
(char *) alloca (strlen (s->filename)
+ strlen (SYMBOL_NAME(sym))
+ 4);
strcpy (string, s->filename);
strcat (string, ":'");
strcat (string, SYMBOL_NAME(sym));
strcat (string, "'");
break_command (string, from_tty);
sr = psr;
old_chain = make_cleanup (free_search_symbols, sr);
}
else
tail->next = psr;
tail = psr;
}
}
else if (!found_in_file)
}
prev_bv = bv;
}
/* If there are no eyes, avoid all contact. I mean, if there are
no debug symbols, then print directly from the msymbol_vector. */
if (found_misc || kind != FUNCTIONS_NAMESPACE)
{
ALL_MSYMBOLS (objfile, msymbol)
{
if (MSYMBOL_TYPE (msymbol) == ourtype ||
MSYMBOL_TYPE (msymbol) == ourtype2 ||
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
{
/* Functions: Look up by address. */
if (kind != FUNCTIONS_NAMESPACE ||
(0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
{
/* Variables/Absolutes: Look up by name */
if (lookup_symbol (SYMBOL_NAME (msymbol),
(struct block *) NULL, VAR_NAMESPACE,
0, (struct symtab **) NULL) == NULL)
{
/* match */
psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
psr->block = i;
psr->msymbol = msymbol;
psr->symtab = NULL;
psr->symbol = NULL;
psr->next = NULL;
if (tail == NULL)
{
sr = psr;
old_chain = make_cleanup (free_search_symbols, &sr);
}
else
tail->next = psr;
tail = psr;
}
}
}
}
}
}
*matches = sr;
if (sr != NULL)
discard_cleanups (old_chain);
}
/* Helper function for symtab_symbol_info, this function uses
the data returned from search_symbols() to print information
regarding the match to gdb_stdout.
*/
static int
print_symbol_info (kind, s, sym, block, last)
namespace_enum kind;
struct symtab *s;
struct symbol *sym;
int block;
char *last;
{
if (last == NULL || strcmp (last, s->filename) != 0)
{
fputs_filtered ("\nFile ", gdb_stdout);
fputs_filtered (s->filename, gdb_stdout);
fputs_filtered (":\n", gdb_stdout);
}
found_in_file = 1;
if (class != 2 && i == STATIC_BLOCK)
if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK)
printf_filtered ("static ");
/* Typedef that is not a C++ class */
if (class == 2
if (kind == TYPES_NAMESPACE
&& SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
c_typedef_print (SYMBOL_TYPE(sym), sym, gdb_stdout);
/* variable, func, or typedef-that-is-c++-class */
else if (class < 2 ||
(class == 2 &&
else if (kind < TYPES_NAMESPACE ||
(kind == TYPES_NAMESPACE &&
SYMBOL_NAMESPACE(sym) == STRUCT_NAMESPACE))
{
type_print (SYMBOL_TYPE (sym),
@ -3048,18 +3192,18 @@ list_symbols (regexp, class, bpt, from_tty)
# if 0
/* Tiemann says: "info methods was never implemented." */
char *demangled_name;
c_type_print_base (TYPE_FN_FIELD_TYPE(t, i),
c_type_print_base (TYPE_FN_FIELD_TYPE(t, block),
gdb_stdout, 0, 0);
c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i),
c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, block),
gdb_stdout, 0);
if (TYPE_FN_FIELD_STUB (t, i))
check_stub_method (TYPE_DOMAIN_TYPE (type), j, i);
if (TYPE_FN_FIELD_STUB (t, block))
check_stub_method (TYPE_DOMAIN_TYPE (type), j, block);
demangled_name =
cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, i),
cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, block),
DMGL_ANSI | DMGL_PARAMS);
if (demangled_name == NULL)
fprintf_filtered (stream, "<badly mangled name %s>",
TYPE_FN_FIELD_PHYSNAME (t, i));
TYPE_FN_FIELD_PHYSNAME (t, block));
else
{
fputs_filtered (demangled_name, stream);
@ -3068,56 +3212,72 @@ list_symbols (regexp, class, bpt, from_tty)
# endif
}
}
}
}
prev_bv = bv;
}
/* If there are no eyes, avoid all contact. I mean, if there are
no debug symbols, then print directly from the msymbol_vector. */
if (found_misc || class != 1)
/* This help function for symtab_symbol_info() prints information
for non-debugging symbols to gdb_stdout.
*/
static void
print_msymbol_info (msymbol)
struct minimal_symbol *msymbol;
{
found_in_file = 0;
ALL_MSYMBOLS (objfile, msymbol)
{
if (MSYMBOL_TYPE (msymbol) == ourtype ||
MSYMBOL_TYPE (msymbol) == ourtype2 ||
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
{
/* Functions: Look up by address. */
if (class != 1 ||
(0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
{
/* Variables/Absolutes: Look up by name */
if (lookup_symbol (SYMBOL_NAME (msymbol),
(struct block *) NULL, VAR_NAMESPACE,
0, (struct symtab **) NULL) == NULL)
{
if (bpt)
{
break_command (SYMBOL_NAME (msymbol), from_tty);
printf_filtered ("<function, no debug info> %s;\n",
SYMBOL_SOURCE_NAME (msymbol));
continue;
}
if (!found_in_file)
{
printf_filtered ("\nNon-debugging symbols:\n");
found_in_file = 1;
}
printf_filtered (" %08lx %s\n",
(unsigned long) SYMBOL_VALUE_ADDRESS (msymbol),
SYMBOL_SOURCE_NAME (msymbol));
}
/* This is the guts of the commands "info functions", "info types", and
"info variables". It calls search_symbols to find all matches and then
print_[m]symbol_info to print out some useful information about the
matches.
*/
static void
symtab_symbol_info (regexp, kind, from_tty)
char *regexp;
namespace_enum kind;
int from_tty;
{
static char *classnames[]
= {"variable", "function", "type", "method"};
struct symbol_search *symbols;
struct symbol_search *p;
struct cleanup *old_chain;
char *last_filename = NULL;
int first = 1;
/* must make sure that if we're interrupted, symbols gets freed */
search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
old_chain = make_cleanup (free_search_symbols, symbols);
printf_filtered (regexp
? "All %ss matching regular expression \"%s\":\n"
: "All defined %ss:\n",
classnames[(int) (kind - LABEL_NAMESPACE - 1)], regexp);
for (p = symbols; p != NULL; p = p->next)
{
QUIT;
if (p->msymbol != NULL)
{
if (first)
{
printf_filtered ("\nNon-debugging symbols:\n");
first = 0;
}
print_msymbol_info (p->msymbol);
}
else
{
print_symbol_info (kind,
p->symtab,
p->symbol,
p->block,
last_filename);
last_filename = p->symtab->filename;
}
}
}
}
}
do_cleanups (old_chain);
}
static void
@ -3125,7 +3285,7 @@ variables_info (regexp, from_tty)
char *regexp;
int from_tty;
{
list_symbols (regexp, 0, 0, from_tty);
symtab_symbol_info (regexp, VARIABLES_NAMESPACE, from_tty);
}
static void
@ -3133,7 +3293,7 @@ functions_info (regexp, from_tty)
char *regexp;
int from_tty;
{
list_symbols (regexp, 1, 0, from_tty);
symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
}
static void
@ -3141,7 +3301,7 @@ types_info (regexp, from_tty)
char *regexp;
int from_tty;
{
list_symbols (regexp, 2, 0, from_tty);
symtab_symbol_info (regexp, TYPES_NAMESPACE, from_tty);
}
#if 0
@ -3150,7 +3310,7 @@ static void
methods_info (regexp)
char *regexp;
{
list_symbols (regexp, 3, 0, from_tty);
symtab_symbol_info (regexp, METHODS_NAMESPACE, 0, from_tty);
}
#endif /* 0 */
@ -3160,10 +3320,43 @@ rbreak_command (regexp, from_tty)
char *regexp;
int from_tty;
{
list_symbols (regexp, 1, 1, from_tty);
}
struct symbol_search *ss;
struct symbol_search *p;
struct cleanup *old_chain;
search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss);
old_chain = make_cleanup (free_search_symbols, ss);
for (p = ss; p != NULL; p = p->next)
{
if (p->msymbol == NULL)
{
char *string = (char *) alloca (strlen (p->symtab->filename)
+ strlen (SYMBOL_NAME (p->symbol))
+ 4);
strcpy (string, p->symtab->filename);
strcat (string, ":'");
strcat (string, SYMBOL_NAME (p->symbol));
strcat (string, "'");
break_command (string, from_tty);
print_symbol_info (FUNCTIONS_NAMESPACE,
p->symtab,
p->symbol,
p->block,
p->symtab->filename);
}
else
{
break_command (SYMBOL_NAME (p->msymbol), from_tty);
printf_filtered ("<function, no debug info> %s;\n",
SYMBOL_SOURCE_NAME (p->msymbol));
}
}
do_cleanups (old_chain);
}
/* Return Nonzero if block a is lexically nested within block b,
or if a and b have the same pc range.
Return zero otherwise. */