summaryrefslogtreecommitdiffstats
path: root/contrib/gdb/gdb/source.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gdb/gdb/source.c')
-rw-r--r--contrib/gdb/gdb/source.c324
1 files changed, 271 insertions, 53 deletions
diff --git a/contrib/gdb/gdb/source.c b/contrib/gdb/gdb/source.c
index 5e7af03..9fe9742 100644
--- a/contrib/gdb/gdb/source.c
+++ b/contrib/gdb/gdb/source.c
@@ -1,5 +1,5 @@
/* List lines of source files for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 88, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
@@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/types.h>
#include "gdb_string.h"
-#include <sys/param.h>
#include "gdb_stat.h"
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
@@ -42,9 +41,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "annotate.h"
#include "gdbtypes.h"
-/* Prototypes for local functions. */
+#ifdef CRLF_SOURCE_FILES
+
+/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
+ host use \r\n rather than just \n. Defining CRLF_SOURCE_FILES is
+ much faster than defining LSEEK_NOT_LINEAR. */
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#define OPEN_MODE (O_RDONLY | O_BINARY)
+#define FDOPEN_MODE FOPEN_RB
+
+#else /* ! defined (CRLF_SOURCE_FILES) */
+
+#define OPEN_MODE O_RDONLY
+#define FDOPEN_MODE FOPEN_RT
-static int open_source_file PARAMS ((struct symtab *));
+#endif /* ! defined (CRLF_SOURCE_FILES) */
+
+/* Forward declarations */
+
+int open_source_file PARAMS ((struct symtab *));
+
+void find_source_lines PARAMS ((struct symtab *, int));
+
+/* Prototypes for exported functions. */
+
+void _initialize_source PARAMS ((void));
+
+/* Prototypes for local functions. */
static int get_filename_and_charpos PARAMS ((struct symtab *, char **));
@@ -62,13 +89,6 @@ static void source_info PARAMS ((char *, int));
static void show_directories PARAMS ((char *, int));
-static void find_source_lines PARAMS ((struct symtab *, int));
-
-/* If we use this declaration, it breaks because of fucking ANSI "const" stuff
- on some systems. We just have to not declare it at all, have it default
- to int, and possibly botch on a few systems. Thanks, ANSIholes... */
-/* extern char *strstr(); */
-
/* Path of directories to search for source files.
Same format as the PATH environment variable's value. */
@@ -99,6 +119,12 @@ static int last_line_listed;
static int first_line_listed;
+/* Saves the name of the last source file visited and a possible error code.
+ Used to prevent repeating annoying "No such file or directories" msgs */
+
+static struct symtab *last_source_visited = NULL;
+static int last_source_error = 0;
+
/* Set the source file default for the "list" command to be S.
@@ -185,6 +211,8 @@ select_source_symtab (s)
current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst);
}
}
+ if (current_source_symtab)
+ return;
error ("Can't find a default source file");
}
@@ -255,7 +283,10 @@ directory_command (dirname, from_tty)
}
}
else
- mod_path (dirname, &source_path);
+ {
+ mod_path (dirname, &source_path);
+ last_source_visited = NULL;
+ }
if (from_tty)
show_directories ((char *)0, from_tty);
forget_cached_source_info ();
@@ -307,7 +338,7 @@ mod_path (dirname, which_path)
}
}
-#ifndef WIN32
+#ifndef _WIN32
/* On win32 h:\ is different to h: */
if (SLASH_P (p[-1]))
/* Sigh. "foo/" => "foo" */
@@ -450,7 +481,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);
}
@@ -493,7 +525,7 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
if (!path)
path = ".";
-#ifdef WIN32
+#ifdef _WIN32
mode |= O_BINARY;
#endif
@@ -592,10 +624,42 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened)
return fd;
}
+
+/* This is essentially a convenience, for clients that want the behaviour
+ of openp, using source_path, but that really don't want the file to be
+ opened but want instead just to know what the full pathname is (as
+ qualified against source_path).
+
+ The current working directory is searched first.
+
+ If the file was found, this function returns 1, and FULL_PATHNAME is
+ set to the fully-qualified pathname.
+
+ Else, this functions returns 0, and FULL_PATHNAME is set to NULL.
+ */
+int
+source_full_path_of (filename, full_pathname)
+ char * filename;
+ char ** full_pathname;
+{
+ int fd;
+
+ fd = openp (source_path, 1, filename, O_RDONLY, 0, full_pathname);
+ if (fd < 0)
+ {
+ *full_pathname = NULL;
+ return 0;
+ }
+
+ close (fd);
+ return 1;
+}
+
+
/* Open a source file given a symtab S. Returns a file descriptor or
negative number for error. */
-static int
+int
open_source_file (s)
struct symtab *s;
{
@@ -607,7 +671,7 @@ open_source_file (s)
/* Quick way out if we already know its full name */
if (s->fullname)
{
- result = open (s->fullname, O_RDONLY);
+ result = open (s->fullname, OPEN_MODE);
if (result >= 0)
return result;
/* Didn't work -- free old one, try again. */
@@ -636,13 +700,13 @@ open_source_file (s)
}
}
- result = openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname);
+ result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
if (result < 0)
{
/* 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, OPEN_MODE, 0, &s->fullname);
}
#ifdef MPW
if (result < 0)
@@ -650,14 +714,14 @@ open_source_file (s)
/* Didn't work. Try using just the MPW basename. */
p = (char *) mpw_basename (s->filename);
if (p != s->filename)
- result = openp (path, 0, p, O_RDONLY, 0, &s->fullname);
+ 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, O_RDONLY, 0, &s->fullname);
+ result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
}
#endif /* MPW */
@@ -705,7 +769,7 @@ symtab_to_filename (s)
to be open on descriptor DESC.
All set S->nlines to the number of such lines. */
-static void
+void
find_source_lines (s, desc)
struct symtab *s;
int desc;
@@ -715,7 +779,7 @@ find_source_lines (s, desc)
int nlines = 0;
int lines_allocated = 1000;
int *line_charpos;
- long exec_mtime;
+ long mtime = 0;
int size;
line_charpos = (int *) xmmalloc (s -> objfile -> md,
@@ -723,11 +787,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);
+ else if (exec_bfd)
+ mtime = bfd_get_mtime(exec_bfd);
+
+ if (mtime && mtime < st.st_mtime)
{
- 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");
+ if (tui_version)
+ printf_filtered ("\n");
+ warning("Source file is more recent than executable.\n");
}
#ifdef LSEEK_NOT_LINEAR
@@ -766,7 +835,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;
@@ -900,12 +971,13 @@ identify_source_line (s, line, mid_statement, pc)
current_source_symtab = s;
return 1;
}
+
/* Print source lines from the file of symtab S,
- starting with line number LINE and stopping before line number STOPLINE. */
+ starting with line number LINE and stopping before line number STOPLINE. */
-void
-print_source_lines (s, line, stopline, noerror)
+static void
+print_source_lines_base (s, line, stopline, noerror)
struct symtab *s;
int line, stopline;
int noerror;
@@ -920,17 +992,37 @@ print_source_lines (s, line, stopline, noerror)
current_source_line = line;
first_line_listed = line;
- desc = open_source_file (s);
+
+ /* Only prints "No such file or directory" once */
+ if ((s != last_source_visited) || (! last_source_error))
+ {
+ last_source_visited = s;
+ desc = open_source_file (s);
+ }
+ else
+ {
+ desc = last_source_error;
+ noerror = 1;
+ }
+
if (desc < 0)
{
- if (! noerror) {
- char *name = alloca (strlen (s->filename) + 100);
- sprintf (name, "%s:%d", s->filename, line);
- print_sys_errmsg (name, errno);
- }
+ last_source_error = desc;
+
+ if (! noerror)
+ {
+ char *name = alloca (strlen (s->filename) + 100);
+ sprintf (name, "%d\t%s", line, s->filename);
+ print_sys_errmsg (name, errno);
+ }
+ else
+ printf_filtered ("%d\tin %s\n", line, s->filename);
+
return;
}
+ last_source_error = 0;
+
if (s->line_charpos == 0)
find_source_lines (s, desc);
@@ -947,7 +1039,7 @@ print_source_lines (s, line, stopline, noerror)
perror_with_name (s->filename);
}
- stream = fdopen (desc, FOPEN_RT);
+ stream = fdopen (desc, FDOPEN_MODE);
clearerr (stream);
while (nlines-- > 0)
@@ -959,9 +1051,15 @@ print_source_lines (s, line, stopline, noerror)
do
{
if (c < 040 && c != '\t' && c != '\n' && c != '\r')
- printf_filtered ("^%c", c + 0100);
+ printf_filtered ("^%c", c + 0100);
else if (c == 0177)
printf_filtered ("^?");
+#ifdef CRLF_SOURCE_FILES
+ else if (c == '\r')
+ {
+ /* Just skip \r characters. */
+ }
+#endif
else
printf_filtered ("%c", c);
} while (c != '\n' && (c = fgetc (stream)) >= 0);
@@ -970,6 +1068,43 @@ print_source_lines (s, line, stopline, noerror)
fclose (stream);
}
+/* Show source lines from the file of symtab S, starting with line
+ number LINE and stopping before line number STOPLINE. If this is the
+ not the command line version, then the source is shown in the source
+ window otherwise it is simply printed */
+
+void
+print_source_lines (s, line, stopline, noerror)
+ struct symtab *s;
+ int line, stopline, 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 PARAMS ((va_list));
+ extern void tui_vUpdateSourceWindowsWithLine PARAMS ((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
+}
+
/* Print a list of files and line numbers which a user may choose from
@@ -1149,9 +1284,19 @@ list_command (arg, from_tty)
else if (sal.symtab == 0)
error ("No default source file yet. Do \"help list\".");
else if (no_end)
- print_source_lines (sal.symtab,
+ if (lines_to_list % 2 == 0)
+ print_source_lines (sal.symtab,
+ max (sal.line - (lines_to_list / 2), 1),
+ sal.line + (lines_to_list / 2), 0);
+ else
+ /* If lines_to_list is odd, then we round down in
+ * one of the lines_to_list/2 computations, round up in
+ * the other, so the total window size around the specified
+ * line comes out right.
+ */
+ print_source_lines (sal.symtab,
max (sal.line - (lines_to_list / 2), 1),
- sal.line + (lines_to_list / 2), 0);
+ sal.line + ((1+lines_to_list) / 2), 0);
else
print_source_lines (sal.symtab, sal.line,
(dummy_end
@@ -1172,11 +1317,12 @@ 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;
sal.line = last_line_listed;
- sal.pc = 0;
sals.nelts = 1;
sals.sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
@@ -1269,9 +1415,33 @@ forward_search_command (regex, from_tty)
register int c;
register int desc;
register FILE *stream;
- int line = last_line_listed + 1;
+ 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)
error (msg);
@@ -1279,8 +1449,6 @@ forward_search_command (regex, from_tty)
if (current_source_symtab == 0)
select_source_symtab (0);
- /* Search from last_line_listed+1 in current_source_symtab */
-
desc = open_source_file (current_source_symtab);
if (desc < 0)
perror_with_name (current_source_symtab->filename);
@@ -1300,7 +1468,7 @@ forward_search_command (regex, from_tty)
perror_with_name (current_source_symtab->filename);
}
- stream = fdopen (desc, FOPEN_RT);
+ stream = fdopen (desc, FDOPEN_MODE);
clearerr (stream);
while (1) {
static char *buf = NULL;
@@ -1331,6 +1499,8 @@ forward_search_command (regex, 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,
@@ -1354,8 +1524,31 @@ reverse_search_command (regex, from_tty)
register int c;
register int desc;
register FILE *stream;
- int line = last_line_listed - 1;
+ 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)
@@ -1364,8 +1557,6 @@ reverse_search_command (regex, from_tty)
if (current_source_symtab == 0)
select_source_symtab (0);
- /* Search from last_line_listed-1 in current_source_symtab */
-
desc = open_source_file (current_source_symtab);
if (desc < 0)
perror_with_name (current_source_symtab->filename);
@@ -1385,7 +1576,7 @@ reverse_search_command (regex, from_tty)
perror_with_name (current_source_symtab->filename);
}
- stream = fdopen (desc, FOPEN_RT);
+ stream = fdopen (desc, FDOPEN_MODE);
clearerr (stream);
while (line > 1)
{
@@ -1406,8 +1597,9 @@ reverse_search_command (regex, from_tty)
{
/* Match! */
fclose (stream);
- print_source_lines (current_source_symtab,
- line, line+1, 0);
+ 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,
(LONGEST) line));
@@ -1447,6 +1639,10 @@ 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.",
&cmdlist);
+
+ if (dbx_commands)
+ add_com_alias("use", "directory", class_files, 0);
+
c->completer = filename_completer;
add_cmd ("directories", no_class, show_directories,
@@ -1455,6 +1651,16 @@ $cwd in the path means the current working directory.\n\
$cdir in the path means the compilation directory of the source file.",
&showlist);
+ if (xdb_commands)
+ {
+ add_com_alias("D", "directory", class_files, 0);
+ add_cmd ("ld", no_class, show_directories,
+ "Current search path for finding source files.\n\
+$cwd in the path means the current working directory.\n\
+$cdir in the path means the compilation directory of the source file.",
+ &cmdlist);
+ }
+
add_info ("source", source_info,
"Information about the current source file.");
@@ -1480,6 +1686,12 @@ The matching line number is also stored as the value of \"$_\".");
"Search backward for regular expression (see regex(3)) from last line listed.\n\
The matching line number is also stored as the value of \"$_\".");
+ if (xdb_commands)
+ {
+ add_com_alias("/", "forward-search", class_files, 0);
+ add_com_alias("?", "reverse-search", class_files, 0);
+ }
+
add_com ("list", class_files, list_command,
concat ("List specified function or line.\n\
With no argument, lists ten more lines after or around previous listing.\n\
@@ -1495,7 +1707,13 @@ Lines can be specified in these ways:\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.", NULL));
- add_com_alias ("l", "list", class_files, 1);
+ if (!xdb_commands)
+ add_com_alias ("l", "list", class_files, 1);
+ else
+ add_com_alias ("v", "list", class_files, 1);
+
+ if (dbx_commands)
+ add_com_alias ("file", "list", class_files, 1);
add_show_from_set
(add_set_cmd ("listsize", class_support, var_uinteger,
OpenPOWER on IntegriCloud