| Index: gdb/source.c
|
| diff --git a/gdb/source.c b/gdb/source.c
|
| index 909f2523b7224d1282c6463de3def84dbe25bb79..0ff0782d453a67d39c7436c3e313dcc31d6e3357 100644
|
| --- a/gdb/source.c
|
| +++ b/gdb/source.c
|
| @@ -243,7 +243,8 @@ select_source_symtab (struct symtab *s)
|
| if one exists. */
|
| if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0))
|
| {
|
| - sals = decode_line_spec (main_name (), DECODE_LINE_FUNFIRSTLINE);
|
| + sals = decode_line_with_current_source (main_name (),
|
| + DECODE_LINE_FUNFIRSTLINE);
|
| sal = sals.sals[0];
|
| xfree (sals.sals);
|
| current_source_pspace = sal.pspace;
|
| @@ -440,62 +441,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
|
| @@ -573,65 +552,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);
|
| }
|
|
|
|
|
| @@ -712,10 +680,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);
|
| @@ -778,16 +747,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;
|
| @@ -802,11 +770,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*
|
| @@ -815,7 +801,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;
|
| }
|
|
|
| @@ -834,6 +820,8 @@ openp (const char *path, int opts, const char *string,
|
| }
|
| }
|
|
|
| + do_cleanups (back_to);
|
| +
|
| done:
|
| if (filename_opened)
|
| {
|
| @@ -971,26 +959,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,
|
| @@ -1017,7 +985,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;
|
| @@ -1429,7 +1406,7 @@ line_info (char *arg, int from_tty)
|
| }
|
| else
|
| {
|
| - sals = decode_line_spec_1 (arg, DECODE_LINE_LIST_MODE);
|
| + sals = decode_line_with_last_displayed (arg, DECODE_LINE_LIST_MODE);
|
|
|
| dont_repeat ();
|
| }
|
|
|