* elflink.h (elf_bfd_final_link): Check if dynobj is not NULL
[binutils-gdb.git] / gdb / source.c
index 49eb3bce6fe258a463389a2e29aa5f715186814b..dab794fb731b9140df803d933f21a77c0c6c8efa 100644 (file)
@@ -1,5 +1,6 @@
 /* List lines of source files for GDB, the GNU debugger.
-   Copyright 1986-1989, 1991-1999 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -38,6 +39,9 @@
 #include "objfiles.h"
 #include "annotate.h"
 #include "gdbtypes.h"
+#include "linespec.h"
+#include "filenames.h"         /* for DOSish file names */
+#include "completer.h"
 #ifdef UI_OUT
 #include "ui-out.h"
 #endif
@@ -150,11 +154,11 @@ select_source_symtab (register struct symtab *s)
 
   /* Make the default place to list be the function `main'
      if one exists.  */
-  if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL))
+  if (lookup_symbol (main_name (), 0, VAR_NAMESPACE, 0, NULL))
     {
-      sals = decode_line_spec ("main", 1);
+      sals = decode_line_spec (main_name (), 1);
       sal = sals.sals[0];
-      free (sals.sals);
+      xfree (sals.sals);
       current_source_symtab = sal.symtab;
       current_source_line = max (sal.line - (lines_to_list - 1), 1);
       if (current_source_symtab)
@@ -198,7 +202,9 @@ select_source_symtab (register struct symtab *s)
     {
       if (cs_pst->readin)
        {
-         internal_error ("select_source_symtab: readin pst found and no symtabs.");
+         internal_error (__FILE__, __LINE__,
+                         "select_source_symtab: "
+                         "readin pst found and no symtabs.");
        }
       else
        {
@@ -228,6 +234,7 @@ forget_cached_source_info (void)
 {
   register struct symtab *s;
   register struct objfile *objfile;
+  struct partial_symtab *pst;
 
   for (objfile = object_files; objfile != NULL; objfile = objfile->next)
     {
@@ -235,15 +242,24 @@ forget_cached_source_info (void)
        {
          if (s->line_charpos != NULL)
            {
-             mfree (objfile->md, s->line_charpos);
+             xmfree (objfile->md, s->line_charpos);
              s->line_charpos = NULL;
            }
          if (s->fullname != NULL)
            {
-             mfree (objfile->md, s->fullname);
+             xmfree (objfile->md, s->fullname);
              s->fullname = NULL;
            }
        }
+
+      ALL_OBJFILE_PSYMTABS (objfile, pst)
+      {
+       if (pst->fullname != NULL)
+         {
+           xfree (pst->fullname);
+           pst->fullname = NULL;
+         }
+      }
     }
 }
 
@@ -253,7 +269,7 @@ init_source_path (void)
   char buf[20];
 
   sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR);
-  source_path = strsave (buf);
+  source_path = xstrdup (buf);
   forget_cached_source_info ();
 }
 
@@ -268,7 +284,7 @@ directory_command (char *dirname, int from_tty)
     {
       if (from_tty && query ("Reinitialize source path to empty? "))
        {
-         free (source_path);
+         xfree (source_path);
          init_source_path ();
        }
     }
@@ -293,8 +309,8 @@ mod_path (char *dirname, char **which_path)
   if (dirname == 0)
     return;
 
-  dirname = strsave (dirname);
-  make_cleanup (free, dirname);
+  dirname = xstrdup (dirname);
+  make_cleanup (xfree, dirname);
 
   do
     {
@@ -326,12 +342,12 @@ mod_path (char *dirname, char **which_path)
          }
       }
 
-      if (!(SLASH_P (*name) && p <= name + 1)  /* "/" */
-#if defined(_WIN32) || defined(__MSDOS__)
+      if (!(IS_DIR_SEPARATOR (*name) && p <= name + 1)  /* "/" */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
       /* On MS-DOS and MS-Windows, h:\ is different from h: */
-         && !(!SLASH_P (*name) && ROOTED_P (name) && p <= name + 3)    /* d:/ */
+         && !(p == name + 3 && name[1] == ':')          /* "d:/" */
 #endif
-         && SLASH_P (p[-1]))
+         && IS_DIR_SEPARATOR (p[-1]))
        /* Sigh. "foo/" => "foo" */
        --p;
       *p = '\0';
@@ -344,7 +360,7 @@ mod_path (char *dirname, char **which_path)
              name = current_directory;
              goto append;
            }
