* Makefile.in (eelf32ppc.c): Depend upon elf32.em, not generic.em.
[deliverable/binutils-gdb.git] / gdb / source.c
index ec569378306b3c6f70ef9427c0bd1eef119fa52c..e2ceb91cc328e5add4606977b3596fa79a2d4eea 100644 (file)
@@ -1,5 +1,6 @@
 /* List lines of source files for GDB, the GNU debugger.
 /* List lines of source files for GDB, the GNU debugger.
-   Copyright (C) 1986, 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
 
 This file is part of GDB.
 
@@ -26,50 +27,41 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "frame.h"
 
 #include <sys/types.h>
 #include "frame.h"
 
 #include <sys/types.h>
-#include <string.h>
+#include "gdb_string.h"
 #include <sys/param.h>
 #include <sys/param.h>
-#include <sys/stat.h>
+#include "gdb_stat.h"
 #include <fcntl.h>
 #include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #include "gdbcore.h"
 #include "regex.h"
 #include "symfile.h"
 #include "objfiles.h"
 #include "gdbcore.h"
 #include "regex.h"
 #include "symfile.h"
 #include "objfiles.h"
-
-#ifndef DIRNAME_SEPARATOR
-#define DIRNAME_SEPARATOR ':'
-#endif
+#include "annotate.h"
+#include "gdbtypes.h"
 
 /* Prototypes for local functions. */
 
 
 /* Prototypes for local functions. */
 
-static int
-open_source_file PARAMS ((struct symtab *));
+static int open_source_file PARAMS ((struct symtab *));
 
 
-static int
-get_filename_and_charpos PARAMS ((struct symtab *, char **));
+static int get_filename_and_charpos PARAMS ((struct symtab *, char **));
 
 
-static void
-reverse_search_command PARAMS ((char *, int));
+static void reverse_search_command PARAMS ((char *, int));
 
 
-static void
-forward_search_command PARAMS ((char *, int));
+static void forward_search_command PARAMS ((char *, int));
 
 
-static void
-line_info PARAMS ((char *, int));
+static void line_info PARAMS ((char *, int));
 
 
-static void
-list_command PARAMS ((char *, int));
+static void list_command PARAMS ((char *, int));
 
 
-static void
-ambiguous_line_spec PARAMS ((struct symtabs_and_lines *));
+static void ambiguous_line_spec PARAMS ((struct symtabs_and_lines *));
 
 
-static void
-source_info PARAMS ((char *, int));
+static void source_info PARAMS ((char *, int));
 
 
-static void
-show_directories PARAMS ((char *, int));
+static void show_directories PARAMS ((char *, int));
 
 
-static void
-find_source_lines PARAMS ((struct symtab *, int));
+static void find_source_lines PARAMS ((struct symtab *, int));
 
 /* If we use this declaration, it breaks because of fucking ANSI "const" stuff
    on some systems.  We just have to not declare it at all, have it default
 
 /* If we use this declaration, it breaks because of fucking ANSI "const" stuff
    on some systems.  We just have to not declare it at all, have it default
@@ -206,10 +198,9 @@ show_directories (ignore, from_tty)
   puts_filtered ("\n");
 }
 
   puts_filtered ("\n");
 }
 
-/* Forget what we learned about line positions in source files,
-   and which directories contain them;
-   must check again now since files may be found in
-   a different directory now.  */
+/* Forget what we learned about line positions in source files, and
+   which directories contain them; must check again now since files
+   may be found in a different directory now.  */
 
 void
 forget_cached_source_info ()
 
 void
 forget_cached_source_info ()
