X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsource.c;h=7de86b4925161652aac2dd708dfc925cc14917d6;hb=1c658ad5fac2a221b589cbe26ec84c788b24a8d1;hp=70890e150d42b01ddb75d774925b3b1ad24a680a;hpb=00174a8637c5c42b77b190c38b1afa94c4c14517;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/source.c b/gdb/source.c index 70890e150d..7de86b4925 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -1,7 +1,5 @@ /* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, - 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1986-2005, 2007-2012 Free Software Foundation, Inc. This file is part of GDB. @@ -245,7 +243,7 @@ select_source_symtab (struct symtab *s) if one exists. */ if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0)) { - sals = decode_line_spec (main_name (), 1); + sals = decode_line_spec (main_name (), DECODE_LINE_FUNFIRSTLINE); sal = sals.sals[0]; xfree (sals.sals); current_source_pspace = sal.pspace; @@ -355,10 +353,10 @@ forget_cached_source_info_for_objfile (struct objfile *objfile) xfree (s->fullname); s->fullname = NULL; } - - if (objfile->sf) - objfile->sf->qf->forget_cached_source_info (objfile); } + + if (objfile->sf) + objfile->sf->qf->forget_cached_source_info (objfile); } /* Forget what we learned about line positions in source files, and @@ -369,7 +367,6 @@ void forget_cached_source_info (void) { struct program_space *pspace; - struct symtab *s; struct objfile *objfile; ALL_PSPACES (pspace) @@ -443,62 +440,40 @@ add_path (char *dirname, char **which_path, int parse_separators) { char *old = *which_path; int prefix = 0; - char **argv = NULL; - char *arg; - int argv_index = 0; + VEC (char_ptr) *dir_vec = NULL; + struct cleanup *back_to; + int ix; + char *name; if (dirname == 0) return; if (parse_separators) { + char **argv, **argvp; + /* This will properly parse the space and tab separators - and any quotes that may exist. DIRNAME_SEPARATOR will - be dealt with later. */ + and any quotes that may exist. */ argv = gdb_buildargv (dirname); - make_cleanup_freeargv (argv); - arg = argv[0]; + for (argvp = argv; *argvp; argvp++) + dirnames_to_char_ptr_vec_append (&dir_vec, *argvp); + + freeargv (argv); } else - { - arg = xstrdup (dirname); - make_cleanup (xfree, arg); - } + VEC_safe_push (char_ptr, dir_vec, xstrdup (dirname)); + back_to = make_cleanup_free_char_ptr_vec (dir_vec); - do + for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, name); ++ix) { - char *name = arg; char *p; struct stat st; - { - char *separator = NULL; - - /* Spaces and tabs will have been removed by buildargv(). - The directories will there be split into a list but - each entry may still contain DIRNAME_SEPARATOR. */ - if (parse_separators) - separator = strchr (name, DIRNAME_SEPARATOR); - - if (separator == 0) - p = arg = name + strlen (name); - else - { - p = separator; - arg = p + 1; - while (*arg == DIRNAME_SEPARATOR) - ++arg; - } - - /* If there are no more directories in this argument then start - on the next argument next time round the loop (if any). */ - if (*arg == '\0') - arg = parse_separators ? argv[++argv_index] : NULL; - } - - /* name is the start of the directory. - p is the separator (or null) following the end. */ + /* Spaces and tabs will have been removed by buildargv(). + NAME is the start of the directory. + P is the '\0' following the end. */ + p = name + strlen (name); while (!(IS_DIR_SEPARATOR (*name) && p <= name + 1) /* "/" */ #ifdef HAVE_DOS_BASED_FILE_SYSTEM @@ -576,65 +551,54 @@ add_path (char *dirname, char **which_path, int parse_separators) append: { unsigned int len = strlen (name); + char tinybuf[2]; p = *which_path; - while (1) + /* FIXME: we should use realpath() or its work-alike + before comparing. Then all the code above which + removes excess slashes and dots could simply go away. */ + if (!filename_cmp (p, name)) { - /* FIXME: we should use realpath() or its work-alike - before comparing. Then all the code above which - removes excess slashes and dots could simply go away. */ - if (!filename_ncmp (p, name, len) - && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR)) - { - /* Found it in the search path, remove old copy. */ - if (p > *which_path) - 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 : */ - } - p = strchr (p, DIRNAME_SEPARATOR); - if (p != 0) - ++p; - else - break; + /* Found it in the search path, remove old copy. */ + if (p > *which_path) + p--; /* Back over leading separator. */ + if (prefix > p - *which_path) + goto skip_dup; /* Same dir twice in one cmd. */ + memmove (p, &p[len + 1], strlen (&p[len + 1]) + 1); /* Copy from next \0 or : */ } - if (p == 0) - { - char tinybuf[2]; - tinybuf[0] = DIRNAME_SEPARATOR; - tinybuf[1] = '\0'; + tinybuf[0] = DIRNAME_SEPARATOR; + tinybuf[1] = '\0'; - /* If we have already tacked on a name(s) in this command, - be sure they stay on the front as we tack on some - more. */ - if (prefix) - { - char *temp, c; - - c = old[prefix]; - old[prefix] = '\0'; - temp = concat (old, tinybuf, name, (char *)NULL); - old[prefix] = c; - *which_path = concat (temp, "", &old[prefix], (char *) NULL); - prefix = strlen (temp); - xfree (temp); - } - else - { - *which_path = concat (name, (old[0] ? tinybuf : old), - old, (char *)NULL); - prefix = strlen (name); - } - xfree (old); - old = *which_path; + /* If we have already tacked on a name(s) in this command, + be sure they stay on the front as we tack on some + more. */ + if (prefix) + { + char *temp, c; + + c = old[prefix]; + old[prefix] = '\0'; + temp = concat (old, tinybuf, name, (char *)NULL); + old[prefix] = c; + *which_path = concat (temp, "", &old[prefix], (char *) NULL); + prefix = strlen (temp); + xfree (temp); } + else + { + *which_path = concat (name, (old[0] ? tinybuf : old), + old, (char *)NULL); + prefix = strlen (name); + } + xfree (old); + old = *which_path; } skip_dup: ; } - while (arg != NULL); + + do_cleanups (back_to); } @@ -715,10 +679,11 @@ openp (const char *path, int opts, const char *string, { int fd; char *filename; - const char *p; - const char *p1; - int len; int alloclen; + VEC (char_ptr) *dir_vec; + struct cleanup *back_to; + int ix; + char *dir; /* The open syscall MODE parameter is not specified. */ gdb_assert ((mode & O_CREAT) == 0); @@ -781,16 +746,15 @@ openp (const char *path, int opts, const char *string, alloclen = strlen (path) + strlen (string) + 2; filename = alloca (alloclen); fd = -1; - for (p = path; p; p = p1 ? p1 + 1 : 0) + + dir_vec = dirnames_to_char_ptr_vec (path); + back_to = make_cleanup_free_char_ptr_vec (dir_vec); + + for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, dir); ++ix) { - p1 = strchr (p, DIRNAME_SEPARATOR); - if (p1) - len = p1 - p; - else - len = strlen (p); + size_t len = strlen (dir); - if (len == 4 && p[0] == '$' && p[1] == 'c' - && p[2] == 'w' && p[3] == 'd') + if (strcmp (dir, "$cwd") == 0) { /* Name is $cwd -- insert current directory name instead. */ int newlen; @@ -805,11 +769,29 @@ openp (const char *path, int opts, const char *string, } strcpy (filename, current_directory); } + else if (strchr(dir, '~')) + { + /* See whether we need to expand the tilde. */ + int newlen; + char *tilde_expanded; + + tilde_expanded = tilde_expand (dir); + + /* First, realloc the filename buffer if too short. */ + len = strlen (tilde_expanded); + newlen = len + strlen (string) + 2; + if (newlen > alloclen) + { + alloclen = newlen; + filename = alloca (alloclen); + } + strcpy (filename, tilde_expanded); + xfree (tilde_expanded); + } else { /* Normal file name in path -- just use it. */ - strncpy (filename, p, len); - filename[len] = 0; + strcpy (filename, dir); /* Don't search $cdir. It's also a magic path like $cwd, but we don't have enough information to expand it. The user *could* @@ -818,7 +800,7 @@ openp (const char *path, int opts, const char *string, contexts. If the user really has '$cdir' one can use './$cdir'. We can get $cdir when loading scripts. When loading source files $cdir must have already been expanded to the correct value. */ - if (strcmp (filename, "$cdir") == 0) + if (strcmp (dir, "$cdir") == 0) continue; } @@ -837,6 +819,8 @@ openp (const char *path, int opts, const char *string, } } + do_cleanups (back_to); + done: if (filename_opened) { @@ -974,26 +958,6 @@ rewrite_source_path (const char *path) return new_path; } -/* This function is capable of finding the absolute path to a - source file, and opening it, provided you give it a FILENAME. Both the - DIRNAME and FULLNAME are only added suggestions on where to find the file. - - FILENAME should be the filename to open. - DIRNAME is the compilation directory of a particular source file. - Only some debug formats provide this info. - FULLNAME can be the last known absolute path to the file in question. - Space for the path must have been malloc'd. If a path substitution - is applied we free the old value and set a new one. - - On Success - A valid file descriptor is returned (the return value is positive). - FULLNAME is set to the absolute path to the file just opened. - The caller is responsible for freeing FULLNAME. - - On Failure - An invalid file descriptor is returned (the return value is negative). - FULLNAME is set to NULL. */ - int find_and_open_source (const char *filename, const char *dirname, @@ -1020,7 +984,16 @@ find_and_open_source (const char *filename, result = open (*fullname, OPEN_MODE); if (result >= 0) - return result; + { + /* Call xfullpath here to be consistent with openp + which we use below. */ + char *lpath = xfullpath (*fullname); + + xfree (*fullname); + *fullname = lpath; + return result; + } + /* Didn't work -- free old one, try again. */ xfree (*fullname); *fullname = NULL; @@ -1106,6 +1079,7 @@ open_source_file (struct symtab *s) If this function fails to find the file that this symtab represents, NULL will be returned and s->fullname will be set to NULL. */ + char * symtab_to_fullname (struct symtab *s) { @@ -1114,8 +1088,12 @@ symtab_to_fullname (struct symtab *s) if (!s) return NULL; - /* Don't check s->fullname here, the file could have been - deleted/moved/..., look for it again. */ + /* Use cached copy if we have it. + We rely on forget_cached_source_info being called appropriately + to handle cases like the file being moved. */ + if (s->fullname) + return s->fullname; + r = find_and_open_source (s->filename, s->dirname, &s->fullname); if (r >= 0) @@ -1277,6 +1255,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror) FILE *stream; int nlines = stopline - line; struct cleanup *cleanup; + struct ui_out *uiout = current_uiout; /* Regardless of whether we can open the file, set current_source_symtab. */ current_source_symtab = s; @@ -1317,10 +1296,12 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror) print_sys_errmsg (name, errno); } else - ui_out_field_int (uiout, "line", line); - ui_out_text (uiout, "\tin "); - ui_out_field_string (uiout, "file", s->filename); - ui_out_text (uiout, "\n"); + { + ui_out_field_int (uiout, "line", line); + ui_out_text (uiout, "\tin "); + ui_out_field_string (uiout, "file", s->filename); + ui_out_text (uiout, "\n"); + } return; } @@ -1408,12 +1389,14 @@ line_info (char *arg, int from_tty) struct symtab_and_line sal; CORE_ADDR start_pc, end_pc; int i; + struct cleanup *cleanups; init_sal (&sal); /* initialize to zeroes */ if (arg == 0) { sal.symtab = current_source_symtab; + sal.pspace = current_program_space; sal.line = last_line_listed; sals.nelts = 1; sals.sals = (struct symtab_and_line *) @@ -1422,16 +1405,20 @@ line_info (char *arg, int from_tty) } else { - sals = decode_line_spec_1 (arg, 0); + sals = decode_line_spec_1 (arg, DECODE_LINE_LIST_MODE); dont_repeat (); } + cleanups = make_cleanup (xfree, sals.sals); + /* C++ More than one line may have been specified, as when the user specifies an overloaded function name. Print info on them all. */ for (i = 0; i < sals.nelts; i++) { sal = sals.sals[i]; + if (sal.pspace != current_program_space) + continue; if (sal.symtab == 0) { @@ -1497,7 +1484,7 @@ line_info (char *arg, int from_tty) printf_filtered (_("Line number %d is out of range for \"%s\".\n"), sal.line, sal.symtab->filename); } - xfree (sals.sals); + do_cleanups (cleanups); } /* Commands to search the source file for a regexp. */