* source.c: Make global variables current_source_symtab and
authorFernando Nasser <fnasser@redhat.com>
Fri, 20 Sep 2002 14:58:59 +0000 (14:58 +0000)
committerFernando Nasser <fnasser@redhat.com>
Fri, 20 Sep 2002 14:58:59 +0000 (14:58 +0000)
        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.

13 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/breakpoint.c
gdb/cli/cli-cmds.c
gdb/linespec.c
gdb/macroscope.c
gdb/scm-lang.c
gdb/source.c
gdb/source.h
gdb/stack.c
gdb/symfile.c
gdb/symtab.c
gdb/symtab.h

index ba66a1809136c5b310a9d0ab4d203ad536e6dc23..f3cc92b24f1fabc794f81bb0f4728dd9221ad82c 100644 (file)
@@ -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>
 
        * h8300-tdep.c (h8300_examine_prologue): Match saved regs location
index ce88570e092170e955425f66388026b6613a2b3e..ca17a2b07a2bc8d3fbf6c07ef2e32fca83f03fa4 100644 (file)
@@ -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) \
index 2998671bbf197ecf69700c09672d9ca01fba83cd..caa8f1c1106039f1ce2a12cc3c0d999487aa3876 100644 (file)
@@ -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);
index 799e1f464d6e116e55890b064df4b5ca8eac25e4..0b5b857c98fd6c01a8752f09e1c9ba1b5bc17edd 100644 (file)
 #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 *);
 \f
 /* 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);
 }
 \f
+/* 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''
index 8e51021fc44a071d58eb75973d93fb0c4481dae5..d1bb4e3328f419d9f572822e21a2b53a796ffdfe 100644 (file)
@@ -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 == '+')
index 08ff6ebff58d14c5bae88cc4b6617bbad435322f..083dc1f4e4a818e15b5730e6285abdeaf87a3299 100644 (file)
@@ -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);
index 00d679730cd95bc39067397a14429409642f218d..318a51d9def8984c9f52b39ba980c3882a241c76 100644 (file)
@@ -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;
index c7c1ce2f5d29e1723ba24c9893f72d911df31f31..e5d99d3db09b4b34ee2d0ffa783e555b21eaa3a6 100644 (file)
@@ -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;
 \f
+/* 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);
 }
 \f
-
-
 /* 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);
-}
 \f
 /* 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,
index 8dbf85170563ded2208652154a0101d26c309212..84cd0ff1a161b4da10f2acbd38ec8dae562a958d 100644 (file)
@@ -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
index 30ebc09dee70fba8ece1ae60770626d2f8e2d7f7..4f41531189a80210ed073ed23f99368cfaeb2533 100644 (file)
@@ -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)
index 3165f33b4b29a422d3f6ade94322fb48f108239e..66bbf7149844f448329f35dda9f008ad745038f6 100644 (file)
@@ -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);
index c18625a57c3b6073ecfc7cdd927fc73f4cdba7ff..a4322926e2f8d5e6030dc3cf4d41c671049f8f57 100644 (file)
@@ -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;
index ba04a987ed70f88e1a3d7bc959f4b1dad8e81638..a78607d584e6f866ecb79056e050c462f6d65939 100644 (file)
@@ -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;