* aout64.h (BMAGIC): Define.
[deliverable/binutils-gdb.git] / gdb / source.c
index 3ea5518e252e7413613ae332e00c0d91255df531..50eb1279fb1be365a6b16064d504e6b459ab5684 100644 (file)
@@ -25,10 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcmd.h"
 #include "frame.h"
 
-#ifdef USG
 #include <sys/types.h>
-#endif
-
 #include <string.h>
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -37,6 +34,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "regex.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "annotate.h"
+
+#ifndef DIRNAME_SEPARATOR
+#define DIRNAME_SEPARATOR ':'
+#endif
 
 /* Prototypes for local functions. */
 
@@ -237,7 +239,10 @@ forget_cached_source_info ()
 void
 init_source_path ()
 {
-  source_path = savestring ("$cdir:$cwd", /* strlen of it */ 10);
+  char buf[20];
+
+  sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR);
+  source_path = strsave (buf);
   forget_cached_source_info ();
 }
 
@@ -288,7 +293,7 @@ mod_path (dirname, which_path)
       struct stat st;
 
       {
-       char *colon = strchr (name, ':');
+       char *colon = strchr (name, DIRNAME_SEPARATOR);
        char *space = strchr (name, ' ');
        char *tab = strchr (name, '\t');
        if (colon == 0 && space == 0 && tab ==  0)
@@ -303,7 +308,7 @@ mod_path (dirname, which_path)
            if (tab != 0 && (p == 0 || tab < p))
              p = tab;
            dirname = p + 1;
-           while (*dirname == ':' || *dirname == ' ' || *dirname == '\t')
+           while (*dirname == DIRNAME_SEPARATOR || *dirname == ' ' || *dirname == '\t')
              ++dirname;
          }
       }
@@ -351,10 +356,23 @@ mod_path (dirname, which_path)
 
       /* Unless it's a variable, check existence.  */
       if (name[0] != '$') {
+       /* These are warnings, not errors, since we don't want a
+          non-existent directory in a .gdbinit file to stop processing
+          of the .gdbinit file.
+
+          Whether they get added to the path is more debatable.  Current
+          answer is yes, in case the user wants to go make the directory
+          or whatever.  If the directory continues to not exist/not be
+          a directory/etc, then having them in the path should be
+          harmless.  */
        if (stat (name, &st) < 0)
-         perror_with_name (name);
-       if ((st.st_mode & S_IFMT) != S_IFDIR)
-         error ("%s is not a directory.", name);
+         {
+           int save_errno = errno;
+           fprintf_unfiltered (gdb_stderr, "Warning: ");
+           print_sys_errmsg (name, save_errno);
+         }
+       else if ((st.st_mode & S_IFMT) != S_IFDIR)
+         warning ("%s is not a directory.", name);
       }
 
     append:
@@ -365,7 +383,7 @@ mod_path (dirname, which_path)
        while (1)
          {
            if (!strncmp (p, name, len)
-               && (p[len] == '\0' || p[len] == ':'))
+               && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR))
              {
                /* Found it in the search path, remove old copy */
                if (p > *which_path)
@@ -374,7 +392,7 @@ mod_path (dirname, which_path)
                  goto skip_dup;        /* Same dir twice in one cmd */
                strcpy (p, &p[len+1]);  /* Copy from next \0 or  : */
              }
-           p = strchr (p, ':');
+           p = strchr (p, DIRNAME_SEPARATOR);
            if (p != 0)
              ++p;
            else
@@ -382,6 +400,11 @@ mod_path (dirname, which_path)
          }
        if (p == 0)
          {
+           char tinybuf[2];
+
+           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)
              {
@@ -389,7 +412,7 @@ mod_path (dirname, which_path)
 
                c = old[prefix];
                old[prefix] = '\0';
-               temp = concat (old, ":", name, NULL);
+               temp = concat (old, tinybuf, name, NULL);
                old[prefix] = c;
                *which_path = concat (temp, "", &old[prefix], NULL);
                prefix = strlen (temp);
@@ -397,7 +420,7 @@ mod_path (dirname, which_path)
              }
            else
              {
-               *which_path = concat (name, (old[0]? ":" : old), old, NULL);
+               *which_path = concat (name, (old[0] ? tinybuf : old), old, NULL);
                prefix = strlen (name);
              }
            free (old);