@@ -256,7 +247,7 @@ directory_command (dirname, from_tty)
   /* FIXME, this goes to "delete dir"... */
   if (dirname == 0)
     {
   /* FIXME, this goes to "delete dir"... */
   if (dirname == 0)
     {
-      if (query ("Reinitialize source path to empty? ", ""))
+      if (query ("Reinitialize source path to empty? "))
        {
          free (source_path);
          init_source_path ();
        {
          free (source_path);
          init_source_path ();
@@ -292,27 +283,30 @@ mod_path (dirname, which_path)
       struct stat st;
 
       {
       struct stat st;
 
       {
-       char *colon = strchr (name, DIRNAME_SEPARATOR);
+       char *separator = strchr (name, DIRNAME_SEPARATOR);
        char *space = strchr (name, ' ');
        char *tab = strchr (name, '\t');
        char *space = strchr (name, ' ');
        char *tab = strchr (name, '\t');
-       if (colon == 0 && space == 0 && tab ==  0)
+
+       if (separator == 0 && space == 0 && tab ==  0)
          p = dirname = name + strlen (name);
        else
          {
            p = 0;
          p = dirname = name + strlen (name);
        else
          {
            p = 0;
-           if (colon != 0 && (p == 0 || colon < p))
-             p = colon;
+           if (separator != 0 && (p == 0 || separator < p))
+             p = separator;
            if (space != 0 && (p == 0 || space < p))
              p = space;
            if (tab != 0 && (p == 0 || tab < p))
              p = tab;
            dirname = p + 1;
            if (space != 0 && (p == 0 || space < p))
              p = space;
            if (tab != 0 && (p == 0 || tab < p))
              p = tab;
            dirname = p + 1;
-           while (*dirname == DIRNAME_SEPARATOR || *dirname == ' ' || *dirname == '\t')
+           while (*dirname == DIRNAME_SEPARATOR
+                  || *dirname == ' '
+                  || *dirname == '\t')
              ++dirname;
          }
       }
 
              ++dirname;
          }
       }
 
-      if (p[-1] == '/')
+      if (SLASH_P (p[-1]))
        /* Sigh. "foo/" => "foo" */
        --p;
       *p = '\0';
        /* Sigh. "foo/" => "foo" */
        --p;
       *p = '\0';
@@ -325,7 +319,7 @@ mod_path (dirname, which_path)
              name = current_directory;
              goto append;
            }
              name = current_directory;
              goto append;
            }
-         else if (p[-2] == '/')
+         else if (SLASH_P (p[-2]))
            {
              if (p - name == 2)
                {
            {
              if (p - name == 2)
                {
@@ -347,8 +341,8 @@ mod_path (dirname, which_path)
 
       if (name[0] == '~')
        name = tilde_expand (name);
 
       if (name[0] == '~')
        name = tilde_expand (name);
-      else if (name[0] != '/' && name[0] != '$')
-       name = concat (current_directory, "/", name, NULL);
+      else if (!SLASH_P (name[0]) && name[0] != '$') 
+         name = concat (current_directory, SLASH_STRING, name, NULL);
       else
        name = savestring (name, p - name);
       make_cleanup (free, name);
       else
        name = savestring (name, p - name);
       make_cleanup (free, name);
@@ -386,7 +380,7 @@ mod_path (dirname, which_path)
              {
                /* Found it in the search path, remove old copy */
                if (p > *which_path)
              {
                /* Found it in the search path, remove old copy */
                if (p > *which_path)
-                 p--;                  /* Back over leading colon */
+                 p--;                  /* Back over leading separator */
                if (prefix > p - *which_path)
                  goto skip_dup;        /* Same dir twice in one cmd */
                strcpy (p, &p[len+1]);  /* Copy from next \0 or  : */
                if (prefix > p - *which_path)
                  goto skip_dup;        /* Same dir twice in one cmd */
                strcpy (p, &p[len+1]);  /* Copy from next \0 or  : */
@@ -495,16 +489,20 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
   if (!path)
     path = ".";
 
   if (!path)
     path = ".";
 
-  if (try_cwd_first || string[0] == '/')
+  if (try_cwd_first || SLASH_P (string[0]))
     {
     {
+      int i;
       filename = string;
       fd = open (filename, mode, prot);
       filename = string;
       fd = open (filename, mode, prot);
-      if (fd >= 0 || string[0] == '/' || strchr (string, '/'))
+      if (fd >= 0)
+       goto done;
+      for (i = 0; string[i]; i++)
+       if (SLASH_P(string[0]))
        goto done;
     }
 
   /* ./foo => foo */
        goto done;
     }
 
   /* ./foo => foo */
-  while (string[0] == '.' && string[1] == '/')
+  while (string[0] == '.' && SLASH_P (string[1]))
     string += 2;
 
   alloclen = strlen (path) + strlen (string) + 2;
     string += 2;
 
   alloclen = strlen (path) + strlen (string) + 2;
@@ -538,10 +536,10 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
       }
 
       /* Remove trailing slashes */
       }
 
       /* Remove trailing slashes */
-      while (len > 0 && filename[len-1] == '/')
+      while (len > 0 && SLASH_P (filename[len-1]))
        filename[--len] = 0;
 
        filename[--len] = 0;
 
-      strcat (filename+len, "/");
+      strcat (filename+len, SLASH_STRING);
       strcat (filename, string);
 
       fd = open (filename, mode);
       strcat (filename, string);
 
       fd = open (filename, mode);
@@ -550,24 +548,44 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
 
  done:
   if (filename_opened)
 
  done:
   if (filename_opened)
-    if (fd < 0)
-      *filename_opened = (char *) 0;
-    else if (filename[0] == '/')
-      *filename_opened = savestring (filename, strlen (filename));
-    else
+    {
+      if (fd < 0)
+       *filename_opened = (char *) 0;
+      else if (ROOTED_P (filename))
+       *filename_opened = savestring (filename, strlen (filename));
+      else
+       {
+         /* Beware the // my son, the Emacs barfs, the botch that catch... */
+         
+         *filename_opened = concat (current_directory, 
+                                    SLASH_CHAR
+                                    == current_directory[strlen(current_directory)-1] 
+                                    ? "": SLASH_STRING,
+                                    filename, NULL);
+        }
+    }
+#ifdef MPW
+  /* This is a debugging hack that can go away when all combinations
+     of Mac and Unix names are handled reasonably.  */
+  {
+    extern int debug_openp;
+
+    if (debug_openp)
       {
       {
-       /* Beware the // my son, the Emacs barfs, the botch that catch... */
-          
-       *filename_opened = concat (current_directory, 
-          '/' == current_directory[strlen(current_directory)-1]? "": "/",
-                                  filename, NULL);
+       printf("openp on %s, path %s mode %d prot %d\n  returned %d",
+              string, path, mode, prot, fd);
+       if (*filename_opened)
+         printf(" (filename is %s)", *filename_opened);
+       printf("\n");
       }
       }
+  }
+#endif /* MPW */
 
   return fd;
 }
 
 
   return fd;
 }
 
-/* Open a source file given a symtab S.  Returns a file descriptor
-   or negative number for error.  */
+/* Open a source file given a symtab S.  Returns a file descriptor or
+   negative number for error.  */
 
 static int
 open_source_file (s)
 
 static int
 open_source_file (s)
@@ -597,16 +615,17 @@ open_source_file (s)
         which produces a "required warning" when assigned to a nonconst. */
       p = (char *)strstr (source_path, "$cdir");
       if (p && (p == path || p[-1] == DIRNAME_SEPARATOR)
         which produces a "required warning" when assigned to a nonconst. */
       p = (char *)strstr (source_path, "$cdir");
       if (p && (p == path || p[-1] == DIRNAME_SEPARATOR)
-           && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0')) {
-       int len;
-
-       path = (char *)
-              alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
-       len = p - source_path;
-       strncpy (path, source_path, len);               /* Before $cdir */
-       strcpy (path + len, s->dirname);                /* new stuff */
-       strcat (path + len, source_path + len + cdir_len); /* After $cdir */
-      }
+           && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0'))
+       {
+         int len;
+
+         path = (char *)
+           alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
+         len = p - source_path;
+         strncpy (path, source_path, len);             /* Before $cdir */
+         strcpy (path + len, s->dirname);              /* new stuff */
+         strcat (path + len, source_path + len + cdir_len); /* After $cdir */
+       }
     }
 
   result = openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname);
     }
 
   result = openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname);
@@ -617,6 +636,23 @@ open_source_file (s)
       if (p != s->filename)
        result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
     }
       if (p != s->filename)
        result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
     }
