gdb/
[deliverable/binutils-gdb.git] / gdb / source.c
index 3bff89bd8475072a180441643d22911865bc287a..b154dfe61779a9d3543b13eb45e93b8fc5cf9163 100644 (file)
@@ -1,7 +1,5 @@
 /* List lines of source files for GDB, the GNU debugger.
-   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
-   2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1986-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -111,6 +109,27 @@ show_lines_to_list (struct ui_file *file, int from_tty,
                    value);
 }
 
+/* Possible values of 'set filename-display'.  */
+static const char filename_display_basename[] = "basename";
+static const char filename_display_relative[] = "relative";
+static const char filename_display_absolute[] = "absolute";
+
+static const char *const filename_display_kind_names[] = {
+  filename_display_basename,
+  filename_display_relative,
+  filename_display_absolute,
+  NULL
+};
+
+static const char *filename_display_string = filename_display_relative;
+
+static void
+show_filename_display_string (struct ui_file *file, int from_tty,
+                             struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Filenames are displayed as \"%s\".\n"), value);
+}
 /* Line number of last line printed.  Default for various commands.
    current_source_line is usually, but not always, the same as this.  */
 
@@ -245,7 +264,8 @@ select_source_symtab (struct symtab *s)
      if one exists.  */
   if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0))
     {
-      sals = decode_line_spec (main_name (), DECODE_LINE_FUNFIRSTLINE);
+      sals = decode_line_with_current_source (main_name (),
+                                             DECODE_LINE_FUNFIRSTLINE);
       sal = sals.sals[0];
       xfree (sals.sals);
       current_source_pspace = sal.pspace;
@@ -385,14 +405,14 @@ init_source_path (void)
 {
   char buf[20];
 
-  sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR);
+  xsnprintf (buf, sizeof (buf), "$cdir%c$cwd", DIRNAME_SEPARATOR);
   source_path = xstrdup (buf);
   forget_cached_source_info ();
 }
 
 /* Add zero or more directories to the front of the source path.  */
 
