Add ravenscar-thread support for powerpc.
[deliverable/binutils-gdb.git] / gdb / source.c
index 909f2523b7224d1282c6463de3def84dbe25bb79..7e14fc6ebcfbec7cde047a80c3274477a9fe59dc 100644 (file)
@@ -243,7 +243,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;
@@ -383,7 +384,7 @@ 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 ();
 }
@@ -440,62 +441,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
@@ -573,65 +552,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);
 }
 
 
@@ -712,10 +680,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);
@@ -778,16 +747,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;
@@ -802,11 +770,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*
@@ -815,7 +801,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;
        }
 
@@ -834,6 +820,8 @@ openp (const char *path, int opts, const char *string,
        }
     }
 
+  do_cleanups (back_to);
+
 done:
   if (filename_opened)
     {
@@ -971,26 +959,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,
@@ -1017,7 +985,16 @@ find_and_open_source (const char *filename,
 
       result = open (*fullname, OPEN_MODE);
       if (result >= 0)
-       return result;
+       {
+         /* Call xfullpath here to be consistent with openp
+            which we use below.  */
+         char *lpath = xfullpath (*fullname);
+
+         xfree (*fullname);
+         *fullname = lpath;
+         return result;
+       }
+
       /* Didn't work -- free old one, try again.  */
       xfree (*fullname);
       *fullname = NULL;
@@ -1104,7 +1081,7 @@ open_source_file (struct symtab *s)
    If this function fails to find the file that this symtab represents,
    NULL will be returned and s->fullname will be set to NULL.  */
 
-char *
+const char *
 symtab_to_fullname (struct symtab *s)
 {
   int r;
@@ -1268,10 +1245,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;
@@ -1299,13 +1275,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;
     }
 
@@ -1313,10 +1289,12 @@ 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);
+         int len = strlen (s->filename) + 100;
+         char *name = alloca (len);
+
+         xsnprintf (name, len, "%d\t%s", line, s->filename);
          print_sys_errmsg (name, errno);
        }
       else
@@ -1324,6 +1302,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
          ui_out_field_int (uiout, "line", line);
          ui_out_text (uiout, "\tin ");
          ui_out_field_string (uiout, "file", s->filename);
+         if (ui_out_is_mi_like_p (uiout))
+           {
+             const char *fullname = symtab_to_fullname (s);
+
+             if (fullname != NULL)
+               ui_out_field_string (uiout, "fullname", fullname);
+           }
          ui_out_text (uiout, "\n");
        }
 
@@ -1360,13 +1345,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, s->filename);
+          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)
@@ -1383,7 +1373,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);
            }
        }
@@ -1399,9 +1389,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.  */
@@ -1429,7 +1420,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 ();
     }
@@ -1976,6 +1967,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\
@@ -1988,12 +1980,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,
            _("\
This page took 0.047826 seconds and 4 git commands to generate.