-         else if (p > name + 1 && SLASH_P (p[-2]))
+         else if (p > name + 1 && IS_DIR_SEPARATOR (p[-2]))
            {
              if (p - name == 2)
                {
@@ -366,15 +382,15 @@ mod_path (char *dirname, char **which_path)
 
       if (name[0] == '~')
        name = tilde_expand (name);
-#if defined(_WIN32) || defined(__MSDOS__)
-      else if (ROOTED_P (name) && p == name + 2)       /* "d:" => "d:." */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+      else if (IS_ABSOLUTE_PATH (name) && p == name + 2) /* "d:" => "d:." */
        name = concat (name, ".", NULL);
 #endif
-      else if (!ROOTED_P (name) && name[0] != '$')
+      else if (!IS_ABSOLUTE_PATH (name) && name[0] != '$')
        name = concat (current_directory, SLASH_STRING, name, NULL);
       else
        name = savestring (name, p - name);
-      make_cleanup (free, name);
+      make_cleanup (xfree, name);
 
       /* Unless it's a variable, check existence.  */
       if (name[0] != '$')
@@ -447,14 +463,14 @@ mod_path (char *dirname, char **which_path)
                old[prefix] = c;
                *which_path = concat (temp, "", &old[prefix], NULL);
                prefix = strlen (temp);
-               free (temp);
+               xfree (temp);
              }
            else
              {
                *which_path = concat (name, (old[0] ? tinybuf : old), old, NULL);
                prefix = strlen (name);
              }
-           free (old);
+           xfree (old);
            old = *which_path;
          }
       }
@@ -498,7 +514,7 @@ source_info (char *ignore, int from_tty)
    so that "exec-file ./foo" or "symbol-file ./foo" insures that you
    get that particular version of foo or an error message).
 
