Subject: [PATCH 12/19] tree_entry_interesting(): support wildcard matching

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Mon, 13 Dec 2010 16:46:49 +0700

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 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