From ecd6911b13179d49e8ddd56f393f8775047d3251 Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Tue, 21 Feb 2006 19:46:48 +0000 Subject: 2006-02-21 Andrew Stubbs * defs.h (directory_switch): Add prototype. * main.c (captured_main): Use directory_switch() instead of directory_command() to add directories from the -d switch. * source.c (directory_switch): New function. (add_path): Use buildargv() to parse spaces in filenames properly. Strip multiple trailing '/' rather than just one. --- gdb/source.c | 81 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 28 deletions(-) (limited to 'gdb/source.c') diff --git a/gdb/source.c b/gdb/source.c index f9f7dd1914e..3b93362b5e3 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -378,6 +378,15 @@ directory_command (char *dirname, int from_tty) forget_cached_source_info (); } +/* Add a path given with the -d command line switch. + This will not be quoted so we must not treat spaces as separators. */ + +void +directory_switch (char *dirname, int from_tty) +{ + add_path (dirname, &source_path, 0); +} + /* Add zero or more directories to the front of an arbitrary path. */ void @@ -397,56 +406,72 @@ 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; if (dirname == 0) return; - dirname = xstrdup (dirname); - make_cleanup (xfree, dirname); + if (parse_separators) + { + /* This will properly parse the space and tab separators + and any quotes that may exist. DIRNAME_SEPARATOR will + be dealt with later. */ + argv = buildargv (dirname); + make_cleanup_freeargv (argv); + + if (argv == NULL) + nomem (0); + + arg = argv[0]; + } + else + { + arg = xstrdup (dirname); + make_cleanup (xfree, arg); + } do { - char *name = dirname; + char *name = arg; char *p; struct stat st; { char *separator = NULL; - char *space = NULL; - char *tab = 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); - space = strchr (name, ' '); - tab = strchr (name, '\t'); - } + separator = strchr (name, DIRNAME_SEPARATOR); - if (separator == 0 && space == 0 && tab == 0) - p = dirname = name + strlen (name); + if (separator == 0) + p = arg = name + strlen (name); else { - p = 0; - if (separator != 0 && (p == 0 || separator < p)) - p = separator; - if (space != 0 && (p == 0 || space < p)) - p = space; - if (tab != 0 && (p == 0 || tab < p)) - p = tab; - dirname = p + 1; - while (*dirname == DIRNAME_SEPARATOR - || *dirname == ' ' - || *dirname == '\t') - ++dirname; + 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; } - if (!(IS_DIR_SEPARATOR (*name) && p <= name + 1) /* "/" */ + /* name is the start of the directory. + p is the separator (or null) following the end. */ + + while (!(IS_DIR_SEPARATOR (*name) && p <= name + 1) /* "/" */ #ifdef HAVE_DOS_BASED_FILE_SYSTEM /* On MS-DOS and MS-Windows, h:\ is different from h: */ - && !(p == name + 3 && name[1] == ':') /* "d:/" */ + && !(p == name + 3 && name[1] == ':') /* "d:/" */ #endif - && IS_DIR_SEPARATOR (p[-1])) + && IS_DIR_SEPARATOR (p[-1])) /* Sigh. "foo/" => "foo" */ --p; *p = '\0'; @@ -577,7 +602,7 @@ add_path (char *dirname, char **which_path, int parse_separators) } skip_dup:; } - while (*dirname != '\0'); + while (arg != NULL); } -- cgit v1.2.1