@@ -435,7 +458,7 @@ source_info (ignore, from_tty)
 
 
 \f
-/* Open a file named STRING, searching path PATH (dir names sep by colons)
+/* Open a file named STRING, searching path PATH (dir names sep by some char)
    using mode MODE and protection bits PROT in the calls to open.
 
    If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
@@ -490,7 +513,7 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
   fd = -1;
   for (p = path; p; p = p1 ? p1 + 1 : 0)
     {
-      p1 = (char *) strchr (p, ':');
+      p1 = (char *) strchr (p, DIRNAME_SEPARATOR);
       if (p1)
        len = p1 - p;
       else
@@ -522,7 +545,7 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
       strcat (filename+len, "/");
       strcat (filename, string);
 
-      fd = open (filename, mode, prot);
+      fd = open (filename, mode);
       if (fd >= 0) break;
     }
 
@@ -574,8 +597,8 @@ open_source_file (s)
       /* We cast strstr's result in case an ANSIhole has made it const,
         which produces a "required warning" when assigned to a nonconst. */
       p = (char *)strstr (source_path, "$cdir");
-      if (p && (p == path || p[-1] == ':')
-           && (p[cdir_len] == ':' || p[cdir_len] == '\0')) {
+      if (p && (p == path || p[-1] == DIRNAME_SEPARATOR)
+           && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0')) {
        int len;
 
        path = (char *)
@@ -593,12 +616,12 @@ open_source_file (s)
       /* Didn't work.  Try using just the basename. */
       p = basename (s->filename);
       if (p != s->filename)
-       result = openp(path, 0, p, O_RDONLY,0, &s->fullname);
+       result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
     }
   if (result >= 0)
     {
-      fullname = s -> fullname;
-      s -> fullname = mstrsave (s -> objfile -> md, s -> fullname);
+      fullname = s->fullname;
+      s->fullname = mstrsave (s->objfile->md, s->fullname);
       free (fullname);
     }
   return result;
@@ -788,12 +811,12 @@ identify_source_line (s, line, mid_statement, pc)
     get_filename_and_charpos (s, (char **)NULL);
   if (s->fullname == 0)
     return 0;
-  if (line >= s->nlines) 
-   return 0;
-  printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname,
-         line, s->line_charpos[line - 1],
-         mid_statement ? "middle" : "beg",
-         pc);
+  if (line > s->nlines)
+    /* Don't index off the end of the line_charpos array.  */
+    return 0;
+  annotate_source (s->fullname, line, s->line_charpos[line - 1],
+                  mid_statement, pc);
+
   current_source_line = line;
   first_line_listed = line;
   last_line_listed = line;
