convert common_prefix() to use struct pathspec

The code now takes advantage of nowildcard_len field. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Jul 14, 2013 at 15:35 UTC 827f4d6c218448d58f934c0980b6366407261b74
4 files changed +18 -19
builtin/commit.c
+1 -1
@@ -199,7 +199,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
199 m = xcalloc(1, pattern->nr);
200
201 if (with_tree) {
202 - char *max_prefix = common_prefix(pattern->raw);
202 + char *max_prefix = common_prefix(pattern);
203 overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : prefix);
204 free(max_prefix);
205 }
builtin/ls-files.c
+1 -1
@@ -546,7 +546,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
546 prefix, argv);
547
548 /* Find common prefix for all pathspec's */
549 - max_prefix = common_prefix(pathspec.raw);
549 + max_prefix = common_prefix(&pathspec);
550 max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
551
552 /* Treat unmatching pathspec elements as errors */
dir.c
+15 -16
@@ -103,26 +103,25 @@ static int fnmatch_icase_mem(const char *pattern, int patternlen,
103 return match_status;
104 }
105
106 -static size_t common_prefix_len(const char **pathspec)
106 +static size_t common_prefix_len(const struct pathspec *pathspec)
107 {
108 - const char *n, *first;
108 + int n;
109 size_t max = 0;
110 - int literal = limit_pathspec_to_literal();
110
112 - if (!pathspec)
113 - return max;
114 -
115 - first = *pathspec;
116 - while ((n = *pathspec++)) {
117 - size_t i, len = 0;
118 - for (i = 0; first == n || i < max; i++) {
119 - char c = n[i];
120 - if (!c || c != first[i] || (!literal && is_glob_special(c)))
111 + GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
112 +
113 + for (n = 0; n < pathspec->nr; n++) {
114 + size_t i = 0, len = 0;
115 + while (i < pathspec->items[n].nowildcard_len &&
116 + (n == 0 || i < max)) {
117 + char c = pathspec->items[n].match[i];
118 + if (c != pathspec->items[0].match[i])
119 break;
120 if (c == '/')
121 len = i + 1;
122 + i++;
123 }
125 - if (first == n || len < max) {
124 + if (n == 0 || len < max) {
125 max = len;
126 if (!max)
127 break;
@@ -135,11 +134,11 @@ static size_t common_prefix_len(const char **pathspec)
134 * Returns a copy of the longest leading path common among all
135 * pathspecs.
136 */
138 -char *common_prefix(const char **pathspec)
137 +char *common_prefix(const struct pathspec *pathspec)
138 {
139 unsigned long len = common_prefix_len(pathspec);
140
142 - return len ? xmemdupz(*pathspec, len) : NULL;
141 + return len ? xmemdupz(pathspec->items[0].match, len) : NULL;
142 }
143
144 int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
@@ -150,7 +149,7 @@ int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
149 * Calculate common prefix for the pathspec, and
150 * use that to optimize the directory walk
151 */
153 - len = common_prefix_len(pathspec->raw);
152 + len = common_prefix_len(pathspec);
153
154 /* Read the directory and prune it */
155 read_directory(dir, pathspec->nr ? pathspec->raw[0] : "", len, pathspec);
dir.h
+1 -1
@@ -130,7 +130,7 @@ struct dir_struct {
130 #define MATCHED_EXACTLY 3
131 extern int simple_length(const char *match);
132 extern int no_wildcard(const char *string);
133 -extern char *common_prefix(const char **pathspec);
133 +extern char *common_prefix(const struct pathspec *pathspec);
134 extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
135 extern int match_pathspec_depth(const struct pathspec *pathspec,
136 const char *name, int namelen,