-   If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
+   If FILENAME_OPENED is non-null, set it to a newly allocated string naming
    the actual file opened (this string will always start with a "/".  We
    have to take special pains to avoid doubling the "/" between the directory
    and the file, sigh!  Emacs gets confuzzed by this when we print the
@@ -510,44 +526,47 @@ source_info (char *ignore, int from_tty)
 /*  >>>> This should only allow files of certain types,
    >>>>  eg executable, non-directory */
 int
-openp (char *path, int try_cwd_first, char *string, int mode, int prot,
+openp (const char *path, int try_cwd_first, const char *string,
+       int mode, int prot,
        char **filename_opened)
 {
   register int fd;
   register char *filename;
-  register char *p, *p1;
+  const char *p;
+  const char *p1;
   register int len;
   int alloclen;
 
   if (!path)
     path = ".";
 
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
   mode |= O_BINARY;
 #endif
 
-  if (try_cwd_first || ROOTED_P (string))
+  if (try_cwd_first || IS_ABSOLUTE_PATH (string))
     {
       int i;
-      filename = string;
+      filename = alloca (strlen (string) + 1);
+      strcpy (filename, string);
       fd = open (filename, mode, prot);
       if (fd >= 0)
        goto done;
       for (i = 0; string[i]; i++)
-       if (SLASH_P (string[i]))
+       if (IS_DIR_SEPARATOR (string[i]))
          goto done;
     }
 
   /* ./foo => foo */
-  while (string[0] == '.' && SLASH_P (string[1]))
+  while (string[0] == '.' && IS_DIR_SEPARATOR (string[1]))
     string += 2;
 
   alloclen = strlen (path) + strlen (string) + 2;
-  filename = (char *) alloca (alloclen);
+  filename = alloca (alloclen);
   fd = -1;
   for (p = path; p; p = p1 ? p1 + 1 : 0)
     {
-      p1 = (char *) strchr (p, DIRNAME_SEPARATOR);
+      p1 = strchr (p, DIRNAME_SEPARATOR);
       if (p1)
        len = p1 - p;
       else
@@ -565,7 +584,7 @@ openp (char *path, int try_cwd_first, char *string, int mode, int prot,
          if (newlen > alloclen)
            {
              alloclen = newlen;
-             filename = (char *) alloca (alloclen);
+             filename = alloca (alloclen);
            }
          strcpy (filename, current_directory);
        }
@@ -577,7 +596,7 @@ openp (char *path, int try_cwd_first, char *string, int mode, int prot,
        }
 
       /* Remove trailing slashes */
-      while (len > 0 && SLASH_P (filename[len - 1]))
+      while (len > 0 && IS_DIR_SEPARATOR (filename[len - 1]))
        filename[--len] = 0;
 
       strcat (filename + len, SLASH_STRING);
@@ -592,35 +611,37 @@ done:
   if (filename_opened)
     {
       if (fd < 0)
-       *filename_opened = (char *) 0;
-      else if (ROOTED_P (filename))
-       *filename_opened = savestring (filename, strlen (filename));
+       *filename_opened = NULL;
+      else if (IS_ABSOLUTE_PATH (filename))
+       *filename_opened = gdb_realpath (filename);
       else
        {
          /* Beware the // my son, the Emacs barfs, the botch that catch... */
 
-         *filename_opened = concat (current_directory,
-                SLASH_P (current_directory[strlen (current_directory) - 1])
+         char *f = concat (current_directory,
+           IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
                                     ? "" : SLASH_STRING,
                                     filename, NULL);
+         *filename_opened = gdb_realpath (f);
+         xfree (f);
        }
     }
-#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)
-      {
-       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 */
+  /* OBSOLETE #ifdef MPW  */
+  /* OBSOLETE This is a debugging hack that can go away when all combinations */
+  /* OBSOLETE of Mac and Unix names are handled reasonably.  */
+  /* OBSOLETE   { */
+  /* OBSOLETE     extern int debug_openp; */
+  /* OBSOLETE  */
+  /* OBSOLETE     if (debug_openp) */
+  /* OBSOLETE       { */
+  /* OBSOLETE  printf ("openp on %s, path %s mode %d prot %d\n  returned %d", */
+  /* OBSOLETE          string, path, mode, prot, fd); */
+  /* OBSOLETE  if (*filename_opened) */
+  /* OBSOLETE    printf (" (filename is %s)", *filename_opened); */
+  /* OBSOLETE  printf ("\n"); */
+  /* OBSOLETE       } */
+  /* OBSOLETE   } */
+  /* OBSOLETE #endif  *//* MPW */
 
   return fd;
 }
@@ -662,7 +683,7 @@ int
 open_source_file (struct symtab *s)
 {
   char *path = source_path;
-  char *p;
+  const char *p;
   int result;
   char *fullname;
 
@@ -673,7 +694,7 @@ open_source_file (struct symtab *s)
       if (result >= 0)
        return result;
       /* Didn't work -- free old one, try again. */
-      mfree (s->objfile->md, s->fullname);
+      xmfree (s->objfile->md, s->fullname);
       s->fullname = NULL;
     }
 
@@ -702,32 +723,32 @@ open_source_file (struct symtab *s)
   if (result < 0)
     {
       /* Didn't work.  Try using just the basename. */
-      p = basename (s->filename);
+      p = lbasename (s->filename);
       if (p != s->filename)
        result = openp (path, 0, p, OPEN_MODE, 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, OPEN_MODE, 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, OPEN_MODE, 0, &s->fullname);
-    }
-#endif /* MPW */
+  /* OBSOLETE #ifdef MPW */
+  /* OBSOLETE   if (result < 0) */
+  /* OBSOLETE     { */
+  /* OBSOLETE        *//* Didn't work.  Try using just the MPW basename. */
+  /* OBSOLETE       p = (char *) mpw_basename (s->filename); */
+  /* OBSOLETE       if (p != s->filename) */
+  /* OBSOLETE  result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname); */
+  /* OBSOLETE     } */
+  /* OBSOLETE   if (result < 0) */
+  /* OBSOLETE     { */
+  /* OBSOLETE        *//* Didn't work.  Try using the mixed Unix/MPW basename. */
+  /* OBSOLETE       p = (char *) mpw_mixed_basename (s->filename); */
+  /* OBSOLETE       if (p != s->filename) */
+  /* OBSOLETE  result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname); */
+  /* OBSOLETE     } */
+  /* OBSOLETE #endif MPW */
 
   if (result >= 0)
     {
       fullname = s->fullname;
       s->fullname = mstrsave (s->objfile->md, s->fullname);
-      free (fullname);
+      xfree (fullname);
     }
   return result;
 }
@@ -789,8 +810,6 @@ find_source_lines (struct symtab *s, int desc)
 
   if (mtime && mtime < st.st_mtime)
     {
-      if (tui_version)
-       printf_filtered ("\n");
       warning ("Source file is more recent than executable.\n");
     }
 
@@ -828,7 +847,7 @@ find_source_lines (struct symtab *s, int desc)
     /* 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);
+    old_cleanups = make_cleanup (xfree, data);
 
     /* Reassign `size' to result of read for systems where \r\n -> \n.  */
     size = myread (desc, data, size);
@@ -1126,31 +1145,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
 void
 print_source_lines (struct symtab *s, int line, int stopline, int noerror)
 {
-#if defined(TUI)
-  if (!tui_version ||
-      m_winPtrIsNull (srcWin) || !srcWin->generic.isVisible)
-    print_source_lines_base (s, line, stopline, noerror);
-  else
-    {
-      TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
-extern void tui_vAddWinToLayout (va_list);
-extern void tui_vUpdateSourceWindowsWithLine (va_list);
-
-      /* Regardless of whether we can open the file,
-         set current_source_symtab. */
-      current_source_symtab = s;
-      current_source_line = line;
-      first_line_listed = line;
-
-      /* make sure that the source window is displayed */
-      tuiDo ((TuiOpaqueFuncPtr) tui_vAddWinToLayout, SRC_WIN);
-
-      tuiDo ((TuiOpaqueFuncPtr) tui_vUpdateSourceWindowsWithLine, s, line);
-      tuiDo ((TuiOpaqueFuncPtr) tui_vUpdateLocatorFilename, s->filename);
-    }
-#else
   print_source_lines_base (s, line, stopline, noerror);
-#endif
 }
 \f
 
@@ -1231,12 +1226,12 @@ list_command (char *arg, int from_tty)
       if (sals.nelts > 1)
        {
          ambiguous_line_spec (&sals);
-         free (sals.sals);
+         xfree (sals.sals);
          return;
        }
 
       sal = sals.sals[0];
-      free (sals.sals);
+      xfree (sals.sals);
     }
 
   /* Record whether the BEG arg is all digits.  */
@@ -1265,11 +1260,11 @@ list_command (char *arg, int from_tty)
          if (sals_end.nelts > 1)
            {
              ambiguous_line_spec (&sals_end);
-             free (sals_end.sals);
+             xfree (sals_end.sals);
              return;
            }
          sal_end = sals_end.sals[0];
-         free (sals_end.sals);
+         xfree (sals_end.sals);
        }
     }
 
@@ -1440,7 +1435,7 @@ line_info (char *arg, int from_tty)
        printf_filtered ("Line number %d is out of range for \"%s\".\n",
                         sal.line, sal.symtab->filename);
     }