-void
+static void
 directory_command (char *dirname, int from_tty)
 {
   dont_repeat ();
@@ -442,62 +462,40 @@ add_path (char *dirname, char **which_path, int parse_separators)
 {
   char *old = *which_path;
   int prefix = 0;
-  char **argv = NULL;
-  char *arg;
-  int argv_index = 0;
+  VEC (char_ptr) *dir_vec = NULL;
+  struct cleanup *back_to;
+  int ix;
+  char *name;
 
   if (dirname == 0)
     return;
 
   if (parse_separators)
     {
+      char **argv, **argvp;
+
       /* This will properly parse the space and tab separators
-        and any quotes that may exist.  DIRNAME_SEPARATOR will
-        be dealt with later.  */
+        and any quotes that may exist.  */
       argv = gdb_buildargv (dirname);
-      make_cleanup_freeargv (argv);
 
-      arg = argv[0];
+      for (argvp = argv; *argvp; argvp++)
+       dirnames_to_char_ptr_vec_append (&dir_vec, *argvp);
+
+      freeargv (argv);
     }
   else
-    {
-      arg = xstrdup (dirname);
-      make_cleanup (xfree, arg);
-    }
+    VEC_safe_push (char_ptr, dir_vec, xstrdup (dirname));
+  back_to = make_cleanup_free_char_ptr_vec (dir_vec);
 
-  do
+  for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, name); ++ix)
     {
-      char *name = arg;
       char *p;
       struct stat st;
 
-      {
-       char *separator = NULL;
-
-       /* Spaces and tabs will have been removed by buildargv().
-          The directories will there be split into a list but
-          each entry may still contain DIRNAME_SEPARATOR.  */
-       if (parse_separators)
-         separator = strchr (name, DIRNAME_SEPARATOR);
-
-       if (separator == 0)
-         p = arg = name + strlen (name);
-       else
-         {
-           p = separator;
-           arg = p + 1;
-           while (*arg == DIRNAME_SEPARATOR)
-             ++arg;
-         }
-
-       /* If there are no more directories in this argument then start
-          on the next argument next time round the loop (if any).  */
-       if (*arg == '\0')
-         arg = parse_separators ? argv[++argv_index] : NULL;
-      }
-
-      /* name is the start of the directory.
-        p is the separator (or null) following the end.  */
+      /* Spaces and tabs will have been removed by buildargv().
+         NAME is the start of the directory.
+        P is the '\0' following the end.  */
+      p = name + strlen (name);
 
       while (!(IS_DIR_SEPARATOR (*name) && p <= name + 1)      /* "/" */
 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
@@ -575,65 +573,54 @@ add_path (char *dirname, char **which_path, int parse_separators)
     append:
       {
        unsigned int len = strlen (name);
+       char tinybuf[2];
 
        p = *which_path;
-       while (1)
+       /* FIXME: we should use realpath() or its work-alike
+          before comparing.  Then all the code above which
+          removes excess slashes and dots could simply go away.  */
+       if (!filename_cmp (p, name))
          {
-           /* FIXME: we should use realpath() or its work-alike
-              before comparing.  Then all the code above which
-              removes excess slashes and dots could simply go away.  */
-           if (!filename_ncmp (p, name, len)
-               && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR))
-             {
-               /* Found it in the search path, remove old copy.  */
-               if (p > *which_path)
-                 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  : */
-             }
-           p = strchr (p, DIRNAME_SEPARATOR);
-           if (p != 0)
-             ++p;
-           else
-             break;
+           /* Found it in the search path, remove old copy.  */
+           if (p > *which_path)
+             p--;              /* Back over leading separator.  */
+           if (prefix > p - *which_path)
+             goto skip_dup;    /* Same dir twice in one cmd.  */
+           memmove (p, &p[len + 1], strlen (&p[len + 1]) + 1); /* Copy from next \0 or  : */
          }
-       if (p == 0)
-         {
-           char tinybuf[2];
 
-           tinybuf[0] = DIRNAME_SEPARATOR;
-           tinybuf[1] = '\0';
+       tinybuf[0] = DIRNAME_SEPARATOR;
+       tinybuf[1] = '\0';
 
-           /* If we have already tacked on a name(s) in this command,
-              be sure they stay on the front as we tack on some
-              more.  */
-           if (prefix)
-             {
-               char *temp, c;
-
-               c = old[prefix];
-               old[prefix] = '\0';
-               temp = concat (old, tinybuf, name, (char *)NULL);
-               old[prefix] = c;
-               *which_path = concat (temp, "", &old[prefix], (char *) NULL);
-               prefix = strlen (temp);
-               xfree (temp);
-             }
-           else
-             {
-               *which_path = concat (name, (old[0] ? tinybuf : old),
-                                     old, (char *)NULL);
-               prefix = strlen (name);
-             }
-           xfree (old);
-           old = *which_path;
+       /* If we have already tacked on a name(s) in this command,
+          be sure they stay on the front as we tack on some
+          more.  */
+       if (prefix)
+         {
+           char *temp, c;
+
+           c = old[prefix];
+           old[prefix] = '\0';
+           temp = concat (old, tinybuf, name, (char *)NULL);
+           old[prefix] = c;
+           *which_path = concat (temp, "", &old[prefix], (char *) NULL);
+           prefix = strlen (temp);
+           xfree (temp);
          }
+       else
+         {
+           *which_path = concat (name, (old[0] ? tinybuf : old),
+                                 old, (char *)NULL);
+           prefix = strlen (name);
+         }
+       xfree (old);
+       old = *which_path;
       }
     skip_dup:
       ;
     }
-  while (arg != NULL);
+
+  do_cleanups (back_to);
 }
 
 