+#ifdef MPW
+  if (result < 0)
+    {
+      /* Didn't work.  Try using just the MPW basename. */
+      p = (char *) mpw_basename (s->filename);
+      if (p != s->filename)
+       result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
+    }
+  if (result < 0)
+    {
+      /* Didn't work.  Try using the mixed Unix/MPW basename. */
+      p = (char *) mpw_mixed_basename (s->filename);
+      if (p != s->filename)
+       result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
+    }
+#endif /* MPW */
+
   if (result >= 0)
     {
       fullname = s->fullname;
   if (result >= 0)
     {
       fullname = s->fullname;
@@ -626,6 +662,35 @@ open_source_file (s)
   return result;
 }
 
   return result;
 }
 
+/* Return the path to the source file associated with symtab.  Returns NULL
+   if no symtab.  */
+
+char *
+symtab_to_filename (s)
+     struct symtab *s;
+{
+  int fd;
+
+  if (!s)
+    return NULL;
+
+  /* If we've seen the file before, just return fullname. */
+
+  if (s->fullname)
+    return s->fullname;
+
+  /* Try opening the file to setup fullname */
+
+  fd = open_source_file (s);
+  if (fd < 0)
+    return s->filename;                /* File not found.  Just use short name */
+
+  /* Found the file.  Cleanup and return the full name */
+
+  close (fd);
+  return s->fullname;
+}
+
 \f
 /* Create and initialize the table S->line_charpos that records
    the positions of the lines in the source file, which is assumed
 \f
 /* Create and initialize the table S->line_charpos that records
    the positions of the lines in the source file, which is assumed
@@ -644,75 +709,80 @@ find_source_lines (s, desc)
   int *line_charpos;
   long exec_mtime;
   int size;
   int *line_charpos;
   long exec_mtime;
   int size;
-#ifdef LSEEK_NOT_LINEAR
-  char c;
-#endif
 
   line_charpos = (int *) xmmalloc (s -> objfile -> md,
                                   lines_allocated * sizeof (int));
   if (fstat (desc, &st) < 0)
 
   line_charpos = (int *) xmmalloc (s -> objfile -> md,
                                   lines_allocated * sizeof (int));
   if (fstat (desc, &st) < 0)
-   perror_with_name (s->filename);
+    perror_with_name (s->filename);
 
 
-  if (exec_bfd) {
-    exec_mtime = bfd_get_mtime(exec_bfd);
-    if (exec_mtime && exec_mtime < st.st_mtime)
-     printf_filtered ("Source file is more recent than executable.\n");
-  }
+  if (exec_bfd)
+    {
+      exec_mtime = bfd_get_mtime(exec_bfd);
+      if (exec_mtime && exec_mtime < st.st_mtime)
+       printf_filtered ("Source file is more recent than executable.\n");
+    }
 
 #ifdef LSEEK_NOT_LINEAR
 
 #ifdef LSEEK_NOT_LINEAR
-  /* Have to read it byte by byte to find out where the chars live */
-
-   line_charpos[0] = tell(desc);
-   nlines = 1;
-   while (myread(desc, &c, 1)>0) 
-   {
-     if (c == '\n') 
-     {
-       if (nlines == lines_allocated) 
-       {
-        lines_allocated *= 2;
-        line_charpos =
-         (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
-                            sizeof (int) * lines_allocated);
-       }
-       line_charpos[nlines++] = tell(desc);
-     }
-   }
-
-#else
-  /* st_size might be a large type, but we only support source files whose 
-     size fits in an int.  FIXME. */
-  size = (int) st.st_size;
-
-#ifdef BROKEN_LARGE_ALLOCA
-  data = (char *) xmalloc (size);
-  make_cleanup (free, data);
-#else
-  data = (char *) alloca (size);
-#endif
-  if (myread (desc, data, size) < 0)
-   perror_with_name (s->filename);
-  end = data + size;
-  p = data;
-  line_charpos[0] = 0;
-  nlines = 1;
-  while (p != end)
   {
   {
-    if (*p++ == '\n'
-       /* A newline at the end does not start a new line.  */
-       && p != end)
-    {
-      if (nlines == lines_allocated)
+    char c;
+
+    /* Have to read it byte by byte to find out where the chars live */
+
+    line_charpos[0] = tell(desc);
+    nlines = 1;
+    while (myread(desc, &c, 1)>0) 
       {
       {
-       lines_allocated *= 2;
-       line_charpos =
-        (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
-                           sizeof (int) * lines_allocated);
+       if (c == '\n') 
+         {
+           if (nlines == lines_allocated) 
+             {
+               lines_allocated *= 2;
+               line_charpos =
+                 (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
+                                    sizeof (int) * lines_allocated);
+             }
+           line_charpos[nlines++] = tell(desc);
+         }
       }
       }
-      line_charpos[nlines++] = p - data;
-    }
   }
   }
