Move lookup_block_symbol to block.c, rename to block_lookup_symbol.
[deliverable/binutils-gdb.git] / gdb / source.c
index 2d9410ecc37ed9cfbcf2823901d40623dd29ee53..19c25623758b0f7d9a10379a694c44e50b688849 100644 (file)
@@ -1,5 +1,5 @@
 /* List lines of source files for GDB, the GNU debugger.
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbcmd.h"
 #include "frame.h"
 #include "value.h"
-#include "gdb_assert.h"
+#include "filestuff.h"
 
 #include <sys/types.h>
-#include "gdb_string.h"
-#include "gdb_stat.h"
+#include <sys/stat.h>
 #include <fcntl.h>
 #include "gdbcore.h"
 #include "gdb_regex.h"
@@ -44,9 +43,6 @@
 #include "ui-out.h"
 #include "readline/readline.h"
 
-#include "psymtab.h"
-
-
 #define OPEN_MODE (O_RDONLY | O_BINARY)
 #define FDOPEN_MODE FOPEN_RB
 
@@ -135,7 +131,9 @@ show_filename_display_string (struct ui_file *file, int from_tty,
 
 static int last_line_listed;
 
-/* First line number listed by last listing command.  */
+/* First line number listed by last listing command.  If 0, then no
+   source lines have yet been listed since the last time the current
+   source line was changed.  */
 
 static int first_line_listed;
 
@@ -155,6 +153,16 @@ get_first_line_listed (void)
   return first_line_listed;
 }
 
+/* Clear line listed range.  This makes the next "list" center the
+   printed source lines around the current source line.  */
+
+static void
+clear_lines_listed_range (void)
+{
+  first_line_listed = 0;
+  last_line_listed = 0;
+}
+
 /* Return the default number of lines to print with commands like the
    cli "list".  The caller of print_source_lines must use this to
    calculate the end line and use it in the call to print_source_lines
@@ -222,6 +230,9 @@ set_current_source_symtab_and_line (const struct symtab_and_line *sal)
   current_source_symtab = sal->symtab;
   current_source_line = sal->line;
 
+  /* Force the next "list" to center around the current line.  */
+  clear_lines_listed_range ();
+
   return cursal;
 }
 
@@ -576,17 +587,33 @@ add_path (char *dirname, char **which_path, int parse_separators)
        char tinybuf[2];
 
        p = *which_path;
-       /* 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))
+       while (1)
          {
-           /* 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  : */
+           /* 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)
+                 {
+                   /* Back over leading separator.  */
+                   p--;
+                 }
+               if (prefix > p - *which_path)
+                 {
+                   /* Same dir twice in one cmd.  */
+                   goto skip_dup;
+                 }
+               /* Copy from next '\0' or ':'.  */
+               memmove (p, &p[len + 1], strlen (&p[len + 1]) + 1);
+             }
+           p = strchr (p, DIRNAME_SEPARATOR);
+           if (p != 0)
+             ++p;
+           else
+             break;
          }
 
        tinybuf[0] = DIRNAME_SEPARATOR;
@@ -676,9 +703,10 @@ is_regular_file (const char *name)
 
    If OPF_TRY_CWD_FIRST, try to open ./STRING before searching PATH.
    (ie pretend the first element of PATH is ".").  This also indicates