-  free (sals.sals);
+  xfree (sals.sals);
 }
 \f
 /* Commands to search the source file for a regexp.  */
@@ -1455,29 +1450,7 @@ forward_search_command (char *regex, int from_tty)
   int line;
   char *msg;
 
-#if defined(TUI)
-  /* 
-     ** If this is the TUI, search from the first line displayed in 
-     ** the source window, otherwise, search from last_line_listed+1 
-     ** in current_source_symtab 
-   */
-  if (!tui_version)
-    line = last_line_listed;
-  else
-    {
-      if (srcWin->generic.isVisible && srcWin->generic.contentSize > 0)
-       line = ((TuiWinContent)
-        srcWin->generic.content)[0]->whichElement.source.lineOrAddr.lineNo;
-      else
-       {
-         printf_filtered ("No source displayed.\nExpression not found.\n");
-         return;
-       }
-    }
-  line++;
-#else
   line = last_line_listed + 1;
-#endif
 
   msg = (char *) re_comp (regex);
   if (msg)
@@ -1549,8 +1522,6 @@ forward_search_command (char *regex, int from_tty)
        {
          /* Match! */
          fclose (stream);
-         if (tui_version)
-           print_source_lines_base (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,
@@ -1574,29 +1545,8 @@ reverse_search_command (char *regex, int from_tty)
   register FILE *stream;
   int line;
   char *msg;
-#if defined(TUI)
-  /*
-     ** If this is the TUI, search from the first line displayed in
-     ** the source window, otherwise, search from last_line_listed-1
-     ** in current_source_symtab
-   */
-  if (!tui_version)
-    line = last_line_listed;
-  else
-    {
-      if (srcWin->generic.isVisible && srcWin->generic.contentSize > 0)
-       line = ((TuiWinContent)
-        srcWin->generic.content)[0]->whichElement.source.lineOrAddr.lineNo;
-      else
-       {
-         printf_filtered ("No source displayed.\nExpression not found.\n");
-         return;
-       }
-    }
-  line--;
-#else
+
   line = last_line_listed - 1;
-#endif
 
   msg = (char *) re_comp (regex);
   if (msg)
@@ -1657,8 +1607,6 @@ reverse_search_command (char *regex, int from_tty)
        {
          /* Match! */
          fclose (stream);
-         if (tui_version)
-           print_source_lines_base (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,