@@ -714,10 +701,11 @@ openp (const char *path, int opts, const char *string,
 {
   int fd;
   char *filename;
-  const char *p;
-  const char *p1;
-  int len;
   int alloclen;
+  VEC (char_ptr) *dir_vec;
+  struct cleanup *back_to;
+  int ix;
+  char *dir;
 
   /* The open syscall MODE parameter is not specified.  */
   gdb_assert ((mode & O_CREAT) == 0);
@@ -780,16 +768,15 @@ openp (const char *path, int opts, const char *string,
   alloclen = strlen (path) + strlen (string) + 2;
   filename = alloca (alloclen);
   fd = -1;
-  for (p = path; p; p = p1 ? p1 + 1 : 0)
+
+  dir_vec = dirnames_to_char_ptr_vec (path);
+  back_to = make_cleanup_free_char_ptr_vec (dir_vec);
+
+  for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, dir); ++ix)
     {
-      p1 = strchr (p, DIRNAME_SEPARATOR);
-      if (p1)
-       len = p1 - p;
-      else
-       len = strlen (p);
+      size_t len = strlen (dir);
 
-      if (len == 4 && p[0] == '$' && p[1] == 'c'
-         && p[2] == 'w' && p[3] == 'd')
+      if (strcmp (dir, "$cwd") == 0)
        {
          /* Name is $cwd -- insert current directory name instead.  */
          int newlen;
@@ -804,11 +791,29 @@ openp (const char *path, int opts, const char *string,
            }
          strcpy (filename, current_directory);
        }
+      else if (strchr(dir, '~'))
+       {
+        /* See whether we need to expand the tilde.  */
+         int newlen;
+         char *tilde_expanded;
+
+         tilde_expanded  = tilde_expand (dir);
+
+         /* First, realloc the filename buffer if too short.  */
+         len = strlen (tilde_expanded);
+         newlen = len + strlen (string) + 2;
+         if (newlen > alloclen)
+           {
+             alloclen = newlen;
+             filename = alloca (alloclen);
+           }
+         strcpy (filename, tilde_expanded);
+         xfree (tilde_expanded);
+       }
       else
        {
          /* Normal file name in path -- just use it.  */
-         strncpy (filename, p, len);
-         filename[len] = 0;
+         strcpy (filename, dir);
 
          /* Don't search $cdir.  It's also a magic path like $cwd, but we
             don't have enough information to expand it.  The user *could*
@@ -817,7 +822,7 @@ openp (const char *path, int opts, const char *string,
             contexts.  If the user really has '$cdir' one can use './$cdir'.
             We can get $cdir when loading scripts.  When loading source files
             $cdir must have already been expanded to the correct value.  */
-         if (strcmp (filename, "$cdir") == 0)
+         if (strcmp (dir, "$cdir") == 0)
            continue;
        }
 
@@ -836,18 +841,16 @@ openp (const char *path, int opts, const char *string,
        }
     }
 
+  do_cleanups (back_to);
+
 done:
   if (filename_opened)
     {
-      /* If a file was opened, canonicalize its filename.  Use xfullpath
-         rather than gdb_realpath to avoid resolving the basename part
-         of filenames when the associated file is a symbolic link.  This
-         fixes a potential inconsistency between the filenames known to
-         GDB and the filenames it prints in the annotations.  */
+      /* If a file was opened, canonicalize its filename.  */
       if (fd < 0)
        *filename_opened = NULL;
       else if (IS_ABSOLUTE_PATH (filename))
-       *filename_opened = xfullpath (filename);
+       *filename_opened = gdb_realpath (filename);
       else
        {
          /* Beware the // my son, the Emacs barfs, the botch that catch...  */
@@ -857,7 +860,7 @@ done:
                            ? "" : SLASH_STRING,
                            filename, (char *)NULL);
 
-         *filename_opened = xfullpath (f);
+         *filename_opened = gdb_realpath (f);
          xfree (f);
        }
     }
@@ -951,7 +954,7 @@ get_substitute_path_rule (const char *path)
    Return NULL if no substitution rule was specified by the user,
    or if no rule applied to the given PATH.  */
    
-static char *
+char *
 rewrite_source_path (const char *path)
 {
   const struct substitute_path_rule *rule = get_substitute_path_rule (path);
@@ -973,26 +976,6 @@ rewrite_source_path (const char *path)
   return new_path;
 }
 
