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 (); |
} |