-#endif
+#else /* lseek linear.  */
+  {
+    struct cleanup *old_cleanups;
+
+    /* st_size might be a large type, but we only support source files whose 
+       size fits in an int.  */
+    size = (int) st.st_size;
+
+    /* Use malloc, not alloca, because this may be pretty large, and we may
+       run into various kinds of limits on stack size.  */
+    data = (char *) xmalloc (size);
+    old_cleanups = make_cleanup (free, data);
+
+    if (myread (desc, data, size) < 0)
+      perror_with_name (s->filename);
+    end = data + size;
+    p = data;
+    line_charpos[0] = 0;
+    nlines = 1;
+    while (p != end)
+      {
+       if (*p++ == '\n'
+           /* A newline at the end does not start a new line.  */
+           && p != end)
+         {
+           if (nlines == lines_allocated)
+             {
+               lines_allocated *= 2;
+               line_charpos =
+                 (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
+                                    sizeof (int) * lines_allocated);
+             }
+           line_charpos[nlines++] = p - data;
+         }
+      }
+    do_cleanups (old_cleanups);
+  }
+#endif /* lseek linear.  */
   s->nlines = nlines;
   s->line_charpos =
    (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
   s->nlines = nlines;
   s->line_charpos =
    (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
@@ -813,12 +883,9 @@ identify_source_line (s, line, mid_statement, pc)
   if (line > s->nlines)
     /* Don't index off the end of the line_charpos array.  */
     return 0;
   if (line > s->nlines)
     /* Don't index off the end of the line_charpos array.  */
     return 0;
-  /* FIXME-32x64: Need a version of print_address_numeric which does
-     not pass use_local to print_longest.  */
-  printf_unfiltered ("\032\032%s:%d:%d:%s:0x%lx\n", s->fullname,
-         line, s->line_charpos[line - 1],
-         mid_statement ? "middle" : "beg",
-         (unsigned long) pc);
+  annotate_source (s->fullname, line, s->line_charpos[line - 1],
+                  mid_statement, pc);
+
   current_source_line = line;
   first_line_listed = line;
   last_line_listed = line;
   current_source_line = line;
   first_line_listed = line;
   last_line_listed = line;
@@ -897,13 +964,11 @@ print_source_lines (s, line, stopline, noerror)
 \f
 
 
 \f
 
 
-/* 
-  C++
-  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.
-  */
+/* 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 (sals)
      struct symtabs_and_lines *sals;
 static void
 ambiguous_line_spec (sals)
      struct symtabs_and_lines *sals;
@@ -915,7 +980,6 @@ ambiguous_line_spec (sals)
                    sals->sals[i].symtab->filename, sals->sals[i].line);
 }
 
                    sals->sals[i].symtab->filename, sals->sals[i].line);
 }
 
-
 static void
 list_command (arg, from_tty)
      char *arg;
 static void
 list_command (arg, from_tty)
      char *arg;
@@ -1042,14 +1106,14 @@ list_command (arg, from_tty)
       sym = find_pc_function (sal.pc);
       if (sym)
        {
       sym = find_pc_function (sal.pc);
       if (sym)
        {
-         print_address_numeric (sal.pc, gdb_stdout);
+         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
        {
          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, gdb_stdout);
+         print_address_numeric (sal.pc, 1, gdb_stdout);
          printf_filtered (" is at %s:%d.\n",
                           sal.symtab->filename, sal.line);
        }
          printf_filtered (" is at %s:%d.\n",
                           sal.symtab->filename, sal.line);
        }
@@ -1104,6 +1168,7 @@ line_info (arg, from_tty)
     {
       sal.symtab = current_source_symtab;
       sal.line = last_line_listed;
     {
       sal.symtab = current_source_symtab;
       sal.line = last_line_listed;
+      sal.pc = 0;
       sals.nelts = 1;
       sals.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
       sals.nelts = 1;
       sals.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
@@ -1172,7 +1237,7 @@ line_info (arg, from_tty)
 
          /* If this is the only line, show the source code.  If it could
             not find the file, don't do anything special.  */
 
          /* If this is the only line, show the source code.  If it could
             not find the file, don't do anything special.  */
-         if (frame_file_full_name && sals.nelts == 1)
+         if (annotation_level && sals.nelts == 1)
            identify_source_line (sal.symtab, sal.line, 0, start_pc);
        }
       else
            identify_source_line (sal.symtab, sal.line, 0, start_pc);
        }
       else
