diff options
author | Keith Seitz <keiths@cygnus> | 1998-06-27 00:45:20 +0000 |
---|---|---|
committer | Keith Seitz <keiths@cygnus> | 1998-06-27 00:45:20 +0000 |
commit | 7f6cb62ee6bb03d33729ca8a27e3946591efc1f1 (patch) | |
tree | 7cfd46a6df61a591ee4b5dbfe21f5084b3b78b29 /gdb | |
parent | 6cddf7d9676cb0264628654e5a242ef7acf700ab (diff) | |
download | gdb-7f6cb62ee6bb03d33729ca8a27e3946591efc1f1.zip gdb-7f6cb62ee6bb03d33729ca8a27e3946591efc1f1.tar.gz gdb-7f6cb62ee6bb03d33729ca8a27e3946591efc1f1.tar.bz2 |
* 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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 21 | ||||
-rw-r--r-- | gdb/ChangeLog-gdbtk | 15 | ||||
-rw-r--r-- | gdb/gdbtk.c | 411 | ||||
-rw-r--r-- | gdb/main.c | 23 | ||||
-rw-r--r-- | gdb/symtab.c | 817 |
5 files changed, 843 insertions, 444 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 547a2b0..6f09a09 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 diff --git a/gdb/ChangeLog-gdbtk b/gdb/ChangeLog-gdbtk index 2c11440..7264fac 100644 --- a/gdb/ChangeLog-gdbtk +++ b/gdb/ChangeLog-gdbtk @@ -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. diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c index cf4dc49..1b2bf87 100644 --- a/gdb/gdbtk.c +++ b/gdb/gdbtk.c @@ -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 @@ -1933,10 +1939,10 @@ x_event (signo) int val; if (varname == NULL) { - Tcl_Obj *varnamestrobj = Tcl_NewStringObj("download_cancel_ok",-1); - varname = Tcl_ObjGetVar2(interp,varnamestrobj,NULL,TCL_GLOBAL_ONLY); + Tcl_Obj *varnamestrobj = Tcl_NewStringObj ("download_cancel_ok",-1); + 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 @@ -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 diff --git a/gdb/symtab.c b/gdb/symtab.c index 422a67e..9b0a996 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -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 @@ -73,9 +73,6 @@ static void sources_info PARAMS ((char *, int)); static void -list_symbols PARAMS ((char *, int, int, int)); - -static void output_source_filename PARAMS ((char *, int *)); char * @@ -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 (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); - phys_name = TYPE_FN_FIELD_PHYSNAME (f, 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 { - 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); + /* 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; - for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) - i1 += find_methods(TYPE_BASECLASS(t, ibase), name, - sym_arr + i1); + if (i1 == 0) + for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) + 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; + + 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; +} + +/* Free any memory associated with a search. */ +void +free_search_symbols (symbols) + struct symbol_search *symbols; +{ + struct symbol_search *p; + struct symbol_search *next; - BPT is non-zero if we should set a breakpoint at the functions - we find. */ + for (p = symbols; p != NULL; p = next) + { + next = p->next; + free (p); + } +} -static void -list_symbols (regexp, class, bpt, from_tty) +/* 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,45 +2903,60 @@ 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) { /* Make sure spacing is right for C++ operators. - This is just a courtesy to make the matching less sensitive - to how many spaces the user leaves between 'operator' - and <TYPENAME> or <OPERATOR>. */ + This is just a courtesy to make the matching less sensitive + to how many spaces the user leaves between 'operator' + and <TYPENAME> or <OPERATOR>. */ char *opend; char *opname = operator_chars (regexp, &opend); if (*opname) - { + { int fix = -1; /* -1 means ok; otherwise number of spaces needed. */ - if (isalpha(*opname) || *opname == '_' || *opname == '$') - { - /* There should 1 space between 'operator' and 'TYPENAME'. */ - if (opname[-1] != ' ' || opname[-2] == ' ') - fix = 1; - } - else - { - /* There should 0 spaces between 'operator' and 'OPERATOR'. */ - if (opname[-1] == ' ') - fix = 0; - } - /* If wrong number of spaces, fix it. */ - if (fix >= 0) - { - char *tmp = (char*) alloca(opend-opname+10); - sprintf(tmp, "operator%.*s%s", fix, " ", opname); - regexp = tmp; - } + if (isalpha(*opname) || *opname == '_' || *opname == '$') + { + /* There should 1 space between 'operator' and 'TYPENAME'. */ + if (opname[-1] != ' ' || opname[-2] == ' ') + fix = 1; + } + else + { + /* There should 0 spaces between 'operator' and 'OPERATOR'. */ + if (opname[-1] == ' ') + fix = 0; + } + /* If wrong number of spaces, fix it. */ + if (fix >= 0) + { + char *tmp = (char*) alloca(opend-opname+10); + sprintf(tmp, "operator%.*s%s", fix, " ", opname); + regexp = tmp; + } } if (0 != (val = re_comp (regexp))) - error ("Invalid regexp (%s): %s", val, regexp); + error ("Invalid regexp (%s): %s", val, regexp); } /* Search through the partial symtabs *first* for all symbols @@ -2873,48 +2967,49 @@ list_symbols (regexp, class, bpt, from_tty) { struct partial_symbol **bound, **gbound, **sbound; int keep_going = 1; - + if (ps->readin) continue; - + gbound = objfile->global_psymbols.list + ps->globals_offset + ps->n_global_syms; sbound = objfile->static_psymbols.list + ps->statics_offset + ps->n_static_syms; bound = gbound; /* Go through all of the symbols stored in a partial - symtab in one loop. */ + symtab in one loop. */ psym = objfile->global_psymbols.list + ps->globals_offset; while (keep_going) - { - if (psym >= bound) - { - if (bound == gbound && ps->n_static_syms != 0) - { - psym = objfile->static_psymbols.list + ps->statics_offset; - bound = sbound; - } - else - keep_going = 0; - continue; - } - else - { - QUIT; - - /* 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 - && 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))) - { - PSYMTAB_TO_SYMTAB(ps); - keep_going = 0; - } - } - psym++; - } + { + if (psym >= bound) + { + if (bound == gbound && ps->n_static_syms != 0) + { + psym = objfile->static_psymbols.list + ps->statics_offset; + bound = sbound; + } + else + keep_going = 0; + continue; + } + else + { + QUIT; + + /* If it would match (logic taken from loop below) + load the file and go on to the next one */ + 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) + || (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; + } + } + psym++; + } } /* Here, we search through the minimal symbol tables for functions @@ -2930,194 +3025,259 @@ 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) - { - if (MSYMBOL_TYPE (msymbol) == ourtype || - MSYMBOL_TYPE (msymbol) == ourtype2 || - MSYMBOL_TYPE (msymbol) == ourtype3 || - MSYMBOL_TYPE (msymbol) == ourtype4) - { - if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol)) - { - if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))) - { - if (class == 1 - || lookup_symbol (SYMBOL_NAME (msymbol), - (struct block *) NULL, - VAR_NAMESPACE, - 0, (struct symtab **) NULL) == NULL) - found_misc = 1; - } - } - } - } + { + if (MSYMBOL_TYPE (msymbol) == ourtype || + MSYMBOL_TYPE (msymbol) == ourtype2 || + MSYMBOL_TYPE (msymbol) == ourtype3 || + MSYMBOL_TYPE (msymbol) == ourtype4) + { + if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol)) + { + if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))) + { + if (kind == FUNCTIONS_NAMESPACE + || lookup_symbol (SYMBOL_NAME (msymbol), + (struct block *) NULL, + VAR_NAMESPACE, + 0, (struct symtab **) NULL) == NULL) + found_misc = 1; + } + } + } + } } - /* 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 - we don't get every symbol many times. - It happens that the first symtab in the list - for any given blockvector is the main file. */ + Scan each blockvector only once so that + we don't get every symbol many times. + It happens that the first symtab in the list + for any given blockvector is the main file. */ if (bv != prev_bv) - for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++) - { - b = BLOCKVECTOR_BLOCK (bv, i); - /* Skip the sort if this block is always sorted. */ - if (!BLOCK_SHOULD_SORT (b)) - sort_block_syms (b); - for (j = 0; j < BLOCK_NSYMS (b); j++) - { - QUIT; - sym = BLOCK_SYM (b, j); - if ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym)) - && ((class == 0 && 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))) - { - if (bpt) - { - /* 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); - } - } - else if (!found_in_file) - { - 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) - printf_filtered ("static "); - - /* Typedef that is not a C++ class */ - if (class == 2 - && 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 && - SYMBOL_NAMESPACE(sym) == STRUCT_NAMESPACE)) - { - type_print (SYMBOL_TYPE (sym), - (SYMBOL_CLASS (sym) == LOC_TYPEDEF - ? "" : SYMBOL_SOURCE_NAME (sym)), - gdb_stdout, 0); - - printf_filtered (";\n"); - } - else - { -# if 0 -/* Tiemann says: "info methods was never implemented." */ - char *demangled_name; - c_type_print_base (TYPE_FN_FIELD_TYPE(t, i), - gdb_stdout, 0, 0); - c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i), - gdb_stdout, 0); - if (TYPE_FN_FIELD_STUB (t, i)) - check_stub_method (TYPE_DOMAIN_TYPE (type), j, i); - demangled_name = - cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, i), - DMGL_ANSI | DMGL_PARAMS); - if (demangled_name == NULL) - fprintf_filtered (stream, "<badly mangled name %s>", - TYPE_FN_FIELD_PHYSNAME (t, i)); - else - { - fputs_filtered (demangled_name, stream); - free (demangled_name); - } -# endif - } - } - } - } + for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++) + { + b = BLOCKVECTOR_BLOCK (bv, i); + /* Skip the sort if this block is always sorted. */ + if (!BLOCK_SHOULD_SORT (b)) + sort_block_syms (b); + for (j = 0; j < BLOCK_NSYMS (b); j++) + { + QUIT; + sym = BLOCK_SYM (b, j); + 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) + || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK) + || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)))) + { + /* 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) + { + sr = psr; + old_chain = make_cleanup (free_search_symbols, sr); + } + else + tail->next = psr; + tail = psr; + } + } + } 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) + if (found_misc || kind != FUNCTIONS_NAMESPACE) { - 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) + { + 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) { - break_command (SYMBOL_NAME (msymbol), from_tty); - printf_filtered ("<function, no debug info> %s;\n", - SYMBOL_SOURCE_NAME (msymbol)); - continue; + sr = psr; + old_chain = make_cleanup (free_search_symbols, &sr); } - 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)); - } - } - } - } - } + 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); + } + + if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK) + printf_filtered ("static "); + + /* Typedef that is not a C++ class */ + 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 (kind < TYPES_NAMESPACE || + (kind == TYPES_NAMESPACE && + SYMBOL_NAMESPACE(sym) == STRUCT_NAMESPACE)) + { + type_print (SYMBOL_TYPE (sym), + (SYMBOL_CLASS (sym) == LOC_TYPEDEF + ? "" : SYMBOL_SOURCE_NAME (sym)), + gdb_stdout, 0); + + printf_filtered (";\n"); + } + else + { +# if 0 + /* Tiemann says: "info methods was never implemented." */ + char *demangled_name; + c_type_print_base (TYPE_FN_FIELD_TYPE(t, block), + gdb_stdout, 0, 0); + c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, block), + gdb_stdout, 0); + 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, block), + DMGL_ANSI | DMGL_PARAMS); + if (demangled_name == NULL) + fprintf_filtered (stream, "<badly mangled name %s>", + TYPE_FN_FIELD_PHYSNAME (t, block)); + else + { + fputs_filtered (demangled_name, stream); + free (demangled_name); + } +# endif + } +} + +/* 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; +{ + 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. */ |