diff options
Diffstat (limited to 'contrib/gdb/gdb/source.c')
-rw-r--r-- | contrib/gdb/gdb/source.c | 324 |
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, |