-   that a slash in STRING disables searching of the path (this is
-   so that "exec-file ./foo" or "symbol-file ./foo" insures that you
-   get that particular version of foo or an error message).
+   that, unless OPF_SEARCH_IN_PATH is also specified, a slash in STRING
+   disables searching of the path (this is so that "exec-file ./foo" or
+   "symbol-file ./foo" insures that you get that particular version of
+   foo or an error message).
 
    If OPTS has OPF_SEARCH_IN_PATH set, absolute names will also be
    searched in path (we usually want this for source files but not for
@@ -690,6 +718,11 @@ is_regular_file (const char *name)
    and the file, sigh!  Emacs gets confuzzed by this when we print the
    source file name!!! 
 
+   If OPTS has OPF_RETURN_REALPATH set return FILENAME_OPENED resolved by
+   gdb_realpath.  Even without OPF_RETURN_REALPATH this function still returns
+   filename starting with "/".  If FILENAME_OPENED is NULL this option has no
+   effect.
+
    If a file is found, return the descriptor.
    Otherwise, return -1, with errno set for the last name we tried to open.  */
 
@@ -737,7 +770,7 @@ openp (const char *path, int opts, const char *string,
        {
          filename = alloca (strlen (string) + 1);
          strcpy (filename, string);
-         fd = open (filename, mode);
+         fd = gdb_open_cloexec (filename, mode, 0);
          if (fd >= 0)
            goto done;
        }
@@ -835,7 +868,7 @@ openp (const char *path, int opts, const char *string,
 
       if (is_regular_file (filename))
        {
-         fd = open (filename, mode);
+         fd = gdb_open_cloexec (filename, mode, 0);
          if (fd >= 0)
            break;
        }
@@ -849,20 +882,10 @@ done:
       /* If a file was opened, canonicalize its filename.  */
       if (fd < 0)
        *filename_opened = NULL;
-      else if (IS_ABSOLUTE_PATH (filename))
+      else if ((opts & OPF_RETURN_REALPATH) != 0)
        *filename_opened = gdb_realpath (filename);
       else
-       {
-         /* Beware the // my son, the Emacs barfs, the botch that catch...  */
-
-         char *f = concat (current_directory,
-                           IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
-                           ? "" : SLASH_STRING,
-                           filename, (char *)NULL);
-
-         *filename_opened = gdb_realpath (f);
-         xfree (f);
-       }
+       *filename_opened = gdb_abspath (filename);
     }
 
   return fd;
@@ -885,8 +908,9 @@ source_full_path_of (const char *filename, char **full_pathname)
 {
   int fd;
 
-  fd = openp (source_path, OPF_TRY_CWD_FIRST | OPF_SEARCH_IN_PATH, filename,
-             O_RDONLY, full_pathname);
+  fd = openp (source_path,
+             OPF_TRY_CWD_FIRST | OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH,
+             filename, O_RDONLY, full_pathname);
   if (fd < 0)
     {
       *full_pathname = NULL;
@@ -906,27 +930,20 @@ substitute_path_rule_matches (const struct substitute_path_rule *rule,
 {
   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.  */
+     so the path should start with rule->from.  */
 
-  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)
+  if (filename_ncmp (path, rule->from, from_len) != 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;
 
@@ -984,6 +1001,7 @@ find_and_open_source (const char *filename,
   char *path = source_path;
   const char *p;
   int result;
+  struct cleanup *cleanup;
 
   /* Quick way out if we already know its full name.  */
 
@@ -1000,7 +1018,7 @@ find_and_open_source (const char *filename,
           *fullname = rewritten_fullname;
         }
 
-      result = open (*fullname, OPEN_MODE);
+      result = gdb_open_cloexec (*fullname, OPEN_MODE, 0);
       if (result >= 0)
        {
          char *lpath = gdb_realpath (*fullname);
@@ -1015,6 +1033,8 @@ find_and_open_source (const char *filename,
       *fullname = NULL;
     }
 
+  cleanup = make_cleanup (null_cleanup, NULL);
+
   if (dirname != NULL)
     {
       /* If necessary, rewrite the compilation directory name according
@@ -1062,15 +1082,18 @@ find_and_open_source (const char *filename,
         }
     }
 
-  result = openp (path, OPF_SEARCH_IN_PATH, filename, OPEN_MODE, fullname);
+  result = openp (path, OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH, filename,
+                 OPEN_MODE, fullname);
   if (result < 0)
     {
       /* Didn't work.  Try using just the basename.  */
       p = lbasename (filename);
       if (p != filename)
-       result = openp (path, OPF_SEARCH_IN_PATH, p, OPEN_MODE, fullname);
+       result = openp (path, OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH, p,
+                       OPEN_MODE, fullname);
     }
 
+  do_cleanups (cleanup);
   return result;
 }
 
@@ -1277,9 +1300,8 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
                   mid_statement, get_objfile_arch (s->objfile), pc);
 
   current_source_line = line;
-  first_line_listed = line;
-  last_line_listed = line;
   current_source_symtab = s;
+  clear_lines_listed_range ();
   return 1;
 }
 \f
@@ -1471,7 +1493,11 @@ line_info (char *arg, int from_tty)
     {
       sal.symtab = current_source_symtab;
       sal.pspace = current_program_space;
-      sal.line = last_line_listed;
+      if (last_line_listed != 0)
+       sal.line = last_line_listed;
+      else
+       sal.line = current_source_line;
+
       sals.nelts = 1;
       sals.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
@@ -1612,7 +1638,7 @@ forward_search_command (char *regex, int from_tty)
       buf = xmalloc (cursize);
       p = buf;
 
-      c = getc (stream);
+      c = fgetc (stream);
       if (c == EOF)
        break;
       do
@@ -1626,7 +1652,7 @@ forward_search_command (char *regex, int from_tty)
              cursize = newsize;
            }
        }
-      while (c != '\n' && (c = getc (stream)) >= 0);
+      while (c != '\n' && (c = fgetc (stream)) >= 0);
 
       /* Remove the \r, if any, at the end of the line, otherwise
          regular expressions that end with $ or \n won't work.  */
@@ -1697,14 +1723,14 @@ reverse_search_command (char *regex, int from_tty)
       char buf[4096];          /* Should be reasonable???  */
       char *p = buf;
 
-      c = getc (stream);
+      c = fgetc (stream);
       if (c == EOF)
        break;
       do
        {
          *p++ = c;
        }
-      while (c != '\n' && (c = getc (stream)) >= 0);
+      while (c != '\n' && (c = fgetc (stream)) >= 0);
 
       /* Remove the \r, if any, at the end of the line, otherwise
          regular expressions that end with $ or \n won't work.  */
@@ -1839,9 +1865,10 @@ show_substitute_path_command (char *args, int from_tty)
   struct substitute_path_rule *rule = substitute_path_rules;
   char **argv;
   char *from = NULL;
+  struct cleanup *cleanup;
   
   argv = gdb_buildargv (args);
-  make_cleanup_freeargv (argv);
+  cleanup = make_cleanup_freeargv (argv);
 
   /* We expect zero or one argument.  */
 
@@ -1861,10 +1888,12 @@ show_substitute_path_command (char *args, int from_tty)
 
   while (rule != NULL)
     {
-      if (from == NULL || FILENAME_CMP (rule->from, from) == 0)
+      if (from == NULL || substitute_path_rule_matches (rule, from) != 0)
         printf_filtered ("  `%s' -> `%s'.\n", rule->from, rule->to);
       rule = rule->next;
     }
+
+  do_cleanups (cleanup);
 }
 
 /* Implement the "unset substitute-path" command.  */
@@ -1876,10 +1905,11 @@ unset_substitute_path_command (char *args, int from_tty)
   char **argv = gdb_buildargv (args);
   char *from = NULL;
   int rule_found = 0;
+  struct cleanup *cleanup;
 
   /* This function takes either 0 or 1 argument.  */
 
-  make_cleanup_freeargv (argv);
+  cleanup = make_cleanup_freeargv (argv);
   if (argv != NULL && argv[0] != NULL && argv[1] != NULL)
     error (_("Incorrect usage, too many arguments in command"));
 
@@ -1917,6 +1947,8 @@ unset_substitute_path_command (char *args, int from_tty)
     error (_("No substitution rule defined for `%s'"), from);
 
   forget_cached_source_info ();
+
+  do_cleanups (cleanup);
 }
 
 /* Add a new source path substitution rule.  */
@@ -1926,9 +1958,10 @@ set_substitute_path_command (char *args, int from_tty)
 {
   char **argv;
   struct substitute_path_rule *rule;
+  struct cleanup *cleanup;
   
   argv = gdb_buildargv (args);
-  make_cleanup_freeargv (argv);
+  cleanup = make_cleanup_freeargv (argv);
 
   if (argv == NULL || argv[0] == NULL || argv [1] == NULL)
     error (_("Incorrect usage, too few arguments in command"));
@@ -1955,6 +1988,8 @@ set_substitute_path_command (char *args, int from_tty)
 
   add_substitute_path_rule (argv[0], argv[1]);
   forget_cached_source_info ();
+
+  do_cleanups (cleanup);
 }
 
 \f
@@ -2044,12 +2079,15 @@ The matching line number is also stored as the value of \"$_\"."));
       add_com_alias ("?", "reverse-search", class_files, 0);
     }
 
-  add_setshow_zuinteger_unlimited_cmd ("listsize", class_support,
-                                      &lines_to_list, _("\
+  add_setshow_integer_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);
+Show number of source lines gdb will list by default."), _("\
+Use this to choose how many source lines the \"list\" displays (unless\n\
+the \"list\" argument explicitly specifies some other number).\n\
+A value of \"unlimited\", or zero, means there's no limit."),
+                           NULL,
+                           show_lines_to_list,
+                           &setlist, &showlist);
 
   add_cmd ("substitute-path", class_files, set_substitute_path_command,
            _("\
This page took 0.029075 seconds and 4 git commands to generate.