-/* This function is capable of finding the absolute path to a
-   source file, and opening it, provided you give it a FILENAME.  Both the
-   DIRNAME and FULLNAME are only added suggestions on where to find the file.
-
-   FILENAME should be the filename to open.
-   DIRNAME is the compilation directory of a particular source file.
-           Only some debug formats provide this info.
-   FULLNAME can be the last known absolute path to the file in question.
-     Space for the path must have been malloc'd.  If a path substitution
-     is applied we free the old value and set a new one.
-
-   On Success 
-     A valid file descriptor is returned (the return value is positive).
-     FULLNAME is set to the absolute path to the file just opened.
-     The caller is responsible for freeing FULLNAME.
-
-   On Failure
-     An invalid file descriptor is returned (the return value is negative).
-     FULLNAME is set to NULL.  */
-
 int
 find_and_open_source (const char *filename,
                      const char *dirname,
@@ -1019,7 +1002,14 @@ find_and_open_source (const char *filename,
 
       result = open (*fullname, OPEN_MODE);
       if (result >= 0)
-       return result;
+       {
+         char *lpath = gdb_realpath (*fullname);
+
+         xfree (*fullname);
+         *fullname = lpath;
+         return result;
+       }
+
       /* Didn't work -- free old one, try again.  */
       xfree (*fullname);
       *fullname = NULL;
@@ -1100,35 +1090,62 @@ open_source_file (struct symtab *s)
 
 /* Finds the fullname that a symtab represents.
 
-   If this functions finds the fullname, it will save it in s->fullname
-   and it will also return the value.
+   This functions finds the fullname and saves it in s->fullname.
+   It will also return the value.
 
    If this function fails to find the file that this symtab represents,
-   NULL will be returned and s->fullname will be set to NULL.  */
+   the expected fullname is used.  Therefore the files does not have to
+   exist.  */
 
-char *
+const char *
 symtab_to_fullname (struct symtab *s)
 {
-  int r;
-
-  if (!s)
-    return NULL;
-
   /* Use cached copy if we have it.
      We rely on forget_cached_source_info being called appropriately
      to handle cases like the file being moved.  */
-  if (s->fullname)
-    return s->fullname;
+  if (s->fullname == NULL)
+    {
+      int fd = find_and_open_source (s->filename, s->dirname, &s->fullname);
 
-  r = find_and_open_source (s->filename, s->dirname, &s->fullname);
+      if (fd >= 0)
+       close (fd);
+      else
+       {
+         char *fullname;
+         struct cleanup *back_to;
 
-  if (r >= 0)
-    {
-      close (r);
-      return s->fullname;
-    }
+         /* rewrite_source_path would be applied by find_and_open_source, we
+            should report the pathname where GDB tried to find the file.  */
 
-  return NULL;
+         if (s->dirname == NULL || IS_ABSOLUTE_PATH (s->filename))
+           fullname = xstrdup (s->filename);
+         else
+           fullname = concat (s->dirname, SLASH_STRING, s->filename, NULL);
+
+         back_to = make_cleanup (xfree, fullname);
+         s->fullname = rewrite_source_path (fullname);
+         if (s->fullname == NULL)
+           s->fullname = xstrdup (fullname);
+         do_cleanups (back_to);
+       }
+    } 
+
+  return s->fullname;
+}
+
+/* See commentary in source.h.  */
+
+const char *
+symtab_to_filename_for_display (struct symtab *symtab)
+{
+  if (filename_display_string == filename_display_basename)
+    return lbasename (symtab->filename);
+  else if (filename_display_string == filename_display_absolute)
+    return symtab_to_fullname (symtab);
+  else if (filename_display_string == filename_display_relative)
+    return symtab->filename;
+  else
+    internal_error (__FILE__, __LINE__, _("invalid filename_display_string"));
 }
 \f
 /* Create and initialize the table S->line_charpos that records
@@ -1150,7 +1167,7 @@ find_source_lines (struct symtab *s, int desc)
   gdb_assert (s);
   line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
   if (fstat (desc, &st) < 0)
-    perror_with_name (s->filename);
+    perror_with_name (symtab_to_filename_for_display (s));
 
   if (s->objfile && s->objfile->obfd)
     mtime = s->objfile->mtime;
@@ -1175,7 +1192,7 @@ find_source_lines (struct symtab *s, int desc)
     /* Reassign `size' to result of read for systems where \r\n -> \n.  */
     size = myread (desc, data, size);
     if (size < 0)
-      perror_with_name (s->filename);
+      perror_with_name (symtab_to_filename_for_display (s));
     end = data + size;
     p = data;
     line_charpos[0] = 0;
@@ -1270,10 +1287,9 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
 /* Print source lines from the file of symtab S,
    starting with line number LINE and stopping before line number STOPLINE.  */
 
-static void print_source_lines_base (struct symtab *s, int line, int stopline,
-                                    int noerror);
 static void
-print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
+print_source_lines_base (struct symtab *s, int line, int stopline,
+                        enum print_source_lines_flags flags)
 {
   int c;
   int desc;
@@ -1301,13 +1317,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
       else
        {
          desc = last_source_error;
-         noerror = 1;
+         flags |= PRINT_SOURCE_LINES_NOERROR;
        }
     }
   else
     {
       desc = last_source_error;
-      noerror = 1;
+         flags |= PRINT_SOURCE_LINES_NOERROR;
       noprint = 1;
     }
 
@@ -1315,17 +1331,36 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
     {
       last_source_error = desc;
 
-      if (!noerror)
+      if (!(flags & PRINT_SOURCE_LINES_NOERROR))
        {
-         char *name = alloca (strlen (s->filename) + 100);
-         sprintf (name, "%d\t%s", line, s->filename);
+         const char *filename = symtab_to_filename_for_display (s);
+         int len = strlen (filename) + 100;
+         char *name = alloca (len);
+
+         xsnprintf (name, len, "%d\t%s", line, filename);
          print_sys_errmsg (name, errno);
        }
       else
        {
          ui_out_field_int (uiout, "line", line);
          ui_out_text (uiout, "\tin ");
-         ui_out_field_string (uiout, "file", s->filename);
+
+         /* CLI expects only the "file" field.  TUI expects only the
+            "fullname" field (and TUI does break if "file" is printed).
+            MI expects both fields.  ui_source_list is set only for CLI,
+            not for TUI.  */
+         if (ui_out_is_mi_like_p (uiout)
+             || ui_out_test_flags (uiout, ui_source_list))
+           ui_out_field_string (uiout, "file",
+                                symtab_to_filename_for_display (s));
+         if (ui_out_is_mi_like_p (uiout)
+             || !ui_out_test_flags (uiout, ui_source_list))
+           {
+             const char *fullname = symtab_to_fullname (s);
+
+             ui_out_field_string (uiout, "fullname", fullname);
+           }
+
          ui_out_text (uiout, "\n");
        }
 
@@ -1341,13 +1376,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
     {
       close (desc);
       error (_("Line number %d out of range; %s has %d lines."),
-            line, s->filename, s->nlines);
+            line, symtab_to_filename_for_display (s), s->nlines);
     }
 
   if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
     {
       close (desc);
-      perror_with_name (s->filename);
+      perror_with_name (symtab_to_filename_for_display (s));
     }
 
   stream = fdopen (desc, FDOPEN_MODE);
@@ -1362,13 +1397,18 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
       if (c == EOF)
        break;
       last_line_listed = current_source_line;
-      sprintf (buf, "%d\t", current_source_line++);
+      if (flags & PRINT_SOURCE_LINES_FILENAME)
+        {
+          ui_out_text (uiout, symtab_to_filename_for_display (s));
+          ui_out_text (uiout, ":");
+        }
+      xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++);
       ui_out_text (uiout, buf);
       do
        {
          if (c < 040 && c != '\t' && c != '\n' && c != '\r')
            {
-             sprintf (buf, "^%c", c + 0100);
+             xsnprintf (buf, sizeof (buf), "^%c", c + 0100);
              ui_out_text (uiout, buf);
            }
          else if (c == 0177)
@@ -1385,7 +1425,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
            }
          else
            {
-             sprintf (buf, "%c", c);
+             xsnprintf (buf, sizeof (buf), "%c", c);
              ui_out_text (uiout, buf);
            }
        }
