X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsource.c;h=7de86b4925161652aac2dd708dfc925cc14917d6;hb=1c658ad5fac2a221b589cbe26ec84c788b24a8d1;hp=8e7acf8f0b1df711dca8dc2f7cd7c7e3f103b8b7;hpb=5ee4ed9f2eeafe7f0be32e0d197240e2b52c6d41;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/source.c b/gdb/source.c index 8e7acf8f0b..7de86b4925 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -440,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,26 +554,17 @@ add_path (char *dirname, char **which_path, int parse_separators) 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. */ - memmove (p, &p[len + 1], strlen (&p[len + 1]) + 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 : */ } tinybuf[0] = DIRNAME_SEPARATOR; @@ -628,7 +597,8 @@ add_path (char *dirname, char **which_path, int parse_separators) skip_dup: ; } - while (arg != NULL); + + do_cleanups (back_to); } @@ -709,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); @@ -775,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; @@ -799,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* @@ -812,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; } @@ -831,6 +819,8 @@ openp (const char *path, int opts, const char *string, } } + do_cleanups (back_to); + done: if (filename_opened) {