Subject: [PATCH 3/5] Convert prefix_pathspec() to produce struct pathspec_item

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Sat, 9 Apr 2011 23:54:18 +0700

New field plain_len is used to mark the first part of 'match' where no
magic can be applied.
---
 cache.h |    1 +
 setup.c |   26 ++++++++++++++++++--------
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/cache.h b/cache.h
index da1a46c..08b4633 100644
--- a/cache.h
+++ b/cache.h
@@ -528,6 +528,7 @@ struct pathspec {
 	struct pathspec_item {
 		const char *match;
 		int len;
+		int plain_len;	/* match[0..plain_len-1] does not have any kind of magic*/
 		unsigned magic;
 	} *items;
 };
diff --git a/setup.c b/setup.c
index 1e7dfb1..8a4a9d0 100644
--- a/setup.c
+++ b/setup.c
@@ -148,11 +148,12 @@ struct pathspec_magic {
  * the prefix part must always match literally, and a single stupid
  * string cannot express such a case.
  */
-const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
+int prefix_pathspec(struct pathspec_item *item,
+		    const char *prefix, int prefixlen,
+		    const char *elt)
 {
 	unsigned magic = 0;
 	const char *copyfrom = elt;
-	const char *retval;
 	int i, free_source = 0;
 
 	if (elt[0] != ':') {
@@ -184,7 +185,8 @@ const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
 			copyfrom++;
 	} else if (!elt[1]) {
 		/* Just ':' -- no element! */
-		return NULL;
+		memset(item, 0, sizeof(*item));
+		return -1;
 	} else {
 		/* shorthand */
 		for (copyfrom = elt + 1;
@@ -225,13 +227,19 @@ const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
 		}
 	}
 
+	memset(item, 0, sizeof(*item));
+	item->magic = magic;
+
 	if (magic & PATHSPEC_FROMTOP)
-		retval = xstrdup(copyfrom);
-	else
-		retval = prefix_path(prefix, prefixlen, copyfrom);
+		item->match = xstrdup(copyfrom);
+	else {
+		item->match = prefix_path(prefix, prefixlen, copyfrom);
+		item->plain_len = prefixlen;
+	}
+	item->len = strlen(item->match);
 	if (free_source)
 		free((char *)copyfrom);
-	return retval;
+	return 0;
 }
 
 const char **get_pathspec_old(const char *prefix, const char **pathspec)
@@ -255,7 +263,9 @@ const char **get_pathspec_old(const char *prefix, const char **pathspec)
 	dst = pathspec;
 	prefixlen = prefix ? strlen(prefix) : 0;
 	while (*src) {
-		*(dst++) = prefix_pathspec(prefix, prefixlen, *src);
+		struct pathspec_item item;
+		prefix_pathspec(&item, prefix, prefixlen, *src);
+		*(dst++) = item.match;
 		src++;
 	}
 	*dst = NULL;
-- 
1.7.4.74.g639db