@@ -1401,9 +1441,10 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
    window otherwise it is simply printed.  */
 
 void
-print_source_lines (struct symtab *s, int line, int stopline, int noerror)
+print_source_lines (struct symtab *s, int line, int stopline,
+                   enum print_source_lines_flags flags)
 {
-  print_source_lines_base (s, line, stopline, noerror);
+  print_source_lines_base (s, line, stopline, flags);
 }
 \f
 /* Print info on range of pc's in a specified line.  */
@@ -1431,7 +1472,7 @@ line_info (char *arg, int from_tty)
     }
   else
     {
-      sals = decode_line_spec_1 (arg, DECODE_LINE_LIST_MODE);
+      sals = decode_line_with_last_displayed (arg, DECODE_LINE_LIST_MODE);
 
       dont_repeat ();
     }
@@ -1472,7 +1513,8 @@ line_info (char *arg, int from_tty)
          if (start_pc == end_pc)
            {
              printf_filtered ("Line %d of \"%s\"",
-                              sal.line, sal.symtab->filename);
+                              sal.line,
+                              symtab_to_filename_for_display (sal.symtab));
              wrap_here ("  ");
              printf_filtered (" is at address ");
              print_address (gdbarch, start_pc, gdb_stdout);
@@ -1482,7 +1524,8 @@ line_info (char *arg, int from_tty)
          else
            {
              printf_filtered ("Line %d of \"%s\"",
-                              sal.line, sal.symtab->filename);
+                              sal.line,
+                              symtab_to_filename_for_display (sal.symtab));
              wrap_here ("  ");
              printf_filtered (" starts at address ");
              print_address (gdbarch, start_pc, gdb_stdout);
