* Rename remote-es1800.c to remote-es.c
[deliverable/binutils-gdb.git] / gdb / source.c
index e59079d4101ded9109d18d385b0462760c7d5ec6..3ea5518e252e7413613ae332e00c0d91255df531 100644 (file)
@@ -106,13 +106,13 @@ static int last_line_listed;
 static int first_line_listed;
 
 \f
-/* Set the source file default for the "list" command, specifying a
-   symtab.  Sigh.  Behavior specification: If it is called with a
-   non-zero argument, that is the symtab to select.  If it is not,
-   first lookup "main"; if it exists, use the symtab and line it
-   defines.  If not, take the last symtab in the symtab lists (if it
-   exists) or the last symtab in the psymtab lists (if *it* exists).  If
-   none of this works, report an error.   */
+/* Set the source file default for the "list" command to be S.
+
+   If S is NULL, and we don't have a default, find one.  This
+   should only be called when the user actually tries to use the
+   default, since we produce an error if we can't find a reasonable
+   default.  Also, since this can cause symbols to be read, doing it
+   before we need to would make things slower than necessary.  */
 
 void
 select_source_symtab (s)
@@ -131,6 +131,9 @@ select_source_symtab (s)
       return;
     }
 
+  if (current_source_symtab)
+    return;
+
   /* Make the default place to list be the function `main'
      if one exists.  */
   if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL))
@@ -154,7 +157,7 @@ select_source_symtab (s)
        {
          char *name = s -> filename;
          int len = strlen (name);
-         if (! (len > 2 && (strcmp (&name[len - 2], ".h") == 0)))
+         if (! (len > 2 && (STREQ (&name[len - 2], ".h"))))
            {
              current_source_symtab = s;
            }
@@ -171,7 +174,7 @@ select_source_symtab (s)
        {
          char *name = ps -> filename;
          int len = strlen (name);
-         if (! (len > 2 && (strcmp (&name[len - 2], ".h") == 0)))
+         if (! (len > 2 && (STREQ (&name[len - 2], ".h"))))
            {
              cs_pst = ps;
            }
@@ -189,9 +192,6 @@ select_source_symtab (s)
        }
     }
 
-  if (current_source_symtab)
-    return;
-
   error ("Can't find a default source file");
 }
 \f
@@ -200,7 +200,9 @@ show_directories (ignore, from_tty)
      char *ignore;
      int from_tty;
 {
-  printf_filtered ("Source directories searched: %s\n", source_path);
+  puts_filtered ("Source directories searched: ");
+  puts_filtered (source_path);
+  puts_filtered ("\n");
 }
 
 /* Forget what we learned about line positions in source files,
@@ -425,17 +427,23 @@ source_info (ignore, from_tty)
   if (s->fullname)
     printf_filtered ("Located in %s\n", s->fullname);
   if (s->nlines)
-    printf_filtered ("Contains %d lines\n", s->nlines);
+    printf_filtered ("Contains %d line%s.\n", s->nlines,
+                    s->nlines == 1 ? "" : "s");
 
-  printf_filtered("Source language %s.\n", language_str (s->language));
+  printf_filtered("Source language is %s.\n", language_str (s->language));
 }
 
 
 \f
 /* Open a file named STRING, searching path PATH (dir names sep by colons)
    using mode MODE and protection bits PROT in the calls to open.
+
    If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
-   (ie pretend the first element of PATH is ".")
+   (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).
+
    If FILENAMED_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
@@ -465,18 +473,18 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
   if (!path)
     path = ".";
 
-  /* ./foo => foo */
-  while (string[0] == '.' && string[1] == '/')
-    string += 2;
-
   if (try_cwd_first || string[0] == '/')
     {
       filename = string;
       fd = open (filename, mode, prot);
-      if (fd >= 0 || string[0] == '/')
+      if (fd >= 0 || string[0] == '/' || strchr (string, '/'))
        goto done;
     }
 
