* source.c: Make global variables current_source_symtab and
current_source_line static. (list_command): Moved to cli/cli-cmds.c. (ambiguous_line_spec): Moved to cli/cli-cmds.c. (get_first_line_listed): New accessor function. (get_lines_to_list): New accessor function. (get_current_source_symtab_and_line): New function. Retrieves the position in the source code that we consider current. (get_current_or_default_source_symtab_and_line): New function. Like the above but attempts to determine a default position if one is not currently defined. (set_current_source_symtab_and_line): New function. Sets the source code position considered current and returns the previously set one. (clear_current_source_symtab_and_line): Reset stored information about a current source line. (_initialize_source): Remove registration for the "list" command and its alias. * source.h: Add declarations for the new functions above. * symtab.h: Remove declarations for the global variables mentioned above. * breakpoint.c (parse_breakpoint_sals): Use accessor functions to obtain current source line. * linespec.c (decode_line_1): Ditto. * macroscope.c (default_macro_scope): Ditto. * scm-lang.c (scm_unpac): Ditto. * stack.c (print_frame_info_base): Ditto. * symfile.c (clear_symtab_users): Ditto. * symtab.c (decode_line_spec): Ditto. * cli/cli-cmds.c (list_command): Moved here from source.c. (ambiguous_line_spec): Moved here from source.c. (_init_cli_cmds): Add definition for "list" and its alias. * Makefile.in: Update dependencies.
This commit is contained in:
parent
7cf108933b
commit
0378c33231
13 changed files with 561 additions and 243 deletions
|
@ -1,3 +1,38 @@
|
||||||
|
2002-09-13 Fernando Nasser <fnasser@redhat.com>
|
||||||
|
|
||||||
|
* source.c: Make global variables current_source_symtab and
|
||||||
|
current_source_line static.
|
||||||
|
(list_command): Moved to cli/cli-cmds.c.
|
||||||
|
(ambiguous_line_spec): Moved to cli/cli-cmds.c.
|
||||||
|
(get_first_line_listed): New accessor function.
|
||||||
|
(get_lines_to_list): New accessor function.
|
||||||
|
(get_current_source_symtab_and_line): New function. Retrieves the
|
||||||
|
position in the source code that we consider current.
|
||||||
|
(get_current_or_default_source_symtab_and_line): New function.
|
||||||
|
Like the above but attempts to determine a default position if one
|
||||||
|
is not currently defined.
|
||||||
|
(set_current_source_symtab_and_line): New function. Sets the source
|
||||||
|
code position considered current and returns the previously set one.
|
||||||
|
(clear_current_source_symtab_and_line): Reset stored information about
|
||||||
|
a current source line.
|
||||||
|
(_initialize_source): Remove registration for the "list" command and
|
||||||
|
its alias.
|
||||||
|
* source.h: Add declarations for the new functions above.
|
||||||
|
* symtab.h: Remove declarations for the global variables mentioned
|
||||||
|
above.
|
||||||
|
* breakpoint.c (parse_breakpoint_sals): Use accessor functions to
|
||||||
|
obtain current source line.
|
||||||
|
* linespec.c (decode_line_1): Ditto.
|
||||||
|
* macroscope.c (default_macro_scope): Ditto.
|
||||||
|
* scm-lang.c (scm_unpac): Ditto.
|
||||||
|
* stack.c (print_frame_info_base): Ditto.
|
||||||
|
* symfile.c (clear_symtab_users): Ditto.
|
||||||
|
* symtab.c (decode_line_spec): Ditto.
|
||||||
|
* cli/cli-cmds.c (list_command): Moved here from source.c.
|
||||||
|
(ambiguous_line_spec): Moved here from source.c.
|
||||||
|
(_init_cli_cmds): Add definition for "list" and its alias.
|
||||||
|
* Makefile.in: Update dependencies.
|
||||||
|
|
||||||
2002-09-20 Corinna Vinschen <vinschen@redhat.com>
|
2002-09-20 Corinna Vinschen <vinschen@redhat.com>
|
||||||
|
|
||||||
* h8300-tdep.c (h8300_examine_prologue): Match saved regs location
|
* h8300-tdep.c (h8300_examine_prologue): Match saved regs location
|
||||||
|
|
|
@ -1550,7 +1550,7 @@ breakpoint.o: breakpoint.c $(defs_h) $(symtab_h) $(frame_h) $(breakpoint_h) \
|
||||||
$(command_h) $(inferior_h) $(gdbthread_h) $(target_h) $(language_h) \
|
$(command_h) $(inferior_h) $(gdbthread_h) $(target_h) $(language_h) \
|
||||||
$(gdb_string_h) $(demangle_h) $(annotate_h) $(symfile_h) \
|
$(gdb_string_h) $(demangle_h) $(annotate_h) $(symfile_h) \
|
||||||
$(objfiles_h) $(linespec_h) $(completer_h) $(gdb_h) $(ui_out_h) \
|
$(objfiles_h) $(linespec_h) $(completer_h) $(gdb_h) $(ui_out_h) \
|
||||||
$(cli_script_h) $(gdb_events_h)
|
$(cli_script_h) $(gdb_events_h) $(source_h)
|
||||||
buildsym.o: buildsym.c $(defs_h) $(bfd_h) $(gdb_obstack_h) $(symtab_h) \
|
buildsym.o: buildsym.c $(defs_h) $(bfd_h) $(gdb_obstack_h) $(symtab_h) \
|
||||||
$(symfile_h) $(objfiles_h) $(gdbtypes_h) $(complaints_h) \
|
$(symfile_h) $(objfiles_h) $(gdbtypes_h) $(complaints_h) \
|
||||||
$(gdb_string_h) $(expression_h) $(language_h) $(bcache_h) \
|
$(gdb_string_h) $(expression_h) $(language_h) $(bcache_h) \
|
||||||
|
@ -1832,7 +1832,7 @@ lin-lwp.o: lin-lwp.c $(defs_h) $(gdb_assert_h) $(gdb_string_h) $(gdb_wait_h) \
|
||||||
$(gdbthread_h) $(inferior_h) $(target_h) $(regcache_h) $(gdbcmd_h)
|
$(gdbthread_h) $(inferior_h) $(target_h) $(regcache_h) $(gdbcmd_h)
|
||||||
linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
|
linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
|
||||||
$(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(completer_h) \
|
$(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(completer_h) \
|
||||||
$(cp_abi_h)
|
$(cp_abi_h) $(source_h)
|
||||||
linux-proc.o: linux-proc.c $(defs_h) $(inferior_h) $(regcache_h) \
|
linux-proc.o: linux-proc.c $(defs_h) $(inferior_h) $(regcache_h) \
|
||||||
$(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_h) \
|
$(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_h) \
|
||||||
$(cli_decode_h) $(gdb_string_h)
|
$(cli_decode_h) $(gdb_string_h)
|
||||||
|
@ -1877,7 +1877,7 @@ macrocmd.o: macrocmd.c $(defs_h) $(macrotab_h) $(macroexp_h) $(macroscope_h) \
|
||||||
macroexp.o: macroexp.c $(defs_h) $(gdb_obstack_h) $(bcache_h) $(macrotab_h) \
|
macroexp.o: macroexp.c $(defs_h) $(gdb_obstack_h) $(bcache_h) $(macrotab_h) \
|
||||||
$(macroexp_h) $(gdb_assert_h)
|
$(macroexp_h) $(gdb_assert_h)
|
||||||
macroscope.o: macroscope.c $(defs_h) $(macroscope_h) $(symtab_h) $(target_h) \
|
macroscope.o: macroscope.c $(defs_h) $(macroscope_h) $(symtab_h) $(target_h) \
|
||||||
$(frame_h) $(inferior_h)
|
$(frame_h) $(inferior_h) $(source_h)
|
||||||
macrotab.o: macrotab.c $(defs_h) $(gdb_obstack_h) $(splay_tree_h) \
|
macrotab.o: macrotab.c $(defs_h) $(gdb_obstack_h) $(splay_tree_h) \
|
||||||
$(symtab_h) $(symfile_h) $(objfiles_h) $(macrotab_h) $(gdb_assert_h) \
|
$(symtab_h) $(symfile_h) $(objfiles_h) $(macrotab_h) $(gdb_assert_h) \
|
||||||
$(bcache_h) $(complaints_h)
|
$(bcache_h) $(complaints_h)
|
||||||
|
@ -2102,7 +2102,7 @@ scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
|
||||||
$(scm_tags_h)
|
$(scm_tags_h)
|
||||||
scm-lang.o: scm-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
|
scm-lang.o: scm-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
|
||||||
$(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
|
$(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
|
||||||
$(scm_tags_h) $(gdb_string_h) $(gdbcore_h)
|
$(scm_tags_h) $(gdb_string_h) $(gdbcore_h) $(source_h)
|
||||||
scm-valprint.o: scm-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
|
scm-valprint.o: scm-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
|
||||||
$(expression_h) $(parser_defs_h) $(language_h) $(value_h) \
|
$(expression_h) $(parser_defs_h) $(language_h) $(value_h) \
|
||||||
$(scm_lang_h) $(valprint_h) $(gdbcore_h)
|
$(scm_lang_h) $(valprint_h) $(gdbcore_h)
|
||||||
|
@ -2187,7 +2187,7 @@ stabsread.o: stabsread.c $(defs_h) $(gdb_string_h) $(bfd_h) $(gdb_obstack_h) \
|
||||||
stack.o: stack.c $(defs_h) $(gdb_string_h) $(value_h) $(symtab_h) \
|
stack.o: stack.c $(defs_h) $(gdb_string_h) $(value_h) $(symtab_h) \
|
||||||
$(gdbtypes_h) $(expression_h) $(language_h) $(frame_h) $(gdbcmd_h) \
|
$(gdbtypes_h) $(expression_h) $(language_h) $(frame_h) $(gdbcmd_h) \
|
||||||
$(gdbcore_h) $(target_h) $(breakpoint_h) $(demangle_h) $(inferior_h) \
|
$(gdbcore_h) $(target_h) $(breakpoint_h) $(demangle_h) $(inferior_h) \
|
||||||
$(annotate_h) $(ui_out_h)
|
$(annotate_h) $(ui_out_h) $(source_h)
|
||||||
standalone.o: standalone.c $(gdb_stat_h) $(defs_h) $(symtab_h) $(frame_h) \
|
standalone.o: standalone.c $(gdb_stat_h) $(defs_h) $(symtab_h) $(frame_h) \
|
||||||
$(inferior_h) $(gdb_wait_h)
|
$(inferior_h) $(gdb_wait_h)
|
||||||
std-regs.o: std-regs.c $(defs_h) $(builtin_regs_h) $(frame_h) $(gdbtypes_h) \
|
std-regs.o: std-regs.c $(defs_h) $(builtin_regs_h) $(frame_h) $(gdbtypes_h) \
|
||||||
|
@ -2198,7 +2198,7 @@ symfile.o: symfile.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
|
||||||
$(frame_h) $(target_h) $(value_h) $(symfile_h) $(objfiles_h) \
|
$(frame_h) $(target_h) $(value_h) $(symfile_h) $(objfiles_h) \
|
||||||
$(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_h) \
|
$(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_h) \
|
||||||
$(demangle_h) $(inferior_h) $(gdb_stabs_h) $(gdb_obstack_h) \
|
$(demangle_h) $(inferior_h) $(gdb_stabs_h) $(gdb_obstack_h) \
|
||||||
$(completer_h) $(bcache_h) $(gdb_string_h) $(gdb_stat_h)
|
$(completer_h) $(bcache_h) $(gdb_string_h) $(gdb_stat_h) $(source_h)
|
||||||
symm-nat.o: symm-nat.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
|
symm-nat.o: symm-nat.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
|
||||||
$(target_h) $(regcache_h) $(gdb_stat_h) $(gdbcore_h) $(gdbcore_h)
|
$(target_h) $(regcache_h) $(gdb_stat_h) $(gdbcore_h) $(gdbcore_h)
|
||||||
symm-tdep.o: symm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
|
symm-tdep.o: symm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
|
||||||
|
@ -2211,7 +2211,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
|
||||||
$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
|
$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
|
||||||
$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
|
$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
|
||||||
$(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
|
$(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
|
||||||
$(cp_abi_h)
|
$(cp_abi_h) $(source_h)
|
||||||
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
|
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
|
||||||
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
|
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
|
||||||
$(gdb_wait_h) $(dcache_h) $(regcache_h)
|
$(gdb_wait_h) $(dcache_h) $(regcache_h)
|
||||||
|
@ -2312,7 +2312,8 @@ z8k-tdep.o: z8k-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(gdbcmd_h) \
|
||||||
cli-cmds.o: $(srcdir)/cli/cli-cmds.c $(defs_h) $(completer_h) $(target_h) \
|
cli-cmds.o: $(srcdir)/cli/cli-cmds.c $(defs_h) $(completer_h) $(target_h) \
|
||||||
$(gdb_wait_h) $(gdb_regex_h) $(gdb_string_h) $(filenames_h) \
|
$(gdb_wait_h) $(gdb_regex_h) $(gdb_string_h) $(filenames_h) \
|
||||||
$(ui_out_h) $(top_h) $(cli_decode_h) $(cli_script_h) \
|
$(ui_out_h) $(top_h) $(cli_decode_h) $(cli_script_h) \
|
||||||
$(cli_setshow_h) $(cli_cmds_h)
|
$(cli_setshow_h) $(cli_cmds_h) $(source_h) $(linespec_h) \
|
||||||
|
$(expression_h) $(language_h) $(objfiles_h)
|
||||||
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-cmds.c
|
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-cmds.c
|
||||||
cli-decode.o: $(srcdir)/cli/cli-decode.c $(defs_h) $(symtab_h) \
|
cli-decode.o: $(srcdir)/cli/cli-decode.c $(defs_h) $(symtab_h) \
|
||||||
$(gdb_regex_h) $(gdb_string_h) $(ui_out_h) $(cli_cmds_h) \
|
$(gdb_regex_h) $(gdb_string_h) $(ui_out_h) $(cli_cmds_h) \
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "annotate.h"
|
#include "annotate.h"
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
|
#include "source.h"
|
||||||
#include "linespec.h"
|
#include "linespec.h"
|
||||||
#include "completer.h"
|
#include "completer.h"
|
||||||
#include "gdb.h"
|
#include "gdb.h"
|
||||||
|
@ -4618,8 +4619,12 @@ parse_breakpoint_sals (char **address,
|
||||||
current_source_symtab (which is decode_line_1's default). This
|
current_source_symtab (which is decode_line_1's default). This
|
||||||
should produce the results we want almost all of the time while
|
should produce the results we want almost all of the time while
|
||||||
leaving default_breakpoint_* alone. */
|
leaving default_breakpoint_* alone. */
|
||||||
|
|
||||||
|
struct symtab_and_line cursal =
|
||||||
|
get_current_or_default_source_symtab_and_line ();
|
||||||
|
|
||||||
if (default_breakpoint_valid
|
if (default_breakpoint_valid
|
||||||
&& (!current_source_symtab
|
&& (!cursal.symtab
|
||||||
|| (strchr ("+-", (*address)[0]) != NULL)))
|
|| (strchr ("+-", (*address)[0]) != NULL)))
|
||||||
*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
|
*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
|
||||||
default_breakpoint_line, addr_string);
|
default_breakpoint_line, addr_string);
|
||||||
|
|
|
@ -25,7 +25,12 @@
|
||||||
#include "gdb_wait.h" /* For shell escape implementation */
|
#include "gdb_wait.h" /* For shell escape implementation */
|
||||||
#include "gdb_regex.h" /* Used by apropos_command */
|
#include "gdb_regex.h" /* Used by apropos_command */
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
|
#include "linespec.h"
|
||||||
|
#include "expression.h"
|
||||||
|
#include "language.h"
|
||||||
#include "filenames.h" /* for DOSish file names */
|
#include "filenames.h" /* for DOSish file names */
|
||||||
|
#include "objfiles.h"
|
||||||
|
#include "source.h"
|
||||||
|
|
||||||
#include "ui-out.h"
|
#include "ui-out.h"
|
||||||
|
|
||||||
|
@ -51,7 +56,7 @@ extern void set_history (char *, int);
|
||||||
|
|
||||||
extern void show_commands (char *, int);
|
extern void show_commands (char *, int);
|
||||||
|
|
||||||
/* Prototypes for local functions */
|
/* Prototypes for local command functions */
|
||||||
|
|
||||||
static void complete_command (char *, int);
|
static void complete_command (char *, int);
|
||||||
|
|
||||||
|
@ -79,7 +84,15 @@ static void make_command (char *, int);
|
||||||
|
|
||||||
static void shell_escape (char *, int);
|
static void shell_escape (char *, int);
|
||||||
|
|
||||||
|
static void edit_command (char *, int);
|
||||||
|
|
||||||
|
static void list_command (char *, int);
|
||||||
|
|
||||||
void apropos_command (char *, int);
|
void apropos_command (char *, int);
|
||||||
|
|
||||||
|
/* Prototypes for local utility functions */
|
||||||
|
|
||||||
|
static void ambiguous_line_spec (struct symtabs_and_lines *);
|
||||||
|
|
||||||
/* Limit the call depth of user-defined commands */
|
/* Limit the call depth of user-defined commands */
|
||||||
int max_user_call_depth;
|
int max_user_call_depth;
|
||||||
|
@ -525,6 +538,281 @@ shell_escape (char *arg, int from_tty)
|
||||||
#endif /* Can fork. */
|
#endif /* Can fork. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
edit_command (char *arg, int from_tty)
|
||||||
|
{
|
||||||
|
struct symtabs_and_lines sals;
|
||||||
|
struct symtab_and_line sal;
|
||||||
|
struct symbol *sym;
|
||||||
|
char *arg1;
|
||||||
|
int cmdlen, log10;
|
||||||
|
unsigned m;
|
||||||
|
char *editor;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/* Pull in the current default source line if necessary */
|
||||||
|
if (arg == 0)
|
||||||
|
sal = get_current_or_default_source_symtab_and_line ();
|
||||||
|
|
||||||
|
/* bare "edit" edits file with present line. */
|
||||||
|
|
||||||
|
if (arg == 0)
|
||||||
|
{
|
||||||
|
if (sal.symtab == 0)
|
||||||
|
error ("No default source file yet.");
|
||||||
|
sal.line += get_lines_to_list () / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Now should only be one argument -- decode it in SAL */
|
||||||
|
|
||||||
|
arg1 = arg;
|
||||||
|
sals = decode_line_1 (&arg1, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (! sals.nelts) return; /* C++ */
|
||||||
|
if (sals.nelts > 1) {
|
||||||
|
ambiguous_line_spec (&sals);
|
||||||
|
xfree (sals.sals);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sal = sals.sals[0];
|
||||||
|
xfree (sals.sals);
|
||||||
|
|
||||||
|
if (*arg1)
|
||||||
|
error ("Junk at end of line specification.");
|
||||||
|
|
||||||
|
/* if line was specified by address,
|
||||||
|
first print exactly which line, and which file.
|
||||||
|
In this case, sal.symtab == 0 means address is outside
|
||||||
|
of all known source files, not that user failed to give a filename. */
|
||||||
|
if (*arg == '*')
|
||||||
|
{
|
||||||
|
if (sal.symtab == 0)
|
||||||
|
/* FIXME-32x64--assumes sal.pc fits in long. */
|
||||||
|
error ("No source file for address %s.",
|
||||||
|
local_hex_string((unsigned long) sal.pc));
|
||||||
|
sym = find_pc_function (sal.pc);
|
||||||
|
if (sym)
|
||||||
|
{
|
||||||
|
print_address_numeric (sal.pc, 1, gdb_stdout);
|
||||||
|
printf_filtered (" is in ");
|
||||||
|
fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
|
||||||
|
printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_address_numeric (sal.pc, 1, gdb_stdout);
|
||||||
|
printf_filtered (" is at %s:%d.\n",
|
||||||
|
sal.symtab->filename, sal.line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If what was given does not imply a symtab, it must be an undebuggable
|
||||||
|
symbol which means no source code. */
|
||||||
|
|
||||||
|
if (sal.symtab == 0)
|
||||||
|
error ("No line number known for %s.", arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((editor = (char *) getenv ("EDITOR")) == NULL)
|
||||||
|
editor = "/bin/ex";
|
||||||
|
|
||||||
|
/* Approximate base-10 log of line to 1 unit for digit count */
|
||||||
|
for(log10=32, m=0x80000000; !(sal.line & m) && log10>0; log10--, m=m>>1);
|
||||||
|
log10 = 1 + (int)((log10 + (0 == ((m-1) & sal.line)))/3.32192809);
|
||||||
|
|
||||||
|
cmdlen = strlen(editor) + 1
|
||||||
|
+ (NULL == sal.symtab->dirname ? 0 : strlen(sal.symtab->dirname) + 1)
|
||||||
|
+ (NULL == sal.symtab->filename? 0 : strlen(sal.symtab->filename)+ 1)
|
||||||
|
+ log10 + 2;
|
||||||
|
|
||||||
|
p = xmalloc(cmdlen);
|
||||||
|
sprintf(p,"%s +%d %s%s",editor,sal.line,
|
||||||
|
(NULL == sal.symtab->dirname ? "./" :
|
||||||
|
(NULL != sal.symtab->filename && *(sal.symtab->filename) != '/') ?
|
||||||
|
sal.symtab->dirname : ""),
|
||||||
|
(NULL == sal.symtab->filename ? "unknown" : sal.symtab->filename)
|
||||||
|
);
|
||||||
|
shell_escape(p, from_tty);
|
||||||
|
|
||||||
|
xfree(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_command (char *arg, int from_tty)
|
||||||
|
{
|
||||||
|
struct symtabs_and_lines sals, sals_end;
|
||||||
|
struct symtab_and_line sal, sal_end, cursal;
|
||||||
|
struct symbol *sym;
|
||||||
|
char *arg1;
|
||||||
|
int no_end = 1;
|
||||||
|
int dummy_end = 0;
|
||||||
|
int dummy_beg = 0;
|
||||||
|
int linenum_beg = 0;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/* Pull in the current default source line if necessary */
|
||||||
|
if (arg == 0 || arg[0] == '+' || arg[0] == '-')
|
||||||
|
cursal = get_current_or_default_source_symtab_and_line ();
|
||||||
|
|
||||||
|
/* "l" or "l +" lists next ten lines. */
|
||||||
|
|
||||||
|
if (arg == 0 || STREQ (arg, "+"))
|
||||||
|
{
|
||||||
|
print_source_lines (cursal.symtab, cursal.line,
|
||||||
|
cursal.line + get_lines_to_list (), 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "l -" lists previous ten lines, the ones before the ten just listed. */
|
||||||
|
if (STREQ (arg, "-"))
|
||||||
|
{
|
||||||
|
print_source_lines (cursal.symtab,
|
||||||
|
max (get_first_line_listed () - get_lines_to_list (), 1),
|
||||||
|
get_first_line_listed (), 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now if there is only one argument, decode it in SAL
|
||||||
|
and set NO_END.
|
||||||
|
If there are two arguments, decode them in SAL and SAL_END
|
||||||
|
and clear NO_END; however, if one of the arguments is blank,
|
||||||
|
set DUMMY_BEG or DUMMY_END to record that fact. */
|
||||||
|
|
||||||
|
if (!have_full_symbols () && !have_partial_symbols ())
|
||||||
|
error ("No symbol table is loaded. Use the \"file\" command.");
|
||||||
|
|
||||||
|
arg1 = arg;
|
||||||
|
if (*arg1 == ',')
|
||||||
|
dummy_beg = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sals = decode_line_1 (&arg1, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (!sals.nelts)
|
||||||
|
return; /* C++ */
|
||||||
|
if (sals.nelts > 1)
|
||||||
|
{
|
||||||
|
ambiguous_line_spec (&sals);
|
||||||
|
xfree (sals.sals);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sal = sals.sals[0];
|
||||||
|
xfree (sals.sals);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record whether the BEG arg is all digits. */
|
||||||
|
|
||||||
|
for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
|
||||||
|
linenum_beg = (p == arg1);
|
||||||
|
|
||||||
|
while (*arg1 == ' ' || *arg1 == '\t')
|
||||||
|
arg1++;
|
||||||
|
if (*arg1 == ',')
|
||||||
|
{
|
||||||
|
no_end = 0;
|
||||||
|
arg1++;
|
||||||
|
while (*arg1 == ' ' || *arg1 == '\t')
|
||||||
|
arg1++;
|
||||||
|
if (*arg1 == 0)
|
||||||
|
dummy_end = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dummy_beg)
|
||||||
|
sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
|
||||||
|
else
|
||||||
|
sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
|
||||||
|
if (sals_end.nelts == 0)
|
||||||
|
return;
|
||||||
|
if (sals_end.nelts > 1)
|
||||||
|
{
|
||||||
|
ambiguous_line_spec (&sals_end);
|
||||||
|
xfree (sals_end.sals);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sal_end = sals_end.sals[0];
|
||||||
|
xfree (sals_end.sals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*arg1)
|
||||||
|
error ("Junk at end of line specification.");
|
||||||
|
|
||||||
|
if (!no_end && !dummy_beg && !dummy_end
|
||||||
|
&& sal.symtab != sal_end.symtab)
|
||||||
|
error ("Specified start and end are in different files.");
|
||||||
|
if (dummy_beg && dummy_end)
|
||||||
|
error ("Two empty args do not say what lines to list.");
|
||||||
|
|
||||||
|
/* if line was specified by address,
|
||||||
|
first print exactly which line, and which file.
|
||||||
|
In this case, sal.symtab == 0 means address is outside
|
||||||
|
of all known source files, not that user failed to give a filename. */
|
||||||
|
if (*arg == '*')
|
||||||
|
{
|
||||||
|
if (sal.symtab == 0)
|
||||||
|
/* FIXME-32x64--assumes sal.pc fits in long. */
|
||||||
|
error ("No source file for address %s.",
|
||||||
|
local_hex_string ((unsigned long) sal.pc));
|
||||||
|
sym = find_pc_function (sal.pc);
|
||||||
|
if (sym)
|
||||||
|
{
|
||||||
|
print_address_numeric (sal.pc, 1, gdb_stdout);
|
||||||
|
printf_filtered (" is in ");
|
||||||
|
fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
|
||||||
|
printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_address_numeric (sal.pc, 1, gdb_stdout);
|
||||||
|
printf_filtered (" is at %s:%d.\n",
|
||||||
|
sal.symtab->filename, sal.line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If line was not specified by just a line number,
|
||||||
|
and it does not imply a symtab, it must be an undebuggable symbol
|
||||||
|
which means no source code. */
|
||||||
|
|
||||||
|
if (!linenum_beg && sal.symtab == 0)
|
||||||
|
error ("No line number known for %s.", arg);
|
||||||
|
|
||||||
|
/* If this command is repeated with RET,
|
||||||
|
turn it into the no-arg variant. */
|
||||||
|
|
||||||
|
if (from_tty)
|
||||||
|
*arg = 0;
|
||||||
|
|
||||||
|
if (dummy_beg && sal_end.symtab == 0)
|
||||||
|
error ("No default source file yet. Do \"help list\".");
|
||||||
|
if (dummy_beg)
|
||||||
|
print_source_lines (sal_end.symtab,
|
||||||
|
max (sal_end.line - (get_lines_to_list () - 1), 1),
|
||||||
|
sal_end.line + 1, 0);
|
||||||
|
else if (sal.symtab == 0)
|
||||||
|
error ("No default source file yet. Do \"help list\".");
|
||||||
|
else if (no_end)
|
||||||
|
{
|
||||||
|
int first_line = sal.line - get_lines_to_list () / 2;
|
||||||
|
|
||||||
|
if (first_line < 1) first_line = 1;
|
||||||
|
|
||||||
|
print_source_lines (sal.symtab,
|
||||||
|
first_line,
|
||||||
|
first_line + get_lines_to_list (),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
print_source_lines (sal.symtab, sal.line,
|
||||||
|
(dummy_end
|
||||||
|
? sal.line + get_lines_to_list ()
|
||||||
|
: sal_end.line + 1),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_command (char *arg, int from_tty)
|
make_command (char *arg, int from_tty)
|
||||||
{
|
{
|
||||||
|
@ -594,6 +882,21 @@ apropos_command (char *searchstr, int from_tty)
|
||||||
xfree (pattern_fastmap);
|
xfree (pattern_fastmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print a list of files and line numbers which a user may choose from
|
||||||
|
in order to list a function which was specified ambiguously (as with
|
||||||
|
`list classname::overloadedfuncname', for example). The vector in
|
||||||
|
SALS provides the filenames and line numbers. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ambiguous_line_spec (struct symtabs_and_lines *sals)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < sals->nelts; ++i)
|
||||||
|
printf_filtered ("file: \"%s\", line number: %d\n",
|
||||||
|
sals->sals[i].symtab->filename, sals->sals[i].line);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_debug (char *arg, int from_tty)
|
set_debug (char *arg, int from_tty)
|
||||||
{
|
{
|
||||||
|
@ -812,6 +1115,43 @@ from the target.", &setlist),
|
||||||
With no arguments, run an inferior shell.");
|
With no arguments, run an inferior shell.");
|
||||||
set_cmd_completer (c, filename_completer);
|
set_cmd_completer (c, filename_completer);
|
||||||
|
|
||||||
|
c = add_com ("edit", class_files, edit_command,
|
||||||
|
concat ("Edit specified file or function.\n\
|
||||||
|
With no argument, edits file containing most recent line listed.\n\
|
||||||
|
", "\
|
||||||
|
Editing targets can be specified in these ways:\n\
|
||||||
|
FILE:LINENUM, to edit at that line in that file,\n\
|
||||||
|
FUNCTION, to edit at the beginning of that function,\n\
|
||||||
|
FILE:FUNCTION, to distinguish among like-named static functions.\n\
|
||||||
|
*ADDRESS, to edit at the line containing that address.\n\
|
||||||
|
Uses EDITOR environment variable contents as editor (or ex as default).",NULL));
|
||||||
|
|
||||||
|
c->completer = location_completer;
|
||||||
|
|
||||||
|
add_com ("list", class_files, list_command,
|
||||||
|
concat ("List specified function or line.\n\
|
||||||
|
With no argument, lists ten more lines after or around previous listing.\n\
|
||||||
|
\"list -\" lists the ten lines before a previous ten-line listing.\n\
|
||||||
|
One argument specifies a line, and ten lines are listed around that line.\n\
|
||||||
|
Two arguments with comma between specify starting and ending lines to list.\n\
|
||||||
|
", "\
|
||||||
|
Lines can be specified in these ways:\n\
|
||||||
|
LINENUM, to list around that line in current file,\n\
|
||||||
|
FILE:LINENUM, to list around that line in that file,\n\
|
||||||
|
FUNCTION, to list around beginning of that function,\n\
|
||||||
|
FILE:FUNCTION, to distinguish among like-named static functions.\n\
|
||||||
|
*ADDRESS, to list around the line containing that address.\n\
|
||||||
|
With two args if one is empty it stands for ten lines away from the other arg.", NULL));
|
||||||
|
|
||||||
|
if (!xdb_commands)
|
||||||
|
add_com_alias ("l", "list", class_files, 1);
|
||||||
|
else
|
||||||
|
add_com_alias ("v", "list", class_files, 1);
|
||||||
|
|
||||||
|
if (dbx_commands)
|
||||||
|
add_com_alias ("file", "list", class_files, 1);
|
||||||
|
|
||||||
|
|
||||||
/* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would
|
/* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would
|
||||||
be a really useful feature. Unfortunately, the below wont do
|
be a really useful feature. Unfortunately, the below wont do
|
||||||
this. Instead it adds support for the form ``(gdb) ! ls''
|
this. Instead it adds support for the form ``(gdb) ! ls''
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
|
#include "source.h"
|
||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "completer.h"
|
#include "completer.h"
|
||||||
|
@ -545,8 +546,14 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
|
||||||
|
|
||||||
if (default_symtab == 0)
|
if (default_symtab == 0)
|
||||||
{
|
{
|
||||||
default_symtab = current_source_symtab;
|
/* Use whatever we have for the default source line. We don't use
|
||||||
default_line = current_source_line;
|
get_current_or_default_symtab_and_line as it can recurse and call
|
||||||
|
us back! */
|
||||||
|
struct symtab_and_line cursal =
|
||||||
|
get_current_source_symtab_and_line ();
|
||||||
|
|
||||||
|
default_symtab = cursal.symtab;
|
||||||
|
default_line = cursal.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if arg is *PC */
|
/* See if arg is *PC */
|
||||||
|
@ -1020,13 +1027,16 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
|
||||||
/* This is where we need to make sure that we have good defaults.
|
/* This is where we need to make sure that we have good defaults.
|
||||||
We must guarantee that this section of code is never executed
|
We must guarantee that this section of code is never executed
|
||||||
when we are called with just a function name, since
|
when we are called with just a function name, since
|
||||||
select_source_symtab calls us with such an argument */
|
get_current_or_default_source_symtab_and_line uses
|
||||||
|
select_source_symtab that calls us with such an argument */
|
||||||
|
|
||||||
if (s == 0 && default_symtab == 0)
|
if (s == 0 && default_symtab == 0)
|
||||||
{
|
{
|
||||||
select_source_symtab (0);
|
struct symtab_and_line cursal =
|
||||||
default_symtab = current_source_symtab;
|
get_current_or_default_source_symtab_and_line ();
|
||||||
default_line = current_source_line;
|
|
||||||
|
default_symtab = cursal.symtab;
|
||||||
|
default_line = cursal.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (**argptr == '+')
|
if (**argptr == '+')
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "macroscope.h"
|
#include "macroscope.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
#include "source.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
@ -84,11 +85,14 @@ default_macro_scope (void)
|
||||||
evaluator to evaluate their numeric arguments. If the
|
evaluator to evaluate their numeric arguments. If the
|
||||||
current language is C, then that may call this function to
|
current language is C, then that may call this function to
|
||||||
choose a scope for macro expansion. If you don't have any
|
choose a scope for macro expansion. If you don't have any
|
||||||
symbol files loaded, then select_source_symtab will raise an
|
symbol files loaded, then get_current_or_default would raise an
|
||||||
error. But `set width' shouldn't raise an error just because
|
error. But `set width' shouldn't raise an error just because
|
||||||
it can't decide which scope to macro-expand its argument in. */
|
it can't decide which scope to macro-expand its argument in. */
|
||||||
sal.symtab = current_source_symtab;
|
struct symtab_and_line cursal =
|
||||||
sal.line = current_source_line;
|
get_current_source_symtab_and_line ();
|
||||||
|
|
||||||
|
sal.symtab = cursal.symtab;
|
||||||
|
sal.line = cursal.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sal_macro_scope (sal);
|
return sal_macro_scope (sal);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "c-lang.h"
|
#include "c-lang.h"
|
||||||
#include "scm-lang.h"
|
#include "scm-lang.h"
|
||||||
#include "scm-tags.h"
|
#include "scm-tags.h"
|
||||||
|
#include "source.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
|
|
||||||
|
@ -133,9 +134,12 @@ scm_unpack (struct type *type, char *valaddr, enum type_code context)
|
||||||
static int
|
static int
|
||||||
in_eval_c (void)
|
in_eval_c (void)
|
||||||
{
|
{
|
||||||
if (current_source_symtab && current_source_symtab->filename)
|
struct symtab_and_line cursal =
|
||||||
|
get_current_or_default_source_symtab_and_line ();
|
||||||
|
|
||||||
|
if (cursal.symtab && cursal.symtab->filename)
|
||||||
{
|
{
|
||||||
char *filename = current_source_symtab->filename;
|
char *filename = cursal.symtab->filename;
|
||||||
int len = strlen (filename);
|
int len = strlen (filename);
|
||||||
if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0)
|
if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
295
gdb/source.c
295
gdb/source.c
|
@ -79,8 +79,6 @@ static void forward_search_command (char *, int);
|
||||||
|
|
||||||
static void line_info (char *, int);
|
static void line_info (char *, int);
|
||||||
|
|
||||||
static void list_command (char *, int);
|
|
||||||
|
|
||||||
static void ambiguous_line_spec (struct symtabs_and_lines *);
|
static void ambiguous_line_spec (struct symtabs_and_lines *);
|
||||||
|
|
||||||
static void source_info (char *, int);
|
static void source_info (char *, int);
|
||||||
|
@ -94,11 +92,11 @@ char *source_path;
|
||||||
|
|
||||||
/* Symtab of default file for listing lines of. */
|
/* Symtab of default file for listing lines of. */
|
||||||
|
|
||||||
struct symtab *current_source_symtab;
|
static struct symtab *current_source_symtab;
|
||||||
|
|
||||||
/* Default next line to list. */
|
/* Default next line to list. */
|
||||||
|
|
||||||
int current_source_line;
|
static int current_source_line;
|
||||||
|
|
||||||
/* Default number of lines to print with commands like "list".
|
/* Default number of lines to print with commands like "list".
|
||||||
This is based on guessing how many long (i.e. more than chars_per_line
|
This is based on guessing how many long (i.e. more than chars_per_line
|
||||||
|
@ -123,6 +121,94 @@ static int first_line_listed;
|
||||||
static struct symtab *last_source_visited = NULL;
|
static struct symtab *last_source_visited = NULL;
|
||||||
static int last_source_error = 0;
|
static int last_source_error = 0;
|
||||||
|
|
||||||
|
/* Return the first line listed by print_source_lines.
|
||||||
|
Used by command interpreters to request listing from
|
||||||
|
a previous point. */
|
||||||
|
|
||||||
|
int
|
||||||
|
get_first_line_listed (void)
|
||||||
|
{
|
||||||
|
return first_line_listed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the default number of lines to print with commands like the
|
||||||
|
cli "list". The caller of print_source_lines must use this to
|
||||||
|
calculate the end line and use it in the call to print_source_lines
|
||||||
|
as it does not automatically use this value. */
|
||||||
|
|
||||||
|
int
|
||||||
|
get_lines_to_list (void)
|
||||||
|
{
|
||||||
|
return lines_to_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the current source file for listing and next line to list.
|
||||||
|
NOTE: The returned sal pc and end fields are not valid. */
|
||||||
|
|
||||||
|
struct symtab_and_line
|
||||||
|
get_current_source_symtab_and_line (void)
|
||||||
|
{
|
||||||
|
struct symtab_and_line cursal;
|
||||||
|
|
||||||
|
cursal.symtab = current_source_symtab;
|
||||||
|
cursal.line = current_source_line;
|
||||||
|
|
||||||
|
return cursal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the current source file for listing and next line to list.
|
||||||
|
If a file is not set, try and get a default.
|
||||||
|
It may err out if a default cannot be determined.
|
||||||
|
Depending on where it is called, it can recurse as the process of
|
||||||
|
determining a new default may call the caler!
|
||||||
|
Use get_current_source_symtab_and_line instead to get whatever
|
||||||
|
we have without erroring out or trying to get a default.
|
||||||
|
NOTE: The returned sal pc and end fields are not valid. */
|
||||||
|
|
||||||
|
struct symtab_and_line
|
||||||
|
get_current_or_default_source_symtab_and_line (void)
|
||||||
|
{
|
||||||
|
struct symtab_and_line cursal;
|
||||||
|
|
||||||
|
if (!have_full_symbols () && !have_partial_symbols ())
|
||||||
|
error ("No symbol table is loaded. Use the \"file\" command.");
|
||||||
|
|
||||||
|
/* Pull in a current source symtab if necessary */
|
||||||
|
if (current_source_symtab == 0)
|
||||||
|
select_source_symtab (0);
|
||||||
|
|
||||||
|
cursal.symtab = current_source_symtab;
|
||||||
|
cursal.line = current_source_line;
|
||||||
|
|
||||||
|
return cursal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the current default file for listing and next line to list
|
||||||
|
(the returned sal pc and end fields are not valid.)
|
||||||
|
and set the surrent default to whatever is in SAL */
|
||||||
|
|
||||||
|
struct symtab_and_line
|
||||||
|
set_current_source_symtab_and_line (struct symtab_and_line *sal)
|
||||||
|
{
|
||||||
|
struct symtab_and_line cursal;
|
||||||
|
|
||||||
|
cursal.symtab = current_source_symtab;
|
||||||
|
cursal.line = current_source_line;
|
||||||
|
|
||||||
|
current_source_symtab = sal->symtab;
|
||||||
|
current_source_line = sal->line;
|
||||||
|
|
||||||
|
return cursal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset any information stored about a default file and line to print. */
|
||||||
|
|
||||||
|
void
|
||||||
|
clear_current_source_symtab_and_line (void)
|
||||||
|
{
|
||||||
|
current_source_symtab = 0;
|
||||||
|
current_source_line = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the source file default for the "list" command to be S.
|
/* Set the source file default for the "list" command to be S.
|
||||||
|
|
||||||
|
@ -1110,8 +1196,6 @@ print_source_lines (struct symtab *s, int line, int stopline, int noerror)
|
||||||
print_source_lines_base (s, line, stopline, noerror);
|
print_source_lines_base (s, line, stopline, noerror);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Print a list of files and line numbers which a user may choose from
|
/* Print a list of files and line numbers which a user may choose from
|
||||||
in order to list a function which was specified ambiguously (as with
|
in order to list a function which was specified ambiguously (as with
|
||||||
`list classname::overloadedfuncname', for example). The vector in
|
`list classname::overloadedfuncname', for example). The vector in
|
||||||
|
@ -1126,182 +1210,6 @@ ambiguous_line_spec (struct symtabs_and_lines *sals)
|
||||||
printf_filtered ("file: \"%s\", line number: %d\n",
|
printf_filtered ("file: \"%s\", line number: %d\n",
|
||||||
sals->sals[i].symtab->filename, sals->sals[i].line);
|
sals->sals[i].symtab->filename, sals->sals[i].line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
list_command (char *arg, int from_tty)
|
|
||||||
{
|
|
||||||
struct symtabs_and_lines sals, sals_end;
|
|
||||||
struct symtab_and_line sal, sal_end;
|
|
||||||
struct symbol *sym;
|
|
||||||
char *arg1;
|
|
||||||
int no_end = 1;
|
|
||||||
int dummy_end = 0;
|
|
||||||
int dummy_beg = 0;
|
|
||||||
int linenum_beg = 0;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (!have_full_symbols () && !have_partial_symbols ())
|
|
||||||
error ("No symbol table is loaded. Use the \"file\" command.");
|
|
||||||
|
|
||||||
/* Pull in a current source symtab if necessary */
|
|
||||||
if (current_source_symtab == 0 &&
|
|
||||||
(arg == 0 || arg[0] == '+' || arg[0] == '-'))
|
|
||||||
select_source_symtab (0);
|
|
||||||
|
|
||||||
/* "l" or "l +" lists next ten lines. */
|
|
||||||
|
|
||||||
if (arg == 0 || STREQ (arg, "+"))
|
|
||||||
{
|
|
||||||
if (current_source_symtab == 0)
|
|
||||||
error ("No default source file yet. Do \"help list\".");
|
|
||||||
print_source_lines (current_source_symtab, current_source_line,
|
|
||||||
current_source_line + lines_to_list, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "l -" lists previous ten lines, the ones before the ten just listed. */
|
|
||||||
if (STREQ (arg, "-"))
|
|
||||||
{
|
|
||||||
if (current_source_symtab == 0)
|
|
||||||
error ("No default source file yet. Do \"help list\".");
|
|
||||||
print_source_lines (current_source_symtab,
|
|
||||||
max (first_line_listed - lines_to_list, 1),
|
|
||||||
first_line_listed, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now if there is only one argument, decode it in SAL
|
|
||||||
and set NO_END.
|
|
||||||
If there are two arguments, decode them in SAL and SAL_END
|
|
||||||
and clear NO_END; however, if one of the arguments is blank,
|
|
||||||
set DUMMY_BEG or DUMMY_END to record that fact. */
|
|
||||||
|
|
||||||
arg1 = arg;
|
|
||||||
if (*arg1 == ',')
|
|
||||||
dummy_beg = 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sals = decode_line_1 (&arg1, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
if (!sals.nelts)
|
|
||||||
return; /* C++ */
|
|
||||||
if (sals.nelts > 1)
|
|
||||||
{
|
|
||||||
ambiguous_line_spec (&sals);
|
|
||||||
xfree (sals.sals);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sal = sals.sals[0];
|
|
||||||
xfree (sals.sals);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Record whether the BEG arg is all digits. */
|
|
||||||
|
|
||||||
for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
|
|
||||||
linenum_beg = (p == arg1);
|
|
||||||
|
|
||||||
while (*arg1 == ' ' || *arg1 == '\t')
|
|
||||||
arg1++;
|
|
||||||
if (*arg1 == ',')
|
|
||||||
{
|
|
||||||
no_end = 0;
|
|
||||||
arg1++;
|
|
||||||
while (*arg1 == ' ' || *arg1 == '\t')
|
|
||||||
arg1++;
|
|
||||||
if (*arg1 == 0)
|
|
||||||
dummy_end = 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (dummy_beg)
|
|
||||||
sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
|
|
||||||
else
|
|
||||||
sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
|
|
||||||
if (sals_end.nelts == 0)
|
|
||||||
return;
|
|
||||||
if (sals_end.nelts > 1)
|
|
||||||
{
|
|
||||||
ambiguous_line_spec (&sals_end);
|
|
||||||
xfree (sals_end.sals);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sal_end = sals_end.sals[0];
|
|
||||||
xfree (sals_end.sals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*arg1)
|
|
||||||
error ("Junk at end of line specification.");
|
|
||||||
|
|
||||||
if (!no_end && !dummy_beg && !dummy_end
|
|
||||||
&& sal.symtab != sal_end.symtab)
|
|
||||||
error ("Specified start and end are in different files.");
|
|
||||||
if (dummy_beg && dummy_end)
|
|
||||||
error ("Two empty args do not say what lines to list.");
|
|
||||||
|
|
||||||
/* if line was specified by address,
|
|
||||||
first print exactly which line, and which file.
|
|
||||||
In this case, sal.symtab == 0 means address is outside
|
|
||||||
of all known source files, not that user failed to give a filename. */
|
|
||||||
if (*arg == '*')
|
|
||||||
{
|
|
||||||
if (sal.symtab == 0)
|
|
||||||
/* FIXME-32x64--assumes sal.pc fits in long. */
|
|
||||||
error ("No source file for address %s.",
|
|
||||||
local_hex_string ((unsigned long) sal.pc));
|
|
||||||
sym = find_pc_function (sal.pc);
|
|
||||||
if (sym)
|
|
||||||
{
|
|
||||||
print_address_numeric (sal.pc, 1, gdb_stdout);
|
|
||||||
printf_filtered (" is in ");
|
|
||||||
fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
|
|
||||||
printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print_address_numeric (sal.pc, 1, gdb_stdout);
|
|
||||||
printf_filtered (" is at %s:%d.\n",
|
|
||||||
sal.symtab->filename, sal.line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If line was not specified by just a line number,
|
|
||||||
and it does not imply a symtab, it must be an undebuggable symbol
|
|
||||||
which means no source code. */
|
|
||||||
|
|
||||||
if (!linenum_beg && sal.symtab == 0)
|
|
||||||
error ("No line number known for %s.", arg);
|
|
||||||
|
|
||||||
/* If this command is repeated with RET,
|
|
||||||
turn it into the no-arg variant. */
|
|
||||||
|
|
||||||
if (from_tty)
|
|
||||||
*arg = 0;
|
|
||||||
|
|
||||||
if (dummy_beg && sal_end.symtab == 0)
|
|
||||||
error ("No default source file yet. Do \"help list\".");
|
|
||||||
if (dummy_beg)
|
|
||||||
print_source_lines (sal_end.symtab,
|
|
||||||
max (sal_end.line - (lines_to_list - 1), 1),
|
|
||||||
sal_end.line + 1, 0);
|
|
||||||
else if (sal.symtab == 0)
|
|
||||||
error ("No default source file yet. Do \"help list\".");
|
|
||||||
else if (no_end)
|
|
||||||
{
|
|
||||||
int first_line = sal.line - lines_to_list / 2;
|
|
||||||
|
|
||||||
if (first_line < 1) first_line = 1;
|
|
||||||
|
|
||||||
print_source_lines (sal.symtab, first_line, first_line + lines_to_list,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
print_source_lines (sal.symtab, sal.line,
|
|
||||||
(dummy_end
|
|
||||||
? sal.line + lines_to_list
|
|
||||||
: sal_end.line + 1),
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print info on range of pc's in a specified line. */
|
/* Print info on range of pc's in a specified line. */
|
||||||
|
|
||||||
|
@ -1662,29 +1570,6 @@ The matching line number is also stored as the value of \"$_\".");
|
||||||
add_com_alias ("?", "reverse-search", class_files, 0);
|
add_com_alias ("?", "reverse-search", class_files, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_com ("list", class_files, list_command,
|
|
||||||
concat ("List specified function or line.\n\
|
|
||||||
With no argument, lists ten more lines after or around previous listing.\n\
|
|
||||||
\"list -\" lists the ten lines before a previous ten-line listing.\n\
|
|
||||||
One argument specifies a line, and ten lines are listed around that line.\n\
|
|
||||||
Two arguments with comma between specify starting and ending lines to list.\n\
|
|
||||||
", "\
|
|
||||||
Lines can be specified in these ways:\n\
|
|
||||||
LINENUM, to list around that line in current file,\n\
|
|
||||||
FILE:LINENUM, to list around that line in that file,\n\
|
|
||||||
FUNCTION, to list around beginning of that function,\n\
|
|
||||||
FILE:FUNCTION, to distinguish among like-named static functions.\n\
|
|
||||||
*ADDRESS, to list around the line containing that address.\n\
|
|
||||||
With two args if one is empty it stands for ten lines away from the other arg.", NULL));
|
|
||||||
|
|
||||||
if (!xdb_commands)
|
|
||||||
add_com_alias ("l", "list", class_files, 1);
|
|
||||||
else
|
|
||||||
add_com_alias ("v", "list", class_files, 1);
|
|
||||||
|
|
||||||
if (dbx_commands)
|
|
||||||
add_com_alias ("file", "list", class_files, 1);
|
|
||||||
|
|
||||||
add_show_from_set
|
add_show_from_set
|
||||||
(add_set_cmd ("listsize", class_support, var_uinteger,
|
(add_set_cmd ("listsize", class_support, var_uinteger,
|
||||||
(char *) &lines_to_list,
|
(char *) &lines_to_list,
|
||||||
|
|
32
gdb/source.h
32
gdb/source.h
|
@ -31,4 +31,36 @@ extern int open_source_file (struct symtab *s);
|
||||||
lines. */
|
lines. */
|
||||||
extern void find_source_lines (struct symtab *s, int desc);
|
extern void find_source_lines (struct symtab *s, int desc);
|
||||||
|
|
||||||
|
/* Return the first line listed by print_source_lines.
|
||||||
|
Used by command interpreters to request listing from
|
||||||
|
a previous point. */
|
||||||
|
extern int get_first_line_listed (void);
|
||||||
|
|
||||||
|
/* Return the default number of lines to print with commands like the
|
||||||
|
cli "list". The caller of print_source_lines must use this to
|
||||||
|
calculate the end line and use it in the call to print_source_lines
|
||||||
|
as it does not automatically use this value. */
|
||||||
|
extern int get_lines_to_list (void);
|
||||||
|
|
||||||
|
/* Return the current source file for listing and next line to list.
|
||||||
|
NOTE: The returned sal pc and end fields are not valid. */
|
||||||
|
extern void clear_current_source_symtab_and_line (void);
|
||||||
|
|
||||||
|
/* Return the current source file for listing and next line to list.
|
||||||
|
If a file is not set, try and get a default.
|
||||||
|
It may err out if a default cannot be determined.
|
||||||
|
Depending on where it is called, it can recurse as the process of
|
||||||
|
determining a new default may call the caler!
|
||||||
|
Use get_current_source_symtab_and_line instead to get whatever
|
||||||
|
we have without erroring out or trying to get a default.
|
||||||
|
NOTE: The returned sal pc and end fields are not valid. */
|
||||||
|
extern struct symtab_and_line get_current_source_symtab_and_line (void);
|
||||||
|
|
||||||
|
/* Return the current default file for listing and next line to list
|
||||||
|
(the returned sal pc and end fields are not valid.)
|
||||||
|
and set the surrent default to whatever is in SAL */
|
||||||
|
extern struct symtab_and_line get_current_or_default_source_symtab_and_line (void);
|
||||||
|
|
||||||
|
/* Reset any information stored about a default file and line to print. */
|
||||||
|
extern struct symtab_and_line set_current_source_symtab_and_line (struct symtab_and_line *);
|
||||||
#endif
|
#endif
|
||||||
|
|
13
gdb/stack.c
13
gdb/stack.c
|
@ -33,6 +33,7 @@
|
||||||
#include "gdbcmd.h"
|
#include "gdbcmd.h"
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
#include "source.h"
|
||||||
#include "breakpoint.h"
|
#include "breakpoint.h"
|
||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
@ -108,7 +109,6 @@ struct frame_info *parse_frame_specification (char *);
|
||||||
static void frame_info (char *, int);
|
static void frame_info (char *, int);
|
||||||
|
|
||||||
extern int addressprint; /* Print addresses, or stay symbolic only? */
|
extern int addressprint; /* Print addresses, or stay symbolic only? */
|
||||||
extern int lines_to_list; /* # of lines "list" command shows by default */
|
|
||||||
|
|
||||||
/* The "selected" stack frame is used by default for local and arg access.
|
/* The "selected" stack frame is used by default for local and arg access.
|
||||||
May be zero, for no selected frame. */
|
May be zero, for no selected frame. */
|
||||||
|
@ -398,14 +398,13 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args)
|
||||||
print_frame (fi, level, source, args, sal);
|
print_frame (fi, level, source, args, sal);
|
||||||
|
|
||||||
source_print = (source == SRC_LINE || source == SRC_AND_LOC);
|
source_print = (source == SRC_LINE || source == SRC_AND_LOC);
|
||||||
|
|
||||||
if (sal.symtab)
|
if (sal.symtab)
|
||||||
{
|
set_current_source_symtab_and_line (&sal);
|
||||||
current_source_symtab = sal.symtab;
|
|
||||||
current_source_line = sal.line;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source_print && sal.symtab)
|
if (source_print && sal.symtab)
|
||||||
{
|
{
|
||||||
|
struct symtab_and_line cursal;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
int mid_statement = (source == SRC_LINE) && (fi->pc != sal.pc);
|
int mid_statement = (source == SRC_LINE) && (fi->pc != sal.pc);
|
||||||
|
|
||||||
|
@ -435,7 +434,9 @@ print_frame_info_base (struct frame_info *fi, int level, int source, int args)
|
||||||
print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
|
print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_source_line = max (sal.line - lines_to_list / 2, 1);
|
cursal = get_current_or_default_source_symtab_and_line ();
|
||||||
|
cursal.line = max (sal.line - get_lines_to_list () / 2, 1);
|
||||||
|
set_current_source_symtab_and_line (&cursal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source != 0)
|
if (source != 0)
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
|
#include "source.h"
|
||||||
#include "gdbcmd.h"
|
#include "gdbcmd.h"
|
||||||
#include "breakpoint.h"
|
#include "breakpoint.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
|
@ -2103,8 +2104,7 @@ clear_symtab_users (void)
|
||||||
clear_internalvars ();
|
clear_internalvars ();
|
||||||
breakpoint_re_set ();
|
breakpoint_re_set ();
|
||||||
set_default_breakpoint (0, 0, 0, 0);
|
set_default_breakpoint (0, 0, 0, 0);
|
||||||
current_source_symtab = 0;
|
clear_current_source_symtab_and_line ();
|
||||||
current_source_line = 0;
|
|
||||||
clear_pc_function_cache ();
|
clear_pc_function_cache ();
|
||||||
if (target_new_objfile_hook)
|
if (target_new_objfile_hook)
|
||||||
target_new_objfile_hook (NULL);
|
target_new_objfile_hook (NULL);
|
||||||
|
|
11
gdb/symtab.c
11
gdb/symtab.c
|
@ -38,6 +38,7 @@
|
||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
#include "linespec.h"
|
#include "linespec.h"
|
||||||
|
#include "source.h"
|
||||||
#include "filenames.h" /* for FILENAME_CMP */
|
#include "filenames.h" /* for FILENAME_CMP */
|
||||||
|
|
||||||
#include "gdb_obstack.h"
|
#include "gdb_obstack.h"
|
||||||
|
@ -3967,11 +3968,19 @@ struct symtabs_and_lines
|
||||||
decode_line_spec (char *string, int funfirstline)
|
decode_line_spec (char *string, int funfirstline)
|
||||||
{
|
{
|
||||||
struct symtabs_and_lines sals;
|
struct symtabs_and_lines sals;
|
||||||
|
struct symtab_and_line cursal;
|
||||||
|
|
||||||
if (string == 0)
|
if (string == 0)
|
||||||
error ("Empty line specification.");
|
error ("Empty line specification.");
|
||||||
|
|
||||||
|
/* We use whatever is set as the current source line. We do not try
|
||||||
|
and get a default or it will recursively call us! */
|
||||||
|
cursal = get_current_source_symtab_and_line ();
|
||||||
|
|
||||||
sals = decode_line_1 (&string, funfirstline,
|
sals = decode_line_1 (&string, funfirstline,
|
||||||
current_source_symtab, current_source_line,
|
cursal.symtab, cursal.line,
|
||||||
(char ***) NULL);
|
(char ***) NULL);
|
||||||
|
|
||||||
if (*string)
|
if (*string)
|
||||||
error ("Junk at end of line specification: %s", string);
|
error ("Junk at end of line specification: %s", string);
|
||||||
return sals;
|
return sals;
|
||||||
|
|
|
@ -1035,14 +1035,6 @@ struct partial_symtab
|
||||||
|
|
||||||
/* External variables and functions for the objects described above. */
|
/* External variables and functions for the objects described above. */
|
||||||
|
|
||||||
/* This symtab variable specifies the current file for printing source lines */
|
|
||||||
|
|
||||||
extern struct symtab *current_source_symtab;
|
|
||||||
|
|
||||||
/* This is the next line to print for listing source lines. */
|
|
||||||
|
|
||||||
extern int current_source_line;
|
|
||||||
|
|
||||||
/* See the comment in symfile.c about how current_objfile is used. */
|
/* See the comment in symfile.c about how current_objfile is used. */
|
||||||
|
|
||||||
extern struct objfile *current_objfile;
|
extern struct objfile *current_objfile;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue