* buildsym.h (struct subfile): Add debugformat member.
[deliverable/binutils-gdb.git] / gdb / source.c
index a300f5df80ca663f46423eab00413fcc01f58e50..b86df915bc788fd2bc65390669fc3c1b2cde9fe4 100644 (file)
@@ -1,5 +1,5 @@
 /* List lines of source files for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994
+   Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -16,7 +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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -25,21 +25,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "command.h"
 #include "gdbcmd.h"
 #include "frame.h"
+#include "value.h"
 
 #include <sys/types.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/stat.h>
+#include "gdb_string.h"
+#include "gdb_stat.h"
 #include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #include "gdbcore.h"
-#include "regex.h"
+#include "gnu-regex.h"
 #include "symfile.h"
 #include "objfiles.h"
 #include "annotate.h"
-
-#ifndef DIRNAME_SEPARATOR
-#define DIRNAME_SEPARATOR ':'
-#endif
+#include "gdbtypes.h"
 
 /* Prototypes for local functions. */
 
@@ -247,7 +247,7 @@ directory_command (dirname, from_tty)
   /* FIXME, this goes to "delete dir"... */
   if (dirname == 0)
     {
-      if (query ("Reinitialize source path to empty? ", ""))
+      if (query ("Reinitialize source path to empty? "))
        {
          free (source_path);
          init_source_path ();
@@ -306,9 +306,12 @@ mod_path (dirname, which_path)
          }
       }
 
-      if (p[-1] == '/')
+#ifndef WIN32 
+      /* On win32 h:\ is different to h: */
+      if (SLASH_P (p[-1]))
        /* Sigh. "foo/" => "foo" */
        --p;
+#endif
       *p = '\0';
 
       while (p[-1] == '.')
@@ -319,7 +322,7 @@ mod_path (dirname, which_path)
              name = current_directory;
              goto append;
            }
-         else if (p[-2] == '/')
+         else if (SLASH_P (p[-2]))
            {
              if (p - name == 2)
                {
@@ -341,8 +344,8 @@ mod_path (dirname, which_path)
 
       if (name[0] == '~')
        name = tilde_expand (name);
-      else if (name[0] != '/' && name[0] != '$')
-       name = concat (current_directory, "/", name, NULL);
+      else if (!ROOTED_P (name) && name[0] != '$') 
+         name = concat (current_directory, SLASH_STRING, name, NULL);
       else
        name = savestring (name, p - name);
       make_cleanup (free, name);
@@ -446,7 +449,8 @@ source_info (ignore, from_tty)
     printf_filtered ("Contains %d line%s.\n", s->nlines,
                     s->nlines == 1 ? "" : "s");
 
-  printf_filtered("Source language is %s.\n", language_str (s->language));
+  printf_filtered ("Source language is %s.\n", language_str (s->language));
+  printf_filtered ("Compiled with %s debugging format.\n", s->debugformat);
 }
 
 
@@ -489,16 +493,24 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
   if (!path)
     path = ".";
 
-  if (try_cwd_first || string[0] == '/')
+#ifdef WIN32
+  mode |= O_BINARY;
+#endif
+
+  if (try_cwd_first || SLASH_P (string[0]))
     {
+      int i;
       filename = string;
       fd = open (filename, mode, prot);
-      if (fd >= 0 || string[0] == '/' || strchr (string, '/'))
+      if (fd >= 0)
        goto done;
+      for (i = 0; string[i]; i++)
+       if (SLASH_P (string[i]))
+         goto done;
     }
 
   /* ./foo => foo */
-  while (string[0] == '.' && string[1] == '/')
+  while (string[0] == '.' && SLASH_P (string[1]))
     string += 2;
 
   alloclen = strlen (path) + strlen (string) + 2;
@@ -513,7 +525,7 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
        len = strlen (p);
 
       if (len == 4 && p[0] == '$' && p[1] == 'c'
-                  && p[2] == 'w' && p[3] == 'd') {
+         && p[2] == 'w' && p[3] == 'd') {
        /* Name is $cwd -- insert current directory name instead.  */
        int newlen;
 
@@ -532,10 +544,10 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
       }
 
       /* Remove trailing slashes */
-      while (len > 0 && filename[len-1] == '/')
-       filename[--len] = 0;
+      while (len > 0 && SLASH_P (filename[len-1]))
+       filename[--len] = 0;
 
-      strcat (filename+len, "/");
+      strcat (filename+len, SLASH_STRING);
       strcat (filename, string);
 
       fd = open (filename, mode);
@@ -547,28 +559,35 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
     {
       if (fd < 0)
        *filename_opened = (char *) 0;
-      else if (filename[0] == '/')
+      else if (ROOTED_P (filename))
        *filename_opened = savestring (filename, strlen (filename));
       else
        {
          /* Beware the // my son, the Emacs barfs, the botch that catch... */
          
          *filename_opened = concat (current_directory, 
-                                    '/' == current_directory[strlen(current_directory)-1]? "": "/",
+                                    SLASH_CHAR
+                                    == current_directory[strlen(current_directory)-1] 
+                                    ? "": SLASH_STRING,
                                     filename, NULL);
         }
     }
-/* start-sanitize-mpw */
 #ifdef MPW
-  if (1) {
-    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");
+  /* 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
-/* end-sanitize-mpw */
+#endif /* MPW */
 
   return fd;
 }
@@ -625,7 +644,6 @@ open_source_file (s)
       if (p != s->filename)
        result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
     }