+  /* ./foo => foo */
+  while (string[0] == '.' && string[1] == '/')
+    string += 2;
+
   alloclen = strlen (path) + strlen (string) + 2;
   filename = (char *) alloca (alloclen);
   fd = -1;
@@ -614,18 +622,42 @@ find_source_lines (s, desc)
   int *line_charpos;
   long exec_mtime;
   int size;
+#ifdef LSEEK_NOT_LINEAR
+  char c;
+#endif
 
   line_charpos = (int *) xmmalloc (s -> objfile -> md,
                                   lines_allocated * sizeof (int));
   if (fstat (desc, &st) < 0)
-    perror_with_name (s->filename);
+   perror_with_name (s->filename);
 
   if (exec_bfd) {
     exec_mtime = bfd_get_mtime(exec_bfd);
     if (exec_mtime && exec_mtime < st.st_mtime)
-      printf_filtered ("Source file is more recent than executable.\n");
+     printf_filtered ("Source file is more recent than executable.\n");
   }
 
+#ifdef LSEEK_NOT_LINEAR
+  /* Have to read it byte by byte to find out where the chars live */
+
+   line_charpos[0] = tell(desc);
+   nlines = 1;
+   while (myread(desc, &c, 1)>0) 
+   {
+     if (c == '\n') 
+     {
+       if (nlines == lines_allocated) 
+       {
+        lines_allocated *= 2;
+        line_charpos =
+         (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
+                            sizeof (int) * lines_allocated);
+       }
+       line_charpos[nlines++] = tell(desc);
+     }
+   }
+
+#else
   /* st_size might be a large type, but we only support source files whose 
      size fits in an int.  FIXME. */
   size = (int) st.st_size;
@@ -637,31 +669,33 @@ find_source_lines (s, desc)
   data = (char *) alloca (size);
 #endif
   if (myread (desc, data, size) < 0)
-    perror_with_name (s->filename);
+   perror_with_name (s->filename);
   end = data + size;
   p = data;
   line_charpos[0] = 0;
   nlines = 1;
   while (p != end)
+  {
+    if (*p++ == '\n'
+       /* A newline at the end does not start a new line.  */
+       && p != end)
     {
-      if (*p++ == '\n'
-         /* A newline at the end does not start a new line.  */
-         && p != end)
-       {
-         if (nlines == lines_allocated)
-           {
-             lines_allocated *= 2;
-             line_charpos =
-                 (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
-                                    sizeof (int) * lines_allocated);
-           }
-         line_charpos[nlines++] = p - data;
-       }
+      if (nlines == lines_allocated)
+      {
+       lines_allocated *= 2;
+       line_charpos =
+        (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
+                           sizeof (int) * lines_allocated);
+      }
+      line_charpos[nlines++] = p - data;
     }
+  }
+#endif
   s->nlines = nlines;
   s->line_charpos =
-      (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
-                        nlines * sizeof (int));
+   (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos,
+                     nlines * sizeof (int));
+
 }
 
 /* Return the character position of a line LINE in symtab S.
@@ -744,19 +778,22 @@ get_filename_and_charpos (s, fullname)
    Return 1 if successful, 0 if could not find the file.  */
 
 int
-identify_source_line (s, line, mid_statement)
+identify_source_line (s, line, mid_statement, pc)
      struct symtab *s;
      int line;
      int mid_statement;
+     CORE_ADDR pc;
 {
   if (s->line_charpos == 0)
     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",
-         get_frame_pc (get_current_frame()));
+         pc);
   current_source_line = line;
   first_line_listed = line;
   last_line_listed = line;
@@ -810,7 +847,7 @@ print_source_lines (s, line, stopline, noerror)
       perror_with_name (s->filename);
     }
 
-  stream = fdopen (desc, "r");
+  stream = fdopen (desc, FOPEN_RT);
   clearerr (stream);
 
   while (nlines-- > 0)
@@ -821,7 +858,7 @@ print_source_lines (s, line, stopline, noerror)
       printf_filtered ("%d\t", current_source_line++);
       do
        {
-         if (c < 040 && c != '\t' && c != '\n')
+         if (c < 040 && c != '\t' && c != '\n' && c != '\r')
              printf_filtered ("^%c", c + 0100);
          else if (c == 0177)
            printf_filtered ("^?");
@@ -879,7 +916,7 @@ list_command (arg, from_tty)
 
   /* "l" or "l +" lists next ten lines.  */
 
-  if (arg == 0 || !strcmp (arg, "+"))
+  if (arg == 0 || STREQ (arg, "+"))
     {
       if (current_source_symtab == 0)
        error ("No default source file yet.  Do \"help list\".");
@@ -889,7 +926,7 @@ list_command (arg, from_tty)
     }
 
   /* "l -" lists previous ten lines, the ones before the ten just listed.  */
-  if (!strcmp (arg, "-"))
+  if (STREQ (arg, "-"))
     {
       if (current_source_symtab == 0)
        error ("No default source file yet.  Do \"help list\".");
@@ -979,7 +1016,7 @@ list_command (arg, from_tty)
       if (sym)
        {
          printf_filtered ("%s is in ", local_hex_string(sal.pc));
-         fprint_symbol (stdout, SYMBOL_NAME (sym));
+         fputs_filtered (SYMBOL_SOURCE_NAME (sym), stdout);
          printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line);
        }
       else
@@ -1046,10 +1083,7 @@ line_info (arg, from_tty)
     {
       sals = decode_line_spec_1 (arg, 0);
       
-      /* If this command is repeated with RET,
-        turn it into the no-arg variant.  */
-      if (from_tty)
-       *arg = 0;
+      dont_repeat ();
     }
 
   /* C++  More than one line may have been specified, as when the user
@@ -1059,9 +1093,22 @@ line_info (arg, from_tty)
       sal = sals.sals[i];
       
       if (sal.symtab == 0)
-       error ("No source file specified.");
-
-      if (sal.line > 0
+       {
+         printf_filtered ("No line number information available");
+         if (sal.pc != 0)
+           {
+             /* This is useful for "info line *0x7f34".  If we can't tell the
+                user about a source line, at least let them have the symbolic
+                address.  */
+             printf_filtered (" for address ");
+             wrap_here ("  ");
+             print_address (sal.pc, stdout);
+           }
+         else
+           printf_filtered (".");
+         printf_filtered ("\n");
+       }
+      else if (sal.line > 0
          && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
        {
          if (start_pc == end_pc)
@@ -1079,8 +1126,16 @@ line_info (arg, from_tty)
          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)
+           identify_source_line (sal.symtab, sal.line, 0, start_pc);
        }
       else
+       /* Is there any case in which we get here, and have an address
+          which the user would want to see?  If we have debugging symbols
+          and no line numbers?  */
        printf_filtered ("Line number %d is out of range for \"%s\".\n",
                         sal.line, sal.symtab->filename);
     }
@@ -1128,7 +1183,7 @@ forward_search_command (regex, from_tty)
       perror_with_name (current_source_symtab->filename);
     }
 
-  stream = fdopen (desc, "r");
+  stream = fdopen (desc, FOPEN_RT);
   clearerr (stream);
   while (1) {
 /* FIXME!!!  We walk right off the end of buf if we get a long line!!! */
@@ -1200,7 +1255,7 @@ reverse_search_command (regex, from_tty)
       perror_with_name (current_source_symtab->filename);
     }
 
-  stream = fdopen (desc, "r");
+  stream = fdopen (desc, FOPEN_RT);
   clearerr (stream);
   while (line > 1)
     {
@@ -1293,7 +1348,7 @@ Lines can be specified in these ways:\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.");
-  add_com_alias ("l", "list", class_files, 0);
+  add_com_alias ("l", "list", class_files, 1);
 
   add_show_from_set
     (add_set_cmd ("listsize", class_support, var_uinteger,
This page took 0.027141 seconds and 4 git commands to generate.