This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: CLI clenup and edit command


To accommodate George Helffrich's edit command patch, I had to perform a clean-up in the CLI code removing some globals and providing the proper accessors. The edit commands goes into its proper place in cli land, and the similar list command is moved there as well.

Although it is all UI stuff, I did touch many files for which I am not the maintainer (being the CLI still scattered around). Please let me know if you don't like any of the changes (they are all "global->accessor" but I've updated some comments).

I don't know what to do with the TUI. It seems that it uses some of the globals and may be affected.

A last note w.r.t. the MI. Someone should create the MI commands equivalent to the CLI list and edit ones. The necessary info was left behind in libgdb (source.c in particular). Depending on how the MI command arguments are defined, it may be possible to share some of the code in list_command() (the one that transforms the arguments in the beginning and end lines to be printed). If that is the case, we can move the common code back to libgdb (source.c) and export it.

Regards to all.
Fernando


--
Fernando Nasser
Red Hat Canada Ltd. E-Mail: fnasser@redhat.com
2323 Yonge Street, Suite #300
Toronto, Ontario M4P 2C9
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.86
diff -c -p -r1.86 breakpoint.c
*** breakpoint.c	5 Sep 2002 01:28:14 -0000	1.86
--- breakpoint.c	13 Sep 2002 19:23:35 -0000
***************
*** 41,46 ****
--- 41,47 ----
  #include "annotate.h"
  #include "symfile.h"
  #include "objfiles.h"
+ #include "source.h"
  #include "linespec.h"
  #include "completer.h"
  #include "gdb.h"
*************** parse_breakpoint_sals (char **address,
*** 4618,4625 ****
           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.  */
        if (default_breakpoint_valid
! 	  && (!current_source_symtab
  	      || (strchr ("+-", (*address)[0]) != NULL)))
  	*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
  			       default_breakpoint_line, addr_string);
--- 4619,4630 ----
           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
! 	  && (!cursal.symtab
  	      || (strchr ("+-", (*address)[0]) != NULL)))
  	*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
  			       default_breakpoint_line, addr_string);
Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.21
diff -c -p -r1.21 linespec.c
*** linespec.c	11 May 2002 22:46:19 -0000	1.21
--- linespec.c	13 Sep 2002 19:23:36 -0000
***************
*** 26,31 ****
--- 26,32 ----
  #include "command.h"
  #include "symfile.h"
  #include "objfiles.h"
+ #include "source.h"
  #include "demangle.h"
  #include "value.h"
  #include "completer.h"
