[PATCH 12/19] tree_entry_interesting(): support wildcard matching
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
tree-walk.c | 33 ++++++++++++++++++++++++++++++---
tree-walk.h | 2 +-
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/tree-walk.c b/tree-walk.c
index d28de30..b5ad42b 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -552,7 +552,7 @@ static int match_dir_prefix(const char *base, int baselen,
* - negative for "no, and no subsequent entries will be either"
*/
int tree_entry_interesting(const struct name_entry *entry,
- const char *base, int baselen,
+ char *base, int baselen,
const struct pathspec *ps)
{
int i;
@@ -573,13 +573,15 @@ int tree_entry_interesting(const struct name_entry *entry,
pathlen = tree_entry_len(entry->path, entry->sha1);
for (i = 0; i < ps->nr; i++) {
+ const struct pathspec_item *item = ps->items+i;
+
const char *match = ps->raw[i];
- int matchlen = ps->items[i].len;
+ int matchlen = item->len;
if (baselen >= matchlen) {
if (!match_dir_prefix(base, baselen, match, matchlen))
/* Just a random prefix match */
- continue;
+ goto match_wildcards;
if (!ps->recursive || ps->max_depth == -1)
return 2;
@@ -596,6 +598,31 @@ int tree_entry_interesting(const struct name_entry *entry,
&never_interesting))
return 1;
}
+
+match_wildcards:
+ /*
+ * Concatenate base and entry->path into one and do
+ * fnmatch() on it.
+ */
+
+ if (!item->has_wildcard)
+ continue;
+
+ never_interesting = 0;
+ memcpy(base + baselen, entry->path, pathlen+1);
+
+ if (!fnmatch(match, base, 0)) {
+ base[baselen] = 0;
+ return 1;
+ }
+ base[baselen] = 0;
+
+ /*
+ * Match all directories. We'll try to match files
+ * later on.
+ */
+ if (ps->recursive && S_ISDIR(entry->mode))
+ return 1;
}
return never_interesting; /* No matches */
}
diff --git a/tree-walk.h b/tree-walk.h
index c12f0a2..94e0ef4 100644
--- a/tree-walk.h
+++ b/tree-walk.h
@@ -60,6 +60,6 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru
return info->pathlen + tree_entry_len(n->path, n->sha1);
}
-extern int tree_entry_interesting(const struct name_entry *, const char *, int, const struct pathspec *ps);
+extern int tree_entry_interesting(const struct name_entry *, char *, int, const struct pathspec *ps);
#endif
--
1.7.3.3.476.g10a82