From: Fernando Nasser Date: Fri, 20 Sep 2002 14:58:59 +0000 (+0000) Subject: * source.c: Make global variables current_source_symtab and X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0378c3323148fbb291d1035d9959de9d9c3a0f7b;p=binutils-gdb.git * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ba66a180913..f3cc92b24f1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,38 @@ +2002-09-13 Fernando Nasser + + * 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 * h8300-tdep.c (h8300_examine_prologue): Match saved regs location diff --git a/gdb/Makefile.in b/gdb/Makefile.in index ce88570e092..ca17a2b07a2 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) \ $(gdb_string_h) $(demangle_h) $(annotate_h) $(symfile_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) \ $(symfile_h) $(objfiles_h) $(gdbtypes_h) $(complaints_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) linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_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) \ $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_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_h) $(gdb_assert_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) \ $(symtab_h) $(symfile_h) $(objfiles_h) $(macrotab_h) $(gdb_assert_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-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) \ - $(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) \ $(expression_h) $(parser_defs_h) $(language_h) $(value_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) \ $(gdbtypes_h) $(expression_h) $(language_h) $(frame_h) $(gdbcmd_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) \ $(inferior_h) $(gdb_wait_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) \ $(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_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) \ $(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) \ @@ -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) \ $(language_h) $(demangle_h) $(inferior_h) $(linespec_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) \ $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_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) \ $(gdb_wait_h) $(gdb_regex_h) $(gdb_string_h) $(filenames_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 cli-decode.o: $(srcdir)/cli/cli-decode.c $(defs_h) $(symtab_h) \ $(gdb_regex_h) $(gdb_string_h) $(ui_out_h) $(cli_cmds_h) \ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 2998671bbf1..caa8f1c1106 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -41,6 +41,7 @@ #include "annotate.h" #include "symfile.h" #include "objfiles.h" +#include "source.h" #include "linespec.h" #include "completer.h" #include "gdb.h" @@ -4618,8 +4619,12 @@ parse_breakpoint_sals (char **address, current_source_symtab (which is decode_line_1's default). This should produce the results we want almost all of the time while leaving default_breakpoint_* alone. */ + + struct symtab_and_line cursal = + get_current_or_default_source_symtab_and_line (); + if (default_breakpoint_valid - && (!current_source_symtab + && (!cursal.symtab || (strchr ("+-", (*address)[0]) != NULL))) *sals = decode_line_1 (address, 1, default_breakpoint_symtab, default_breakpoint_line, addr_string); diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 799e1f464d6..0b5b857c98f 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -25,7 +25,12 @@ #include "gdb_wait.h" /* For shell escape implementation */ #include "gdb_regex.h" /* Used by apropos_command */ #include "gdb_string.h" +#include "linespec.h" +#include "expression.h" +#include "language.h" #include "filenames.h" /* for DOSish file names */ +#include "objfiles.h" +#include "source.h" #include "ui-out.h" @@ -51,7 +56,7 @@ extern void set_history (char *, int); extern void show_commands (char *, int); -/* Prototypes for local functions */ +/* Prototypes for local command functions */ static void complete_command (char *, int); @@ -79,7 +84,15 @@ static void make_command (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); + +/* Prototypes for local utility functions */ + +static void ambiguous_line_spec (struct symtabs_and_lines *); /* Limit the call depth of user-defined commands */ int max_user_call_depth; @@ -525,6 +538,281 @@ shell_escape (char *arg, int from_tty) #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 make_command (char *arg, int from_tty) { @@ -594,6 +882,21 @@ apropos_command (char *searchstr, int from_tty) 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 set_debug (char *arg, int from_tty) { @@ -812,6 +1115,43 @@ from the target.", &setlist), With no arguments, run an inferior shell."); 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 be a really useful feature. Unfortunately, the below wont do this. Instead it adds support for the form ``(gdb) ! ls'' diff --git a/gdb/linespec.c b/gdb/linespec.c index 8e51021fc44..d1bb4e3328f 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -26,6 +26,7 @@ #include "command.h" #include "symfile.h" #include "objfiles.h" +#include "source.h" #include "demangle.h" #include "value.h" #include "completer.h" @@ -545,8 +546,14 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, if (default_symtab == 0) { - default_symtab = current_source_symtab; - default_line = current_source_line; + /* Use whatever we have for the default source line. We don't use + 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 */ @@ -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. We must guarantee that this section of code is never executed 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) { - select_source_symtab (0); - default_symtab = current_source_symtab; - default_line = current_source_line; + struct symtab_and_line cursal = + get_current_or_default_source_symtab_and_line (); + + default_symtab = cursal.symtab; + default_line = cursal.line; } if (**argptr == '+') diff --git a/gdb/macroscope.c b/gdb/macroscope.c index 08ff6ebff58..083dc1f4e4a 100644 --- a/gdb/macroscope.c +++ b/gdb/macroscope.c @@ -23,6 +23,7 @@ #include "macroscope.h" #include "symtab.h" +#include "source.h" #include "target.h" #include "frame.h" #include "inferior.h" @@ -84,11 +85,14 @@ default_macro_scope (void) evaluator to evaluate their numeric arguments. If the current language is C, then that may call this function to 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 it can't decide which scope to macro-expand its argument in. */ - sal.symtab = current_source_symtab; - sal.line = current_source_line; + struct symtab_and_line cursal = + get_current_source_symtab_and_line (); + + sal.symtab = cursal.symtab; + sal.line = cursal.line; } return sal_macro_scope (sal); diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c index 00d679730cd..318a51d9def 100644 --- a/gdb/scm-lang.c +++ b/gdb/scm-lang.c @@ -29,6 +29,7 @@ #include "c-lang.h" #include "scm-lang.h" #include "scm-tags.h" +#include "source.h" #include "gdb_string.h" #include "gdbcore.h" @@ -133,9 +134,12 @@ scm_unpack (struct type *type, char *valaddr, enum type_code context) static int 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); if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0) return 1; diff --git a/gdb/source.c b/gdb/source.c index c7c1ce2f5d2..e5d99d3db09 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -79,8 +79,6 @@ static void forward_search_command (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 source_info (char *, int); @@ -94,11 +92,11 @@ char *source_path; /* Symtab of default file for listing lines of. */ -struct symtab *current_source_symtab; +static struct symtab *current_source_symtab; /* Default next line to list. */ -int current_source_line; +static int current_source_line; /* 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 @@ -123,6 +121,94 @@ static int first_line_listed; static struct symtab *last_source_visited = NULL; 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. @@ -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 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 @@ -1126,182 +1210,6 @@ ambiguous_line_spec (struct symtabs_and_lines *sals) printf_filtered ("file: \"%s\", line number: %d\n", 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. */ @@ -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 ("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_set_cmd ("listsize", class_support, var_uinteger, (char *) &lines_to_list, diff --git a/gdb/source.h b/gdb/source.h index 8dbf8517056..84cd0ff1a16 100644 --- a/gdb/source.h +++ b/gdb/source.h @@ -31,4 +31,36 @@ extern int open_source_file (struct symtab *s); lines. */ 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 diff --git a/gdb/stack.c b/gdb/stack.c index 30ebc09dee7..4f41531189a 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -33,6 +33,7 @@ #include "gdbcmd.h" #include "gdbcore.h" #include "target.h" +#include "source.h" #include "breakpoint.h" #include "demangle.h" #include "inferior.h" @@ -108,7 +109,6 @@ struct frame_info *parse_frame_specification (char *); static void frame_info (char *, int); 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. 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); source_print = (source == SRC_LINE || source == SRC_AND_LOC); + if (sal.symtab) - { - current_source_symtab = sal.symtab; - current_source_line = sal.line; - } + set_current_source_symtab_and_line (&sal); if (source_print && sal.symtab) { + struct symtab_and_line cursal; int done = 0; 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); } } - 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) diff --git a/gdb/symfile.c b/gdb/symfile.c index 3165f33b4b2..66bbf714984 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -31,6 +31,7 @@ #include "value.h" #include "symfile.h" #include "objfiles.h" +#include "source.h" #include "gdbcmd.h" #include "breakpoint.h" #include "language.h" @@ -2103,8 +2104,7 @@ clear_symtab_users (void) clear_internalvars (); breakpoint_re_set (); set_default_breakpoint (0, 0, 0, 0); - current_source_symtab = 0; - current_source_line = 0; + clear_current_source_symtab_and_line (); clear_pc_function_cache (); if (target_new_objfile_hook) target_new_objfile_hook (NULL); diff --git a/gdb/symtab.c b/gdb/symtab.c index c18625a57c3..a4322926e2f 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -38,6 +38,7 @@ #include "demangle.h" #include "inferior.h" #include "linespec.h" +#include "source.h" #include "filenames.h" /* for FILENAME_CMP */ #include "gdb_obstack.h" @@ -3967,11 +3968,19 @@ struct symtabs_and_lines decode_line_spec (char *string, int funfirstline) { struct symtabs_and_lines sals; + struct symtab_and_line cursal; + if (string == 0) 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, - current_source_symtab, current_source_line, + cursal.symtab, cursal.line, (char ***) NULL); + if (*string) error ("Junk at end of line specification: %s", string); return sals; diff --git a/gdb/symtab.h b/gdb/symtab.h index ba04a987ed7..a78607d584e 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1035,14 +1035,6 @@ struct partial_symtab /* 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. */ extern struct objfile *current_objfile;