* linux-nat.c (enum sigchld_state): Delete.
[deliverable/binutils-gdb.git] / gdb / source.c
index 800491959d519a61bf794393baa307ceb3997dd9..50f3510f130c4157012580c25e8d5f3cce3e3b74 100644 (file)
@@ -1,13 +1,13 @@
 /* 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
-   Free Software Foundation, Inc.
+   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 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -29,6 +27,7 @@
 #include "gdbcmd.h"
 #include "frame.h"
 #include "value.h"
+#include "gdb_assert.h"
 
 #include <sys/types.h>
 #include "gdb_string.h"
@@ -73,6 +72,17 @@ static void show_directories (char *, int);
 
 char *source_path;
 
+/* Support for source path substitution commands.  */
+
+struct substitute_path_rule
+{
+  char *from;
+  char *to;
+  struct substitute_path_rule *next;
+};
+
+static struct substitute_path_rule *substitute_path_rules = NULL;
+
 /* Symtab of default file for listing lines of.  */
 
 static struct symtab *current_source_symtab;
@@ -229,7 +239,7 @@ select_source_symtab (struct symtab *s)
 
   /* Make the default place to list be the function `main'
      if one exists.  */
-  if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0, NULL))
+  if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0))
     {
       sals = decode_line_spec (main_name (), 1);
       sal = sals.sals[0];
@@ -240,7 +250,8 @@ select_source_symtab (struct symtab *s)
        return;
     }
 
-  /* All right; find the last file in the symtab list (ignoring .h's).  */
+  /* Alright; find the last file in the symtab list (ignoring .h's
+     and namespace symtabs).  */
 
   current_source_line = 1;
 
@@ -250,14 +261,15 @@ select_source_symtab (struct symtab *s)
        {
          const char *name = s->filename;
          int len = strlen (name);
-         if (!(len > 2 && strcmp(&name[len - 2], ".h") == 0))
+         if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
+             || strcmp (name, "<<C++-namespaces>>") == 0)))
            current_source_symtab = s;
        }
     }
   if (current_source_symtab)
     return;
 
-  /* Howabout the partial symbol tables? */
+  /* How about the partial symbol tables?  */
 
   for (ofp = object_files; ofp != NULL; ofp = ofp->next)
     {
@@ -265,7 +277,8 @@ select_source_symtab (struct symtab *s)
        {
          const char *name = ps->filename;
          int len = strlen (name);
-         if (!(len > 2 && strcmp (&name[len - 2], ".h") == 0))
+         if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
+             || strcmp (name, "<<C++-namespaces>>") == 0)))
            cs_pst = ps;
        }
     }