@@ -1230,15 +1295,26 @@ forward_search_command (regex, from_tty)
   stream = fdopen (desc, FOPEN_RT);
   clearerr (stream);
   while (1) {
   stream = fdopen (desc, FOPEN_RT);
   clearerr (stream);
   while (1) {
-/* FIXME!!!  We walk right off the end of buf if we get a long line!!! */
-    char buf[4096];            /* Should be reasonable??? */
-    register char *p = buf;
+    static char *buf = NULL;
+    register char *p;
+    int cursize, newsize;
+
+    cursize = 256;
+    buf = xmalloc (cursize);
+    p = buf;
 
     c = getc (stream);
     if (c == EOF)
       break;
     do {
       *p++ = c;
 
     c = getc (stream);
     if (c == EOF)
       break;
     do {
       *p++ = c;
+      if (p - buf == cursize)
+       {
+         newsize = cursize + cursize / 2;
+         buf = xrealloc (buf, newsize);
+         p = buf + cursize;
+         cursize = newsize;
+       }
     } while (c != '\n' && (c = getc (stream)) >= 0);
 
     /* we now have a source line in buf, null terminate and match */
     } while (c != '\n' && (c = getc (stream)) >= 0);
 
     /* we now have a source line in buf, null terminate and match */
@@ -1247,8 +1323,10 @@ forward_search_command (regex, from_tty)
       {
        /* Match! */
        fclose (stream);
       {
        /* Match! */
        fclose (stream);
-       print_source_lines (current_source_symtab,
-                          line, line+1, 0);
+       print_source_lines (current_source_symtab, line, line+1, 0);
+       set_internalvar (lookup_internalvar ("_"),
+                        value_from_longest (builtin_type_int,
+                                            (LONGEST) line));
        current_source_line = max (line - lines_to_list / 2, 1);
        return;
       }
        current_source_line = max (line - lines_to_list / 2, 1);
        return;
       }
@@ -1322,6 +1400,9 @@ reverse_search_command (regex, from_tty)
          fclose (stream);
          print_source_lines (current_source_symtab,
                              line, line+1, 0);
          fclose (stream);
          print_source_lines (current_source_symtab,
                              line, line+1, 0);
+         set_internalvar (lookup_internalvar ("_"),
+                          value_from_longest (builtin_type_int,
+                                              (LONGEST) line));
          current_source_line = max (line - lines_to_list / 2, 1);
          return;
        }
          current_source_line = max (line - lines_to_list / 2, 1);
          return;
        }
