From 4a085b16f430bcfe1b6e2e84e7a569f4e191e906 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 6 Sep 2011 12:32:30 -0700 Subject: consolidate pathspec_prefix and common_prefix The implementation from pathspec_prefix (slightly modified) replaces the current common_prefix, because it also respects glob characters. Based on a patch by Clemens Buchacher. Signed-off-by: Junio C Hamano --- dir.c | 54 +++++++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) (limited to 'dir.c') diff --git a/dir.c b/dir.c index 08281d2ef7..7bc75c9448 100644 --- a/dir.c +++ b/dir.c @@ -34,49 +34,43 @@ int fnmatch_icase(const char *pattern, const char *string, int flags) return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0)); } -static int common_prefix(const char **pathspec) +size_t common_prefix_len(const char **pathspec) { - const char *path, *slash, *next; - int prefix; + const char *n, *first; + size_t max = 0; if (!pathspec) - return 0; - - path = *pathspec; - slash = strrchr(path, '/'); - if (!slash) - return 0; - - /* - * The first 'prefix' characters of 'path' are common leading - * path components among the pathspecs we have seen so far, - * including the trailing slash. - */ - prefix = slash - path + 1; - while ((next = *++pathspec) != NULL) { - int len, last_matching_slash = -1; - for (len = 0; len < prefix && next[len] == path[len]; len++) - if (next[len] == '/') - last_matching_slash = len; - if (len == prefix) - continue; - if (last_matching_slash < 0) - return 0; - prefix = last_matching_slash + 1; + return max; + + first = *pathspec; + while ((n = *pathspec++)) { + size_t i, len = 0; + for (i = 0; first == n || i < max; i++) { + char c = n[i]; + if (!c || c != first[i] || is_glob_special(c)) + break; + if (c == '/') + len = i + 1; + } + if (first == n || len < max) { + max = len; + if (!max) + break; + } } - return prefix; + return max; } int fill_directory(struct dir_struct *dir, const char **pathspec) { const char *path; - int len; + size_t len; /* * Calculate common prefix for the pathspec, and * use that to optimize the directory walk */ - len = common_prefix(pathspec); + len = common_prefix_len(pathspec); path = ""; if (len) @@ -84,6 +78,8 @@ int fill_directory(struct dir_struct *dir, const char **pathspec) /* Read the directory and prune it */ read_directory(dir, path, len, pathspec); + if (*path) + free((char *)path); return len; } -- cgit v1.3