@@ -359,7 +372,7 @@ directory_command (char *dirname, int from_tty)
   /* FIXME, this goes to "delete dir"... */
   if (dirname == 0)
     {
-      if (from_tty && query (_("Reinitialize source path to empty? ")))
+      if (!from_tty || query (_("Reinitialize source path to empty? ")))
        {
          xfree (source_path);
          init_source_path ();
@@ -415,12 +428,9 @@ add_path (char *dirname, char **which_path, int parse_separators)
       /* This will properly parse the space and tab separators
         and any quotes that may exist. DIRNAME_SEPARATOR will
         be dealt with later.  */
-      argv = buildargv (dirname);
+      argv = gdb_buildargv (dirname);
       make_cleanup_freeargv (argv);
 
-      if (argv == NULL)
-       nomem (0);
-
       arg = argv[0];
     }
   else
@@ -812,7 +822,7 @@ done:
 
    Else, this functions returns 0, and FULL_PATHNAME is set to NULL.  */
 int
-source_full_path_of (char *filename, char **full_pathname)
+source_full_path_of (const char *filename, char **full_pathname)
 {
   int fd;
 
@@ -828,6 +838,85 @@ source_full_path_of (char *filename, char **full_pathname)
   return 1;
 }
 
+/* Return non-zero if RULE matches PATH, that is if the rule can be
+   applied to PATH.  */
+
+static int
+substitute_path_rule_matches (const struct substitute_path_rule *rule,
+                              const char *path)
+{
+  const int from_len = strlen (rule->from);
+  const int path_len = strlen (path);
+  char *path_start;
+
+  if (path_len < from_len)
+    return 0;
+
+  /* The substitution rules are anchored at the start of the path,
+     so the path should start with rule->from.  There is no filename
+     comparison routine, so we need to extract the first FROM_LEN
+     characters from PATH first and use that to do the comparison.  */
+
+  path_start = alloca (from_len + 1);
+  strncpy (path_start, path, from_len);
+  path_start[from_len] = '\0';
+
+  if (FILENAME_CMP (path_start, rule->from) != 0)
+    return 0;
+
+  /* Make sure that the region in the path that matches the substitution
+     rule is immediately followed by a directory separator (or the end of
+     string character).  */
+  
+  if (path[from_len] != '\0' && !IS_DIR_SEPARATOR (path[from_len]))
+    return 0;
+
+  return 1;
+}
+
+/* Find the substitute-path rule that applies to PATH and return it.
+   Return NULL if no rule applies.  */
+
+static struct substitute_path_rule *
+get_substitute_path_rule (const char *path)
+{
+  struct substitute_path_rule *rule = substitute_path_rules;
+
+  while (rule != NULL && !substitute_path_rule_matches (rule, path))
+    rule = rule->next;
+
+  return rule;
+}
+
+/* If the user specified a source path substitution rule that applies
+   to PATH, then apply it and return the new path.  This new path must
+   be deallocated afterwards.  
+   
+   Return NULL if no substitution rule was specified by the user,
+   or if no rule applied to the given PATH.  */
+   
+static char *
+rewrite_source_path (const char *path)
+{
+  const struct substitute_path_rule *rule = get_substitute_path_rule (path);
+  char *new_path;
+  int from_len;
+  
+  if (rule == NULL)
+    return NULL;
+
+  from_len = strlen (rule->from);
+
+  /* Compute the rewritten path and return it.  */
+
+  new_path =
+    (char *) xmalloc (strlen (path) + 1 + strlen (rule->to) - from_len);
+  strcpy (new_path, rule->to);
+  strcat (new_path, path + from_len);
+
+  return new_path;
+}
+
 /* This function is capable of finding the absolute path to a
    source file, and opening it, provided you give it an 
    OBJFILE and FILENAME. Both the DIRNAME and FULLNAME are only
@@ -838,15 +927,19 @@ source_full_path_of (char *filename, char **full_pathname)
    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
-     A non valid file descriptor is returned. ( the return value is negitive ) 
+     An invalid file descriptor is returned. ( the return value is negative ) 
      FULLNAME is set to NULL.  */
-int
+
+static int
 find_and_open_source (struct objfile *objfile,
                      const char *filename,
                      const char *dirname,
@@ -857,8 +950,20 @@ find_and_open_source (struct objfile *objfile,
   int result;
 
   /* Quick way out if we already know its full name */
+
   if (*fullname)
     {
+      /* The user may have requested that source paths be rewritten
+         according to substitution rules he provided.  If a substitution
+         rule applies to this path, then apply it.  */
+      char *rewritten_fullname = rewrite_source_path (*fullname);
+
+      if (rewritten_fullname != NULL)
+        {
+          xfree (*fullname);
+          *fullname = rewritten_fullname;
+        }
+
       result = open (*fullname, OPEN_MODE);
       if (result >= 0)
        return result;
@@ -869,6 +974,17 @@ find_and_open_source (struct objfile *objfile,
 
   if (dirname != NULL)
     {
+      /* If necessary, rewrite the compilation directory name according
+         to the source path substitution rules specified by the user.  */
+
+      char *rewritten_dirname = rewrite_source_path (dirname);
+
+      if (rewritten_dirname != NULL)
+        {
+          make_cleanup (xfree, rewritten_dirname);
+          dirname = rewritten_dirname;
+        }
+      
       /* Replace a path entry of  $cdir  with the compilation directory name */
 #define        cdir_len        5
       /* We cast strstr's result in case an ANSIhole has made it const,
@@ -888,6 +1004,19 @@ find_and_open_source (struct objfile *objfile,
        }
     }
 
+  if (IS_ABSOLUTE_PATH (filename))
+    {
+      /* If filename is absolute path, try the source path
+        substitution on it.  */
+      char *rewritten_filename = rewrite_source_path (filename);
+
+      if (rewritten_filename != NULL)
+        {
+          make_cleanup (xfree, rewritten_filename);
+          filename = rewritten_filename;
+        }
+    }
+
   result = openp (path, OPF_SEARCH_IN_PATH, filename, OPEN_MODE, 0, fullname);
   if (result < 0)
     {
@@ -897,13 +1026,6 @@ find_and_open_source (struct objfile *objfile,
        result = openp (path, OPF_SEARCH_IN_PATH, p, OPEN_MODE, 0, fullname);
     }
 
-  if (result >= 0)
-    {
-      char *tmp_fullname;
-      tmp_fullname = *fullname;
-      *fullname = xstrdup (tmp_fullname);
-      xfree (tmp_fullname);
-    }
   return result;
 }
 
@@ -924,11 +1046,11 @@ open_source_file (struct symtab *s)
 
 /* Finds the fullname that a symtab represents.
 
-   If this functions finds the fullname, it will save it in ps->fullname
+   If this functions finds the fullname, it will save it in s->fullname
    and it will also return the value.
 
    If this function fails to find the file that this symtab represents,
-   NULL will be returned and ps->fullname will be set to NULL.  */
+   NULL will be returned and s->fullname will be set to NULL.  */
 char *
 symtab_to_fullname (struct symtab *s)
 {
@@ -942,7 +1064,7 @@ symtab_to_fullname (struct symtab *s)
   r = find_and_open_source (s->objfile, s->filename, s->dirname,
                            &s->fullname);
 
-  if (r)
+  if (r >= 0)
     {
       close (r);
       return s->fullname;
@@ -971,7 +1093,7 @@ psymtab_to_fullname (struct partial_symtab *ps)
   r = find_and_open_source (ps->objfile, ps->filename, ps->dirname,
                            &ps->fullname);
 
-  if (r
+  if (r >= 0)
     {
       close (r);
       return ps->fullname;
@@ -996,14 +1118,15 @@ find_source_lines (struct symtab *s, int desc)
   long mtime = 0;
   int size;
 
+  gdb_assert (s);
   line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
   if (fstat (desc, &st) < 0)
     perror_with_name (s->filename);
 
-  if (s && s->objfile && s->objfile->obfd)
-    mtime = bfd_get_mtime (s->objfile->obfd);
+  if (s->objfile && s->objfile->obfd)
+    mtime = s->objfile->mtime;
   else if (exec_bfd)
-    mtime = bfd_get_mtime (exec_bfd);
+    mtime = exec_bfd_mtime;
 
   if (mtime && mtime < st.st_mtime)
     warning (_("Source file is more recent than executable."));
@@ -1128,6 +1251,7 @@ static int
 get_filename_and_charpos (struct symtab *s, char **fullname)
 {
   int desc, linenums_changed = 0;
+  struct cleanup *cleanups;
 
   desc = open_source_file (s);
   if (desc < 0)
@@ -1136,13 +1260,14 @@ get_filename_and_charpos (struct symtab *s, char **fullname)
        *fullname = NULL;
       return 0;
     }
+  cleanups = make_cleanup_close (desc);
   if (fullname)
     *fullname = s->fullname;
   if (s->line_charpos == 0)
     linenums_changed = 1;
   if (linenums_changed)
     find_source_lines (s, desc);
-  close (desc);
+  do_cleanups (cleanups);
   return linenums_changed;
 }
 
@@ -1189,6 +1314,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
   int desc;
   FILE *stream;
   int nlines = stopline - line;
+  struct cleanup *cleanup;
 
   /* Regardless of whether we can open the file, set current_source_symtab. */
   current_source_symtab = s;
@@ -1255,6 +1381,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
 
   stream = fdopen (desc, FDOPEN_MODE);
   clearerr (stream);
+  cleanup = make_cleanup_fclose (stream);
 
   while (nlines-- > 0)
     {
@@ -1294,11 +1421,11 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
       while (c != '\n' && (c = fgetc (stream)) >= 0);
     }
 
-  fclose (stream);
+  do_cleanups (cleanup);
 }
 \f
 /* Show source lines from the file of symtab S, starting with line
-   number LINE and stopping before line number STOPLINE.  If this is the
+   number LINE and stopping before line number STOPLINE.  If this is
    not the command line version, then the source is shown in the source
    window otherwise it is simply printed */
 
@@ -1385,7 +1512,7 @@ line_info (char *arg, int from_tty)
            }
 
          /* x/i should display this line's code.  */
-         set_next_address (start_pc);
+         set_next_address (current_gdbarch, start_pc);
 
          /* Repeating "info line" should do the following line.  */
          last_line_listed = sal.line + 1;
@@ -1415,6 +1542,7 @@ forward_search_command (char *regex, int from_tty)
   FILE *stream;
   int line;
   char *msg;
+  struct cleanup *cleanups;
 
   line = last_line_listed + 1;
 
@@ -1428,24 +1556,21 @@ 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);
+  cleanups = make_cleanup_close (desc);
 
   if (current_source_symtab->line_charpos == 0)
     find_source_lines (current_source_symtab, desc);
 
   if (line < 1 || line > current_source_symtab->nlines)
-    {
-      close (desc);
-      error (_("Expression not found"));
-    }
+    error (_("Expression not found"));
 
   if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    {
-      close (desc);
-      perror_with_name (current_source_symtab->filename);
-    }
+    perror_with_name (current_source_symtab->filename);
 
+  discard_cleanups (cleanups);
   stream = fdopen (desc, FDOPEN_MODE);
   clearerr (stream);
+  cleanups = make_cleanup_fclose (stream);
   while (1)
     {
       static char *buf = NULL;
@@ -1488,7 +1613,7 @@ forward_search_command (char *regex, int from_tty)
          fclose (stream);
          print_source_lines (current_source_symtab, line, line + 1, 0);
          set_internalvar (lookup_internalvar ("_"),
-                          value_from_longest (builtin_type_int,
+                          value_from_longest (builtin_type_int32,
                                               (LONGEST) line));
          current_source_line = max (line - lines_to_list / 2, 1);
          return;
@@ -1497,7 +1622,7 @@ forward_search_command (char *regex, int from_tty)
     }
 
   printf_filtered (_("Expression not found\n"));
-  fclose (stream);
+  do_cleanups (cleanups);
 }
 
 static void
@@ -1508,6 +1633,7 @@ reverse_search_command (char *regex, int from_tty)
   FILE *stream;
   int line;
   char *msg;
+  struct cleanup *cleanups;
 
   line = last_line_listed - 1;
 
@@ -1521,24 +1647,21 @@ 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);
+  cleanups = make_cleanup_close (desc);
 
   if (current_source_symtab->line_charpos == 0)
     find_source_lines (current_source_symtab, desc);
 
   if (line < 1 || line > current_source_symtab->nlines)
-    {
-      close (desc);
-      error (_("Expression not found"));
-    }
+    error (_("Expression not found"));
 
   if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    {
-      close (desc);
-      perror_with_name (current_source_symtab->filename);
-    }
+    perror_with_name (current_source_symtab->filename);
 
+  discard_cleanups (cleanups);
   stream = fdopen (desc, FDOPEN_MODE);
   clearerr (stream);
+  cleanups = make_cleanup_fclose (stream);
   while (line > 1)
     {
 /* FIXME!!!  We walk right off the end of buf if we get a long line!!! */
@@ -1570,7 +1693,7 @@ reverse_search_command (char *regex, int from_tty)
          fclose (stream);
          print_source_lines (current_source_symtab, line, line + 1, 0);
          set_internalvar (lookup_internalvar ("_"),
-                          value_from_longest (builtin_type_int,
+                          value_from_longest (builtin_type_int32,
                                               (LONGEST) line));
          current_source_line = max (line - lines_to_list / 2, 1);
          return;
@@ -1584,9 +1707,224 @@ reverse_search_command (char *regex, int from_tty)
     }
 
   printf_filtered (_("Expression not found\n"));
-  fclose (stream);
+  do_cleanups (cleanups);
   return;
 }
+
+/* If the last character of PATH is a directory separator, then strip it.  */
+
+static void
+strip_trailing_directory_separator (char *path)
+{
+  const int last = strlen (path) - 1;
+
+  if (last < 0)
+    return;  /* No stripping is needed if PATH is the empty string.  */
+
+  if (IS_DIR_SEPARATOR (path[last]))
+    path[last] = '\0';
+}
+
+/* Return the path substitution rule that matches FROM.
+   Return NULL if no rule matches.  */
+
+static struct substitute_path_rule *
+find_substitute_path_rule (const char *from)
+{
+  struct substitute_path_rule *rule = substitute_path_rules;
+
+  while (rule != NULL)
+    {
+      if (FILENAME_CMP (rule->from, from) == 0)
+        return rule;
+      rule = rule->next;
+    }
+
+  return NULL;
+}
+
+/* Add a new substitute-path rule at the end of the current list of rules.
+   The new rule will replace FROM into TO.  */
+
+void
+add_substitute_path_rule (char *from, char *to)
+{
+  struct substitute_path_rule *rule;
+  struct substitute_path_rule *new_rule;
+
+  new_rule = xmalloc (sizeof (struct substitute_path_rule));
+  new_rule->from = xstrdup (from);
+  new_rule->to = xstrdup (to);
+  new_rule->next = NULL;
+
+  /* If the list of rules are empty, then insert the new rule
+     at the head of the list.  */
+
+  if (substitute_path_rules == NULL)
+    {
+      substitute_path_rules = new_rule;
+      return;
+    }
+
+  /* Otherwise, skip to the last rule in our list and then append
+     the new rule.  */
+
+  rule = substitute_path_rules;
+  while (rule->next != NULL)
+    rule = rule->next;
+
+  rule->next = new_rule;
+}
+
+/* Remove the given source path substitution rule from the current list
+   of rules.  The memory allocated for that rule is also deallocated.  */
+
+static void
+delete_substitute_path_rule (struct substitute_path_rule *rule)
+{
+  if (rule == substitute_path_rules)
+    substitute_path_rules = rule->next;
+  else
+    {
+      struct substitute_path_rule *prev = substitute_path_rules;
+
+      while (prev != NULL && prev->next != rule)
+        prev = prev->next;
+
+      gdb_assert (prev != NULL);
+
+      prev->next = rule->next;
+    }
+
+  xfree (rule->from);
+  xfree (rule->to);
+  xfree (rule);
+}
+
+/* Implement the "show substitute-path" command.  */
+
+static void
+show_substitute_path_command (char *args, int from_tty)
+{
+  struct substitute_path_rule *rule = substitute_path_rules;
+  char **argv;
+  char *from = NULL;
+  
+  argv = gdb_buildargv (args);
+  make_cleanup_freeargv (argv);
+
+  /* We expect zero or one argument.  */
+
+  if (argv != NULL && argv[0] != NULL && argv[1] != NULL)
+    error (_("Too many arguments in command"));
+
+  if (argv != NULL && argv[0] != NULL)
+    from = argv[0];
+
+  /* Print the substitution rules.  */
+
+  if (from != NULL)
+    printf_filtered
+      (_("Source path substitution rule matching `%s':\n"), from);
+  else
+    printf_filtered (_("List of all source path substitution rules:\n"));
+
+  while (rule != NULL)
+    {
+      if (from == NULL || FILENAME_CMP (rule->from, from) == 0)
+        printf_filtered ("  `%s' -> `%s'.\n", rule->from, rule->to);
+      rule = rule->next;
+    }
+}
+
+/* Implement the "unset substitute-path" command.  */
+
+static void
+unset_substitute_path_command (char *args, int from_tty)
+{
+  struct substitute_path_rule *rule = substitute_path_rules;
+  char **argv = gdb_buildargv (args);
+  char *from = NULL;
+  int rule_found = 0;
+
+  /* This function takes either 0 or 1 argument.  */
+
+  make_cleanup_freeargv (argv);
+  if (argv != NULL && argv[0] != NULL && argv[1] != NULL)
+    error (_("Incorrect usage, too many arguments in command"));
+
+  if (argv != NULL && argv[0] != NULL)
+    from = argv[0];
+
+  /* If the user asked for all the rules to be deleted, ask him
+     to confirm and give him a chance to abort before the action
+     is performed.  */
+
+  if (from == NULL
+      && !query (_("Delete all source path substitution rules? ")))
+    error (_("Canceled"));
+
+  /* Delete the rule matching the argument.  No argument means that
+     all rules should be deleted.  */
+
+  while (rule != NULL)
+    {
+      struct substitute_path_rule *next = rule->next;
+
+      if (from == NULL || FILENAME_CMP (from, rule->from) == 0)
+        {
+          delete_substitute_path_rule (rule);
+          rule_found = 1;
+        }
+
+      rule = next;
+    }
+  
+  /* If the user asked for a specific rule to be deleted but
+     we could not find it, then report an error.  */
+
+  if (from != NULL && !rule_found)
+    error (_("No substitution rule defined for `%s'"), from);
+}
+
+/* Add a new source path substitution rule.  */
+
+static void
+set_substitute_path_command (char *args, int from_tty)
+{
+  char *from_path, *to_path;
+  char **argv;
+  struct substitute_path_rule *rule;
+  
+  argv = gdb_buildargv (args);
+  make_cleanup_freeargv (argv);
+
+  if (argv == NULL || argv[0] == NULL || argv [1] == NULL)
+    error (_("Incorrect usage, too few arguments in command"));
+
+  if (argv[2] != NULL)
+    error (_("Incorrect usage, too many arguments in command"));
+
+  if (*(argv[0]) == '\0')
+    error (_("First argument must be at least one character long"));
+
+  /* Strip any trailing directory separator character in either FROM
+     or TO.  The substitution rule already implicitly contains them.  */
+  strip_trailing_directory_separator (argv[0]);
+  strip_trailing_directory_separator (argv[1]);
+
+  /* If a rule with the same "from" was previously defined, then
+     delete it.  This new rule replaces it.  */
+
+  rule = find_substitute_path_rule (argv[0]);
+  if (rule != NULL)
+    delete_substitute_path_rule (rule);
+      
+  /* Insert the new substitution rule.  */
+
+  add_substitute_path_rule (argv[0], argv[1]);
+}
+
 \f
 void
 _initialize_source (void)
@@ -1666,4 +2004,27 @@ Show number of source lines gdb will list by default."), NULL,
                            NULL,
                            show_lines_to_list,
                            &setlist, &showlist);
+
+  add_cmd ("substitute-path", class_files, set_substitute_path_command,
+           _("\
+Usage: set substitute-path FROM TO\n\
+Add a substitution rule replacing FROM into TO in source file names.\n\
+If a substitution rule was previously set for FROM, the old rule\n\
+is replaced by the new one."),
+           &setlist);
+
+  add_cmd ("substitute-path", class_files, unset_substitute_path_command,
+           _("\
+Usage: unset substitute-path [FROM]\n\
+Delete the rule for substituting FROM in source file names.  If FROM\n\
+is not specified, all substituting rules are deleted.\n\
+If the debugger cannot find a rule for FROM, it will display a warning."),
+           &unsetlist);
+
+  add_cmd ("substitute-path", class_files, show_substitute_path_command,
+           _("\
+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);
 }
This page took 0.03435 seconds and 4 git commands to generate.