@@ -1370,37 +1451,42 @@ $cdir in the path means the compilation directory of the source file.",
            "Information about the current source file.");
 
   add_info ("line", line_info,
            "Information about the current source file.");
 
   add_info ("line", line_info,
-           "Core addresses of the code for a source line.\n\
+           concat ("Core addresses of the code for a source line.\n\
 Line can be specified as\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\
 Line can be specified as\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\
+", "\
 Default is to describe the last source line that was listed.\n\n\
 This sets the default address for \"x\" to the line's first instruction\n\
 so that \"x/i\" suffices to start examining the machine code.\n\
 Default is to describe the last source line that was listed.\n\n\
 This sets the default address for \"x\" to the line's first instruction\n\
 so that \"x/i\" suffices to start examining the machine code.\n\
-The address is also stored as the value of \"$_\".");
+The address is also stored as the value of \"$_\".", NULL));
 
   add_com ("forward-search", class_files, forward_search_command,
 
   add_com ("forward-search", class_files, forward_search_command,
-          "Search for regular expression (see regex(3)) from last line listed.");
+          "Search for regular expression (see regex(3)) from last line listed.\n\
+The matching line number is also stored as the value of \"$_\".");
   add_com_alias ("search", "forward-search", class_files, 0);
 
   add_com ("reverse-search", class_files, reverse_search_command,
   add_com_alias ("search", "forward-search", class_files, 0);
 
   add_com ("reverse-search", class_files, reverse_search_command,
-          "Search backward for regular expression (see regex(3)) from last line listed.");
+          "Search backward for regular expression (see regex(3)) from last line listed.\n\
+The matching line number is also stored as the value of \"$_\".");
 
   add_com ("list", class_files, list_command,
 
   add_com ("list", class_files, list_command,
-          "List specified function or line.\n\
+          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\
 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\
 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.");
+With two args if one is empty it stands for ten lines away from the other arg.", NULL));
+
   add_com_alias ("l", "list", class_files, 1);
 
   add_show_from_set
   add_com_alias ("l", "list", class_files, 1);
 
   add_show_from_set
This page took 0.03201 seconds and 4 git commands to generate.