diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/source.c | 342 |
2 files changed, 223 insertions, 124 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f709083..231017e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +Wed Dec 7 18:22:59 1994 Stan Shebs <shebs@andros.cygnus.com> + + * source.c: Various cosmetic changes. + (forward_search_command): Handle very long source lines correctly. + Wed Dec 7 13:21:47 1994 Rob Savoye <rob@darkstar.cygnus.com> * hppa-tdep.c: Use GDB_TARGET_IS_PA_ELF so SOM target support will diff --git a/gdb/source.c b/gdb/source.c index 50eb127..a300f5d 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -1,5 +1,6 @@ /* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1988, 1989, 1991 Free Software Foundation, Inc. + Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994 + Free Software Foundation, Inc. This file is part of GDB. @@ -42,35 +43,25 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Prototypes for local functions. */ -static int -open_source_file PARAMS ((struct symtab *)); +static int open_source_file PARAMS ((struct symtab *)); -static int -get_filename_and_charpos PARAMS ((struct symtab *, char **)); +static int get_filename_and_charpos PARAMS ((struct symtab *, char **)); -static void -reverse_search_command PARAMS ((char *, int)); +static void reverse_search_command PARAMS ((char *, int)); -static void -forward_search_command PARAMS ((char *, int)); +static void forward_search_command PARAMS ((char *, int)); -static void -line_info PARAMS ((char *, int)); +static void line_info PARAMS ((char *, int)); -static void -list_command PARAMS ((char *, int)); +static void list_command PARAMS ((char *, int)); -static void -ambiguous_line_spec PARAMS ((struct symtabs_and_lines *)); +static void ambiguous_line_spec PARAMS ((struct symtabs_and_lines *)); -static void -source_info PARAMS ((char *, int)); +static void source_info PARAMS ((char *, int)); -static void -show_directories PARAMS ((char *, int)); +static void show_directories PARAMS ((char *, int)); -static void -find_source_lines PARAMS ((struct symtab *, 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 @@ -207,10 +198,9 @@ show_directories (ignore, from_tty) puts_filtered ("\n"); } -/* Forget what we learned about line positions in source files, - and which directories contain them; - must check again now since files may be found in - a different directory now. */ +/* Forget what we learned about line positions in source files, and + which directories contain them; must check again now since files + may be found in a different directory now. */ void forget_cached_source_info () @@ -293,22 +283,25 @@ mod_path (dirname, which_path) struct stat st; { - char *colon = strchr (name, DIRNAME_SEPARATOR); + char *separator = strchr (name, DIRNAME_SEPARATOR); char *space = strchr (name, ' '); char *tab = strchr (name, '\t'); - if (colon == 0 && space == 0 && tab == 0) + + if (separator == 0 && space == 0 && tab == 0) p = dirname = name + strlen (name); else { p = 0; - if (colon != 0 && (p == 0 || colon < p)) - p = colon; + if (separator != 0 && (p == 0 || separator < p)) + p = separator; if (space != 0 && (p == 0 || space < p)) p = space; if (tab != 0 && (p == 0 || tab < p)) p = tab; dirname = p + 1; - while (*dirname == DIRNAME_SEPARATOR || *dirname == ' ' || *dirname == '\t') + while (*dirname == DIRNAME_SEPARATOR + || *dirname == ' ' + || *dirname == '\t') ++dirname; } } @@ -387,7 +380,7 @@ mod_path (dirname, which_path) { /* Found it in the search path, remove old copy */ if (p > *which_path) - p--; /* Back over leading colon */ + p--; /* Back over leading separator */ if (prefix > p - *which_path) goto skip_dup; /* Same dir twice in one cmd */ strcpy (p, &p[len+1]); /* Copy from next \0 or : */ @@ -551,24 +544,37 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened) done: if (filename_opened) - if (fd < 0) - *filename_opened = (char *) 0; - else if (filename[0] == '/') - *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]? "": "/", - filename, NULL); - } + { + if (fd < 0) + *filename_opened = (char *) 0; + else if (filename[0] == '/') + *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]? "": "/", + 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"); + } +#endif +/* end-sanitize-mpw */ return fd; } -/* Open a source file given a symtab S. Returns a file descriptor - or negative number for error. */ +/* Open a source file given a symtab S. Returns a file descriptor or + negative number for error. */ static int open_source_file (s) @@ -598,16 +604,17 @@ open_source_file (s) which produces a "required warning" when assigned to a nonconst. */ p = (char *)strstr (source_path, "$cdir"); if (p && (p == path || p[-1] == DIRNAME_SEPARATOR) - && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0')) { - int len; - - path = (char *) - alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1); - len = p - source_path; - strncpy (path, source_path, len); /* Before $cdir */ - strcpy (path + len, s->dirname); /* new stuff */ - strcat (path + len, source_path + len + cdir_len); /* After $cdir */ - } + && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0')) + { + int len; + + path = (char *) + alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1); + len = p - source_path; + strncpy (path, source_path, len); /* Before $cdir */ + strcpy (path + len, s->dirname); /* new stuff */ + strcat (path + len, source_path + len + cdir_len); /* After $cdir */ + } } result = openp (path, 0, s->filename, O_RDONLY, 0, &s->fullname); @@ -618,6 +625,24 @@ 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) + { + /* 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); + } + 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); + } +#endif +/* end-sanitize-mpw */ if (result >= 0) { fullname = s->fullname; @@ -627,6 +652,35 @@ open_source_file (s) return result; } +/* Return the path to the source file associated with symtab. Returns NULL + if no symtab. */ + +char * +symtab_to_filename (s) + struct symtab *s; +{ + int fd; + + if (!s) + return NULL; + + /* If we've seen the file before, just return fullname. */ + + if (s->fullname) + return s->fullname; + + /* Try opening the file to setup fullname */ + + fd = open_source_file (s); + if (fd < 0) + return s->filename; /* File not found. Just use short name */ + + /* Found the file. Cleanup and return the full name */ + + close (fd); + return s->fullname; +} + /* Create and initialize the table S->line_charpos that records the positions of the lines in the source file, which is assumed @@ -645,75 +699,80 @@ 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"); - } + 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"); + } #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); - } - } + { + char c; -#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; + /* Have to read it byte by byte to find out where the chars live */ -#ifdef BROKEN_LARGE_ALLOCA - data = (char *) xmalloc (size); - make_cleanup (free, data); -#else - data = (char *) alloca (size); -#endif - if (myread (desc, data, size) < 0) - perror_with_name (s->filename); - end = data + size; - p = data; - line_charpos[0] = 0; - nlines = 1; - while (p != end) + 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 /* lseek linear. */ { - if (*p++ == '\n' - /* A newline at the end does not start a new line. */ - && p != end) - { - if (nlines == lines_allocated) + struct cleanup *old_cleanups; + + /* st_size might be a large type, but we only support source files whose + size fits in an int. */ + size = (int) st.st_size; + + /* Use malloc, not alloca, because this may be pretty large, and we may + run into various kinds of limits on stack size. */ + data = (char *) xmalloc (size); + old_cleanups = make_cleanup (free, data); + + if (myread (desc, data, size) < 0) + perror_with_name (s->filename); + end = data + size; + p = data; + line_charpos[0] = 0; + nlines = 1; + while (p != end) { - lines_allocated *= 2; - line_charpos = - (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, - sizeof (int) * lines_allocated); + 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; + } } - line_charpos[nlines++] = p - data; - } + do_cleanups (old_cleanups); } -#endif +#endif /* lseek linear. */ s->nlines = nlines; s->line_charpos = (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, @@ -895,13 +954,11 @@ print_source_lines (s, line, stopline, noerror) -/* - C++ - Print a list of files and line numbers which a user may choose from - in order to list a function which was specified ambiguously - (as with `list classname::overloadedfuncname', for example). - The vector in SALS provides the filenames and line numbers. - */ +/* Print a list of files and line numbers which a user may choose from + in order to list a function which was specified ambiguously (as with + `list classname::overloadedfuncname', for example). The vector in + SALS provides the filenames and line numbers. */ + static void ambiguous_line_spec (sals) struct symtabs_and_lines *sals; @@ -913,7 +970,6 @@ ambiguous_line_spec (sals) sals->sals[i].symtab->filename, sals->sals[i].line); } - static void list_command (arg, from_tty) char *arg; @@ -1228,15 +1284,26 @@ forward_search_command (regex, from_tty) stream = fdopen (desc, FOPEN_RT); clearerr (stream); while (1) { -/* FIXME!!! We walk right off the end of buf if we get a long line!!! */ - char buf[4096]; /* Should be reasonable??? */ - register char *p = buf; + static char *buf = NULL; + register char *p; + int cursize, newsize; + + cursize = 256; + buf = xmalloc (cursize); + p = buf; c = getc (stream); if (c == EOF) break; do { *p++ = c; + if (p - buf == cursize) + { + newsize = cursize + cursize / 2; + buf = xrealloc (buf, newsize); + p = buf + cursize; + cursize = newsize; + } } while (c != '\n' && (c = getc (stream)) >= 0); /* we now have a source line in buf, null terminate and match */ @@ -1245,8 +1312,7 @@ forward_search_command (regex, from_tty) { /* Match! */ fclose (stream); - print_source_lines (current_source_symtab, - line, line+1, 0); + print_source_lines (current_source_symtab, line, line+1, 0); current_source_line = max (line - lines_to_list / 2, 1); return; } @@ -1367,6 +1433,9 @@ $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\ Line can be specified as\n\ @@ -1378,6 +1447,17 @@ 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 */ add_com ("forward-search", class_files, forward_search_command, "Search for regular expression (see regex(3)) from last line listed."); @@ -1386,6 +1466,9 @@ The address is also stored as the value of \"$_\"."); add_com ("reverse-search", class_files, reverse_search_command, "Search backward for regular expression (see regex(3)) from last line listed."); +/* start-sanitize-mpw */ +#ifndef MPW_C +/* end-sanitize-mpw */ 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\ @@ -1399,6 +1482,17 @@ 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."); +/* 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 */ add_com_alias ("l", "list", class_files, 1); add_show_from_set |