-/* start-sanitize-mpw */
 #ifdef MPW
   if (result < 0)
     {
@@ -641,8 +659,8 @@ open_source_file (s)
       if (p != s->filename)
        result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
     }
-#endif
-/* end-sanitize-mpw */
+#endif /* MPW */
+
   if (result >= 0)
     {
       fullname = s->fullname;
@@ -697,7 +715,7 @@ find_source_lines (s, desc)
   int nlines = 0;
   int lines_allocated = 1000;
   int *line_charpos;
-  long exec_mtime;
+  long mtime;
   int size;
 
   line_charpos = (int *) xmmalloc (s -> objfile -> md,
@@ -705,10 +723,16 @@ find_source_lines (s, desc)
   if (fstat (desc, &st) < 0)
     perror_with_name (s->filename);
 
-  if (exec_bfd)
+  if (s && s->objfile && s->objfile->obfd)
+    {
+      mtime = bfd_get_mtime(s->objfile->obfd);
+      if (mtime && mtime < st.st_mtime)
+       printf_filtered ("Source file is more recent than executable.\n");
+    }
+  else if (exec_bfd)
     {
-      exec_mtime = bfd_get_mtime(exec_bfd);
-      if (exec_mtime && exec_mtime < st.st_mtime)
+      mtime = bfd_get_mtime(exec_bfd);
+      if (mtime && mtime < st.st_mtime)
        printf_filtered ("Source file is more recent than executable.\n");
     }
 
@@ -718,7 +742,7 @@ find_source_lines (s, desc)
 
     /* Have to read it byte by byte to find out where the chars live */
 
-    line_charpos[0] = tell(desc);
+    line_charpos[0] = lseek (desc, 0, SEEK_CUR);
     nlines = 1;
     while (myread(desc, &c, 1)>0) 
       {
@@ -731,7 +755,7 @@ find_source_lines (s, desc)
                  (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
                                     sizeof (int) * lines_allocated);
              }
-           line_charpos[nlines++] = tell(desc);
+           line_charpos[nlines++] = lseek (desc, 0, SEEK_CUR);
          }
       }
   }
@@ -748,7 +772,9 @@ find_source_lines (s, desc)
     data = (char *) xmalloc (size);
     old_cleanups = make_cleanup (free, data);
 
-    if (myread (desc, data, size) < 0)
+    /* 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);
     end = data + size;
     p = data;
@@ -1154,6 +1180,8 @@ line_info (arg, from_tty)
   CORE_ADDR start_pc, end_pc;
   int i;
 
+  INIT_SAL (&sal);     /* initialize to zeroes */
+
   if (arg == 0)
     {
       sal.symtab = current_source_symtab;
@@ -1313,6 +1341,9 @@ forward_search_command (regex, from_tty)
        /* Match! */
        fclose (stream);
        print_source_lines (current_source_symtab, line, line+1, 0);
+       set_internalvar (lookup_internalvar ("_"),
+                        value_from_longest (builtin_type_int,
+                                            (LONGEST) line));
        current_source_line = max (line - lines_to_list / 2, 1);
        return;
       }