@@ -947,7 +970,7 @@ list_command (arg, from_tty)
     dummy_beg = 1;
   else
     {
-      sals = decode_line_1 (&arg1, 0, 0, 0);
+      sals = decode_line_1 (&arg1, 0, 0, 0, 0);
 
       if (! sals.nelts) return;  /*  C++  */
       if (sals.nelts > 1)
@@ -979,9 +1002,9 @@ list_command (arg, from_tty)
       else
        {
          if (dummy_beg)
-           sals_end = decode_line_1 (&arg1, 0, 0, 0);
+           sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
          else
-           sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
+           sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
          if (sals_end.nelts == 0) 
            return;
          if (sals_end.nelts > 1)
@@ -1011,18 +1034,23 @@ list_command (arg, from_tty)
   if (*arg == '*')
     {
       if (sal.symtab == 0)
-       error ("No source file for address %s.", local_hex_string(sal.pc));
+       /* FIXME-32x64--assumes sal.pc fits in long.  */
+       error ("No source file for address %s.",
+               local_hex_string((unsigned long) sal.pc));
       sym = find_pc_function (sal.pc);
       if (sym)
        {
-         printf_filtered ("%s is in ", local_hex_string(sal.pc));
-         fputs_filtered (SYMBOL_SOURCE_NAME (sym), stdout);
+         print_address_numeric (sal.pc, 1, gdb_stdout);
+         printf_filtered (" is in ");
+         fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
          printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
        }
       else
-       printf_filtered ("%s is at %s:%d.\n",
-                        local_hex_string(sal.pc), 
-                        sal.symtab->filename, sal.line);
+       {
+         print_address_numeric (sal.pc, 1, gdb_stdout);
+         printf_filtered (" is at %s:%d.\n",
+                          sal.symtab->filename, sal.line);
+       }
     }
 
   /* If line was not specified by just a line number,
@@ -1102,34 +1130,47 @@ line_info (arg, from_tty)
                 address.  */
              printf_filtered (" for address ");
              wrap_here ("  ");
-             print_address (sal.pc, stdout);
+             print_address (sal.pc, gdb_stdout);
            }
          else
            printf_filtered (".");
          printf_filtered ("\n");
        }
       else if (sal.line > 0
-         && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
+              && find_line_pc_range (sal, &start_pc, &end_pc))
        {
          if (start_pc == end_pc)
-           printf_filtered ("Line %d of \"%s\" is at pc %s but contains no code.\n",
-                            sal.line, sal.symtab->filename, local_hex_string(start_pc));
+           {
+             printf_filtered ("Line %d of \"%s\"",
+                              sal.line, sal.symtab->filename);
+             wrap_here ("  ");
+             printf_filtered (" is at address ");
+             print_address (start_pc, gdb_stdout);
+             wrap_here ("  ");
+             printf_filtered (" but contains no code.\n");
+           }
          else
            {
-             printf_filtered ("Line %d of \"%s\" starts at pc %s",
-                              sal.line, sal.symtab->filename, 
-                              local_hex_string(start_pc));
-             printf_filtered (" and ends at %s.\n",
-                              local_hex_string(end_pc));
+             printf_filtered ("Line %d of \"%s\"",
+                              sal.line, sal.symtab->filename);
+             wrap_here ("  ");
+             printf_filtered (" starts at address ");
+             print_address (start_pc, gdb_stdout);
+             wrap_here ("  ");
+             printf_filtered (" and ends at ");
+             print_address (end_pc, gdb_stdout);
+             printf_filtered (".\n");
            }
+
          /* x/i should display this line's code.  */
          set_next_address (start_pc);
+
          /* Repeating "info line" should do the following line.  */
          last_line_listed = sal.line + 1;
 
          /* If this is the only line, show the source code.  If it could
             not find the file, don't do anything special.  */
-         if (frame_file_full_name && sals.nelts == 1)
+         if (annotation_level && sals.nelts == 1)
            identify_source_line (sal.symtab, sal.line, 0, start_pc);
        }
       else
@@ -1139,6 +1180,7 @@ line_info (arg, from_tty)
        printf_filtered ("Line number %d is out of range for \"%s\".\n",
                         sal.line, sal.symtab->filename);
     }
+  free (sals.sals);
 }
 \f
 /* Commands to search the source file for a regexp.  */
@@ -1297,15 +1339,24 @@ reverse_search_command (regex, from_tty)
 void
 _initialize_source ()
 {
+  struct cmd_list_element *c;
   current_source_symtab = 0;
   init_source_path ();
 
-  add_com ("directory", class_files, directory_command,
+  /* The intention is to use POSIX Basic Regular Expressions.
+     Always use the GNU regex routine for consistency across all hosts.
+     Our current GNU regex.c does not have all the POSIX features, so this is
+     just an approximation.  */
+  re_set_syntax (RE_SYNTAX_GREP);
+
+  c = add_cmd ("directory", class_files, directory_command,
           "Add directory DIR to beginning of search path for source files.\n\
 Forget cached info on source file locations and line positions.\n\
 DIR can also be $cwd for the current working directory, or $cdir for the\n\
 directory in which the source file was compiled into object code.\n\
-With no argument, reset the search path to $cdir:$cwd, the default.");
+With no argument, reset the search path to $cdir:$cwd, the default.",
+              &cmdlist);
+  c->completer = filename_completer;
 
   add_cmd ("directories", no_class, show_directories,
           "Current search path for finding source files.\n\
This page took 0.029538 seconds and 4 git commands to generate.