diff options
Diffstat (limited to 'gdb/source.c')
-rw-r--r-- | gdb/source.c | 247 |
1 files changed, 148 insertions, 99 deletions
diff --git a/gdb/source.c b/gdb/source.c index 27e2139..bf8760b 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -1,22 +1,21 @@ /* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc. -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. +This file is part of GDB. -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. +GDB is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ +GDB is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GDB; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "symtab.h" @@ -57,8 +56,13 @@ static int first_line_listed; struct symtab *psymtab_to_symtab (); -/* Set the source file default for the "list" command, - specifying a symtab. */ +/* Set the source file default for the "list" command, specifying a + symtab. Sigh. Behaivior 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_list (if it + exists) or the last symtab in the psytab_list (if *it* exists). If + none of this works, report an error. */ void select_source_symtab (s) @@ -68,6 +72,13 @@ select_source_symtab (s) struct symtab_and_line sal; struct partial_symtab *ps, *cs_pst; + if (s) + { + current_source_symtab = s; + current_source_line = 1; + return; + } + /* Make the default place to list be the function `main' if one exists. */ if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0)) @@ -76,14 +87,13 @@ select_source_symtab (s) sal = sals.sals[0]; free (sals.sals); current_source_symtab = sal.symtab; - current_source_line = sal.line - 9; + current_source_line = max (sal.line - 9, 1); return; } - /* If there is no `main', use the last symtab in the list, - which is actually the first found in the file's symbol table. - But ignore .h files. */ - if (s) + /* All right; find the last file in the symtab list (ignoring .h's). */ + + if (s = symtab_list) { do { @@ -96,7 +106,7 @@ select_source_symtab (s) while (s); current_source_line = 1; } - else + else if (partial_symtab_list) { ps = partial_symtab_list; while (ps) @@ -108,7 +118,10 @@ select_source_symtab (s) ps = ps->next; } if (cs_pst) - current_source_symtab = psymtab_to_symtab (cs_pst); + if (cs_pst->readin) + fatal ("Internal: select_source_symtab: readin pst found and no symtabs."); + else + current_source_symtab = psymtab_to_symtab (cs_pst); else current_source_symtab = 0; current_source_line = 1; @@ -146,6 +159,8 @@ directory_command (dirname, from_tty) { char *old = source_path; + dont_repeat (); + if (dirname == 0) { if (query ("Reinitialize source path to %s? ", current_directory)) @@ -156,76 +171,109 @@ directory_command (dirname, from_tty) } else { - struct stat st; - register int len = strlen (dirname); - register char *tem; - extern char *index (); - - if (index (dirname, ':')) - error ("Please add one directory at a time to the source path."); - if (dirname[len - 1] == '/') - /* Sigh. "foo/" => "foo" */ - dirname[--len] == '\0'; - - while (dirname[len - 1] == '.') + dirname = tilde_expand (dirname); + make_cleanup (free, dirname); + + do { - if (len == 1) - { - /* "." => getwd () */ - dirname = current_directory; - goto append; - } - else if (dirname[len - 2] == '/') + extern char *index (); + char *name = dirname; + register char *p; + struct stat st; + + { + char *colon = index (name, ':'); + char *space = index (name, ' '); + char *tab = index (name, '\t'); + if (colon == 0 && space == 0 && tab == 0) + p = dirname = name + strlen (name); + else + { + p = 0; + if (colon != 0 && (p == 0 || colon < p)) + p = colon; + if (space != 0 && (p == 0 || space < p)) + p = space; + if (tab != 0 && (p == 0 || tab < p)) + p = tab; + dirname = p + 1; + while (*dirname == ':' || *dirname == ' ' || *dirname == '\t') + ++dirname; + } + } + + if (p[-1] == '/') + /* Sigh. "foo/" => "foo" */ + --p; + *p = '\0'; + + while (p[-1] == '.') { - if (len == 2) + if (p - name == 1) { - /* "/." => "/" */ - dirname[--len] = '\0'; + /* "." => getwd (). */ + name = current_directory; goto append; } - else + else if (p[-2] == '/') { - /* "...foo/." => "...foo" */ - dirname[len -= 2] = '\0'; - continue; + if (p - name == 2) + { + /* "/." => "/". */ + *--p = '\0'; + goto append; + } + else + { + /* "...foo/." => "...foo". */ + p -= 2; + *p = '\0'; + continue; + } } + else + break; } - break; - } - - if (dirname[0] != '/') - dirname = concat (current_directory, "/", dirname); - else - dirname = savestring (dirname, len); - make_cleanup (free, dirname); - if (stat (dirname, &st) < 0) - perror_with_name (dirname); - if ((st.st_mode & S_IFMT) != S_IFDIR) - error ("%s is not a directory.", dirname); - - append: - len = strlen (dirname); - tem = source_path; - while (1) - { - if (!strncmp (tem, dirname, len) - && (tem[len] == '\0' || tem[len] == ':')) - { - printf ("\"%s\" is already in the source path.\n", - dirname); - break; - } - tem = index (tem, ':'); - if (tem) - tem++; + if (*name != '/') + name = concat (current_directory, "/", name); else - { - source_path = concat (old, ":", dirname); - free (old); - break; - } - } + name = savestring (name, p - name); + make_cleanup (free, name); + + if (stat (name, &st) < 0) + perror_with_name (name); + if ((st.st_mode & S_IFMT) != S_IFDIR) + error ("%s is not a directory.", name); + + append: + { + register unsigned int len = strlen (name); + + p = source_path; + while (1) + { + if (!strncmp (p, name, len) + && (p[len] == '\0' || p[len] == ':')) + { + if (from_tty) + printf ("\"%s\" is already in the source path.\n", name); + break; + } + p = index (p, ':'); + if (p != 0) + ++p; + else + break; + } + if (p == 0) + { + source_path = concat (old, ":", name); + free (old); + old = source_path; + } + } + } while (*dirname != '\0'); if (from_tty) directories_info (); } @@ -257,6 +305,9 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened) register char *p, *p1; register int len; + if (!path) + path = "."; + /* ./foo => foo */ while (string[0] == '.' && string[1] == '/') string += 2; @@ -433,9 +484,10 @@ identify_source_line (s, line, mid_statement) get_filename_and_charpos (s, line, 0); if (s->fullname == 0) return 0; - printf ("\032\032%s:%d:%d:%s\n", s->fullname, + printf ("\032\032%s:%d:%d:%s:0x%x\n", s->fullname, line, s->line_charpos[line - 1], - mid_statement ? "middle" : "beg"); + mid_statement ? "middle" : "beg", + get_frame_pc (get_current_frame())); current_source_line = line; first_line_listed = line; last_line_listed = line; @@ -495,18 +547,15 @@ print_source_lines (s, line, stopline, noerror) c = fgetc (stream); if (c == EOF) break; last_line_listed = current_source_line; - printf ("%d\t", current_source_line++); + printf_filtered ("%d\t", current_source_line++); do { if (c < 040 && c != '\t' && c != '\n') - { - fputc ('^', stdout); - fputc (c + 0100, stdout); - } + printf_filtered ("^%c", c + 0100); else if (c == 0177) - printf ("^?"); + printf_filtered ("^?"); else - fputc (c, stdout); + printf_filtered ("%c", c); } while (c != '\n' && (c = fgetc (stream)) >= 0); } @@ -550,12 +599,12 @@ list_command (arg, from_tty) char *p; if (symtab_list == 0 && partial_symtab_list == 0) - error ("Listing source lines requires symbols."); + error ("No symbol table is loaded. Use the \"symbol-file\" command."); /* Pull in a current source symtab if necessary */ if (current_source_symtab == 0 && (arg == 0 || arg[0] == '+' || arg[0] == '-')) - select_source_symtab (symtab_list); + select_source_symtab (0); /* "l" or "l +" lists next ten lines. */ @@ -768,8 +817,8 @@ forward_search_command (regex, from_tty) if (msg) error (msg); - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); + if (current_source_symtab == 0) + select_source_symtab (0); /* Search from last_line_listed+1 in current_source_symtab */ @@ -838,8 +887,8 @@ reverse_search_command (regex, from_tty) if (msg) error (msg); - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); + if (current_source_symtab == 0) + select_source_symtab (0); /* Search from last_line_listed-1 in current_source_symtab */ |