@@ -1386,6 +1417,9 @@ reverse_search_command (regex, from_tty)
          fclose (stream);
          print_source_lines (current_source_symtab,
                              line, line+1, 0);
+         set_internalvar (lookup_internalvar ("_"),
+                          value_from_longest (builtin_type_int,
+                                              (LONGEST) line));
          current_source_line = max (line - lines_to_list / 2, 1);
          return;
        }
@@ -1433,66 +1467,43 @@ $cdir in the path means the compilation directory of the source file.",
   add_info ("source", source_info,
            "Information about the current source file.");
 
-/* start-sanitize-mpw */
-#ifndef MPW_C
-/* end-sanitize-mpw */
   add_info ("line", line_info,
-           "Core addresses of the code for a source line.\n\
+           concat ("Core addresses of the code for a source line.\n\
 Line can be specified as\n\
   LINENUM, to list around that line in current file,\n\
   FILE:LINENUM, to list around that line in that file,\n\
   FUNCTION, to list around beginning of that function,\n\
   FILE:FUNCTION, to distinguish among like-named static functions.\n\
+", "\
 Default is to describe the last source line that was listed.\n\n\
 This sets the default address for \"x\" to the line's first instruction\n\
 so that \"x/i\" suffices to start examining the machine code.\n\
-The address is also stored as the value of \"$_\".");
-/* start-sanitize-mpw */
-#else
-  add_info ("line", line_info,
-           "Core addresses of the code for a source line. \n\
-Line can be specified as \n\
-  LINENUM, to list around that line in current file, \n\
-  FILE:LINENUM, to list around that line in that file, \n\
-Default is to describe the last source line that was listed. \n\n\
-The address is also stored as the value of \"$_\". ");
-#endif
-/* end-sanitize-mpw */
+The address is also stored as the value of \"$_\".", NULL));
 
   add_com ("forward-search", class_files, forward_search_command,
-          "Search for regular expression (see regex(3)) from last line listed.");
+          "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 ("reverse-search", class_files, reverse_search_command,
-          "Search backward for regular expression (see regex(3)) from last line listed.");
+          "Search backward for regular expression (see regex(3)) from last line listed.\n\
+The matching line number is also stored as the value of \"$_\".");
 
-/* start-sanitize-mpw */
-#ifndef MPW_C
-/* end-sanitize-mpw */
   add_com ("list", class_files, list_command,
-          "List specified function or line.\n\
+          concat ("List specified function or line.\n\
 With no argument, lists ten more lines after or around previous listing.\n\
 \"list -\" lists the ten lines before a previous ten-line listing.\n\
 One argument specifies a line, and ten lines are listed around that line.\n\
 Two arguments with comma between specify starting and ending lines to list.\n\
+", "\
 Lines can be specified in these ways:\n\
   LINENUM, to list around that line in current file,\n\
   FILE:LINENUM, to list around that line in that file,\n\
   FUNCTION, to list around beginning of that function,\n\
   FILE:FUNCTION, to distinguish among like-named static functions.\n\
   *ADDRESS, to list around the line containing that address.\n\
-With two args if one is empty it stands for ten lines away from the other arg.");
-/* start-sanitize-mpw */
-#else /* MPW_C */
-  add_com ("list", class_files, list_command,
-          "List specified function or line.\n\
-With no argument, lists ten more lines after or around previous listing. \n\
-One argument specifies a line, and ten lines are listed around that line. \n\
-Two arguments with comma between specify starting and ending lines to list. \n\
-Lines can be specified in these ways:\n\
-With two args if one is empty it stands for ten lines away from the other arg. ");
-#endif /* MPW_C */
-/* end-sanitize-mpw */
+With two args if one is empty it stands for ten lines away from the other arg.", NULL));
+
   add_com_alias ("l", "list", class_files, 1);
 
   add_show_from_set
This page took 0.029202 seconds and 4 git commands to generate.