@@ -1508,7 +1551,7 @@ line_info (char *arg, int from_tty)
           which the user would want to see?  If we have debugging symbols
           and no line numbers?  */
        printf_filtered (_("Line number %d is out of range for \"%s\".\n"),
-                        sal.line, sal.symtab->filename);
+                        sal.line, symtab_to_filename_for_display (sal.symtab));
     }
   do_cleanups (cleanups);
 }
@@ -1536,7 +1579,7 @@ forward_search_command (char *regex, int from_tty)
 
   desc = open_source_file (current_source_symtab);
   if (desc < 0)
-    perror_with_name (current_source_symtab->filename);
+    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
   cleanups = make_cleanup_close (desc);
 
   if (current_source_symtab->line_charpos == 0)
@@ -1546,7 +1589,7 @@ forward_search_command (char *regex, int from_tty)
     error (_("Expression not found"));
 
   if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    perror_with_name (current_source_symtab->filename);
+    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
 
   discard_cleanups (cleanups);
   stream = fdopen (desc, FDOPEN_MODE);
@@ -1625,7 +1668,7 @@ reverse_search_command (char *regex, int from_tty)
 
   desc = open_source_file (current_source_symtab);
   if (desc < 0)
-    perror_with_name (current_source_symtab->filename);
+    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
   cleanups = make_cleanup_close (desc);
 
   if (current_source_symtab->line_charpos == 0)
@@ -1635,7 +1678,7 @@ reverse_search_command (char *regex, int from_tty)
     error (_("Expression not found"));
 
   if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    perror_with_name (current_source_symtab->filename);
+    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
 
   discard_cleanups (cleanups);
   stream = fdopen (desc, FDOPEN_MODE);
@@ -1678,8 +1721,11 @@ reverse_search_command (char *regex, int from_tty)
       line--;
       if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
        {
+         const char *filename;
+
          do_cleanups (cleanups);
-         perror_with_name (current_source_symtab->filename);
+         filename = symtab_to_filename_for_display (current_source_symtab);
+         perror_with_name (filename);
        }
     }
 
@@ -1978,6 +2024,7 @@ The address is also stored as the value of \"$_\"."));
 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_alias ("fo", "forward-search", class_files, 1);
 
   add_com ("reverse-search", class_files, reverse_search_command, _("\
 Search backward for regular expression (see regex(3)) from last line listed.\n\
@@ -1990,12 +2037,12 @@ The matching line number is also stored as the value of \"$_\"."));
       add_com_alias ("?", "reverse-search", class_files, 0);
     }
 
-  add_setshow_integer_cmd ("listsize", class_support, &lines_to_list, _("\
+  add_setshow_zuinteger_unlimited_cmd ("listsize", class_support,
+                                      &lines_to_list, _("\
 Set number of source lines gdb will list by default."), _("\
 Show number of source lines gdb will list by default."), NULL,
-                           NULL,
-                           show_lines_to_list,
-                           &setlist, &showlist);
+                                      NULL, show_lines_to_list,
+                                      &setlist, &showlist);
 
   add_cmd ("substitute-path", class_files, set_substitute_path_command,
            _("\
@@ -2019,4 +2066,19 @@ Usage: show substitute-path [FROM]\n\
 Print the rule for substituting FROM in source file names. If FROM\n\
 is not specified, print all substitution rules."),
            &showlist);
+
+  add_setshow_enum_cmd ("filename-display", class_files,
+                       filename_display_kind_names,
+                       &filename_display_string, _("\
+Set how to display filenames."), _("\
+Show how to display filenames."), _("\
+filename-display can be:\n\
+  basename - display only basename of a filename\n\
+  relative - display a filename relative to the compilation directory\n\
+  absolute - display an absolute filename\n\
+By default, relative filenames are displayed."),
+                       NULL,
+                       show_filename_display_string,
+                       &setlist, &showlist);
+
 }
This page took 0.03349 seconds and 4 git commands to generate.