*************** decode_line_1 (char **argptr, int funfir
*** 545,552 ****
  
    if (default_symtab == 0)
      {
!       default_symtab = current_source_symtab;
!       default_line = current_source_line;
      }
  
    /* See if arg is *PC */
--- 546,559 ----
  
    if (default_symtab == 0)
      {
!       /* 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 */
*************** decode_line_1 (char **argptr, int funfir
*** 1020,1032 ****
        /* 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  */
  
        if (s == 0 && default_symtab == 0)
  	{
! 	  select_source_symtab (0);
! 	  default_symtab = current_source_symtab;
! 	  default_line = current_source_line;
  	}
  
        if (**argptr == '+')
--- 1027,1042 ----
        /* 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
! 	 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)
  	{
!           struct symtab_and_line cursal =
! 		  get_current_or_default_source_symtab_and_line ();
!       
!           default_symtab = cursal.symtab;
!           default_line = cursal.line;
  	}
  
        if (**argptr == '+')
Index: macroscope.c
===================================================================
RCS file: /cvs/src/src/gdb/macroscope.c,v
retrieving revision 1.3
diff -c -p -r1.3 macroscope.c
*** macroscope.c	30 May 2002 00:02:03 -0000	1.3
--- macroscope.c	13 Sep 2002 19:23:36 -0000
***************
*** 23,28 ****
--- 23,29 ----
  
  #include "macroscope.h"
  #include "symtab.h"
+ #include "source.h"
  #include "target.h"
  #include "frame.h"
  #include "inferior.h"
*************** default_macro_scope (void)
*** 84,94 ****
           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
           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;
      }
  
    return sal_macro_scope (sal);
--- 85,98 ----
           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 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.  */
!       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: scm-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/scm-lang.c,v
retrieving revision 1.9
diff -c -p -r1.9 scm-lang.c
*** scm-lang.c	23 Mar 2002 17:38:13 -0000	1.9
--- scm-lang.c	13 Sep 2002 19:23:36 -0000
***************
*** 29,34 ****
--- 29,35 ----
  #include "c-lang.h"
  #include "scm-lang.h"
  #include "scm-tags.h"
+ #include "source.h"
  #include "gdb_string.h"
  #include "gdbcore.h"
  
*************** scm_unpack (struct type *type, char *val
*** 133,141 ****
  static int
  in_eval_c (void)
  {
!   if (current_source_symtab && current_source_symtab->filename)
      {
!       char *filename = current_source_symtab->filename;
        int len = strlen (filename);
        if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0)
  	return 1;
--- 134,145 ----
  static int
  in_eval_c (void)
  {
!   struct symtab_and_line cursal =
! 	  get_current_or_default_source_symtab_and_line ();
!   
!   if (cursal.symtab && cursal.symtab->filename)
      {
!       char *filename = cursal.symtab->filename;
        int len = strlen (filename);
        if (len >= 6 && strcmp (filename + len - 6, "eval.c") == 0)
  	return 1;
Index: source.c
===================================================================
RCS file: /cvs/src/src/gdb/source.c,v
retrieving revision 1.29
diff -c -p -r1.29 source.c
*** source.c	11 Jun 2002 20:36:51 -0000	1.29
--- source.c	13 Sep 2002 19:23:37 -0000
*************** static void forward_search_command (char
*** 79,86 ****
  
  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);
--- 79,84 ----
*************** char *source_path;
*** 94,104 ****
  
  /* Symtab of default file for listing lines of.  */
  
! struct symtab *current_source_symtab;
  
  /* Default next line to list.  */
  
! 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
--- 92,102 ----
  
  /* Symtab of default file for listing lines of.  */
  
! static struct symtab *current_source_symtab;
  
  /* Default next line to list.  */
  
! 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
*************** static int first_line_listed;
*** 123,128 ****
--- 121,214 ----
  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.
  
*************** print_source_lines (struct symtab *s, in
*** 1110,1117 ****
    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
--- 1196,1201 ----
*************** ambiguous_line_spec (struct symtabs_and_
*** 1126,1307 ****
      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.  */
  
--- 1210,1215 ----
*************** The matching line number is also stored 
*** 1661,1689 ****
        add_com_alias ("/", "forward-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_set_cmd ("listsize", class_support, var_uinteger,
--- 1569,1574 ----
Index: source.h
===================================================================
RCS file: /cvs/src/src/gdb/source.h,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 source.h
*** source.h	22 Sep 1999 03:25:04 -0000	1.1.1.1
--- source.h	13 Sep 2002 19:23:37 -0000
*************** extern int open_source_file (struct symt
*** 31,34 ****
--- 31,66 ----
     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: stack.c
===================================================================
RCS file: /cvs/src/src/gdb/stack.c,v
retrieving revision 1.42
diff -c -p -r1.42 stack.c
*** stack.c	29 Aug 2002 19:59:35 -0000	1.42
--- stack.c	13 Sep 2002 19:23:37 -0000
***************
*** 33,38 ****
--- 33,39 ----
  #include "gdbcmd.h"
  #include "gdbcore.h"
  #include "target.h"
+ #include "source.h"
  #include "breakpoint.h"
  #include "demangle.h"
  #include "inferior.h"
*************** struct frame_info *parse_frame_specifica
*** 108,114 ****
  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.  */
--- 109,114 ----
*************** print_frame_info_base (struct frame_info
*** 398,411 ****
      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;
!     }
  
    if (source_print && sal.symtab)
      {
        int done = 0;
        int mid_statement = (source == SRC_LINE) && (fi->pc != sal.pc);
  
--- 398,410 ----
      print_frame (fi, level, source, args, sal);
  
    source_print = (source == SRC_LINE || source == SRC_AND_LOC);
+ 
    if (sal.symtab)
!     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);
  
*************** print_frame_info_base (struct frame_info
*** 435,441 ****
  	      print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
  	    }
  	}
!       current_source_line = max (sal.line - lines_to_list / 2, 1);
      }
  
    if (source != 0)
--- 434,442 ----
  	      print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
  	    }
  	}
!       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: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.65
diff -c -p -r1.65 symfile.c
*** symfile.c	1 Aug 2002 17:18:32 -0000	1.65
--- symfile.c	13 Sep 2002 19:23:37 -0000
***************
*** 31,36 ****
--- 31,37 ----
  #include "value.h"
  #include "symfile.h"
  #include "objfiles.h"
+ #include "source.h"
  #include "gdbcmd.h"
  #include "breakpoint.h"
  #include "language.h"
*************** clear_symtab_users (void)
*** 2118,2125 ****
    clear_internalvars ();
    breakpoint_re_set ();
    set_default_breakpoint (0, 0, 0, 0);
!   current_source_symtab = 0;
!   current_source_line = 0;
    clear_pc_function_cache ();
    if (target_new_objfile_hook)
      target_new_objfile_hook (NULL);
--- 2119,2125 ----
    clear_internalvars ();
    breakpoint_re_set ();
    set_default_breakpoint (0, 0, 0, 0);
!   clear_current_source_symtab_and_line ();
    clear_pc_function_cache ();
    if (target_new_objfile_hook)
      target_new_objfile_hook (NULL);
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.69
diff -c -p -r1.69 symtab.c
*** symtab.c	30 Aug 2002 03:24:00 -0000	1.69
--- symtab.c	13 Sep 2002 19:23:38 -0000
***************
*** 38,43 ****
--- 38,44 ----
  #include "demangle.h"
  #include "inferior.h"
  #include "linespec.h"
+ #include "source.h"
  #include "filenames.h"		/* for FILENAME_CMP */
  
  #include "gdb_obstack.h"
*************** struct symtabs_and_lines
*** 3967,3977 ****
  decode_line_spec (char *string, int funfirstline)
  {
    struct symtabs_and_lines sals;
    if (string == 0)
      error ("Empty line specification.");
    sals = decode_line_1 (&string, funfirstline,
! 			current_source_symtab, current_source_line,
  			(char ***) NULL);
    if (*string)
      error ("Junk at end of line specification: %s", string);
    return sals;
--- 3968,3986 ----
  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,
! 			cursal.symtab, cursal.line,
  			(char ***) NULL);
+ 
    if (*string)
      error ("Junk at end of line specification: %s", string);
    return sals;
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.39
diff -c -p -r1.39 symtab.h
*** symtab.h	12 Sep 2002 19:19:37 -0000	1.39
--- symtab.h	13 Sep 2002 19:23:38 -0000
*************** struct partial_symtab
*** 1035,1048 ****
  
  /* 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;
--- 1035,1040 ----
Index: cli/cli-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-cmds.c,v
retrieving revision 1.20
diff -c -p -r1.20 cli-cmds.c
*** cli/cli-cmds.c	30 Jul 2002 13:45:14 -0000	1.20
--- cli/cli-cmds.c	13 Sep 2002 19:23:38 -0000
***************
*** 25,31 ****
--- 25,36 ----
  #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"
  
*************** extern void set_history (char *, int);
*** 51,57 ****
  
  extern void show_commands (char *, int);
  
! /* Prototypes for local functions */
  
  static void complete_command (char *, int);
  
--- 56,62 ----
  
  extern void show_commands (char *, int);
  
! /* Prototypes for local command functions */
  
  static void complete_command (char *, int);
  
*************** static void make_command (char *, int);
*** 79,85 ****
--- 84,98 ----
  
  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;
*************** shell_escape (char *arg, int from_tty)
*** 526,531 ****
--- 539,819 ----
  }
  
  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)
  {
    char *p;
*************** apropos_command (char *searchstr, int fr
*** 594,599 ****
--- 882,902 ----
    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)
  {
*************** from the target.", &setlist),
*** 811,816 ****
--- 1114,1156 ----
  	       "Execute the rest of the line as a shell command.\n\
  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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]