git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH/WIP 05/10] pathspec: prepare for :(glob)path syntax
Date: Sun, 13 Jan 2013 19:49:34 +0700	[thread overview]
Message-ID: <1358081379-17752-6-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1358081379-17752-1-git-send-email-pclouds@gmail.com>

:(glob)path differs from path that it uses wildmatch with
FNM_PATHNAME while plain "path" uses fnmatch without FNM_PATHNAME.

git_fnmatch() was probably ill-designed. It was intended to cover
other use of fnmatch besides pathspec. But so far it's only used by
pathspec code.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c |  9 +++++++--
 cache.h       |  1 +
 dir.c         | 34 ++++++++++++++++++++++------------
 dir.h         |  8 +++-----
 setup.c       |  1 +
 tree-walk.c   | 11 ++++++-----
 6 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index d09a07a..1b99e2b 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -416,11 +416,16 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		/*
 		 * file_exists() assumes exact match
 		 */
-		GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+		GUARD_PATHSPEC(&pathspec,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB);
 
 		for (i = 0; i < pathspec.nr; i++) {
 			const char *path = pathspec.items[i].match;
-			if (!seen[i] && !file_exists(path)) {
+			if (!seen[i] &&
+			    ((pathspec.items[i].magic & PATHSPEC_GLOB) ||
+			     !file_exists(path))) {
 				if (ignore_missing) {
 					int dtype = DT_UNKNOWN;
 					if (is_path_excluded(&check, path, -1, &dtype))
diff --git a/cache.h b/cache.h
index fb54876..9c27f18 100644
--- a/cache.h
+++ b/cache.h
@@ -479,6 +479,7 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
 /* Pathspec magic */
 #define PATHSPEC_FROMTOP    (1<<0)
 #define PATHSPEC_LITERAL    (1<<1)
+#define PATHSPEC_GLOB       (1<<2)
 
 #define PATHSPEC_ONESTAR 1	/* the pathspec pattern sastisfies GFNM_ONESTAR */
 
diff --git a/dir.c b/dir.c
index 63d07cd..760b776 100644
--- a/dir.c
+++ b/dir.c
@@ -37,26 +37,28 @@ int fnmatch_icase(const char *pattern, const char *string, int flags)
 	return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
 }
 
-inline int git_fnmatch(const char *pattern, const char *string,
-		       int flags, int prefix)
+inline int git_fnmatch(const struct pathspec_item *item,
+		       const char *pattern, const char *string,
+		       int prefix)
 {
-	int fnm_flags = 0;
-	if (flags & GFNM_PATHNAME)
-		fnm_flags |= FNM_PATHNAME;
 	if (prefix > 0) {
 		if (strncmp(pattern, string, prefix))
 			return FNM_NOMATCH;
 		pattern += prefix;
 		string += prefix;
 	}
-	if (flags & GFNM_ONESTAR) {
+	if (item->flags & PATHSPEC_ONESTAR) {
 		int pattern_len = strlen(++pattern);
 		int string_len = strlen(string);
 		return string_len < pattern_len ||
 		       strcmp(pattern,
 			      string + string_len - pattern_len);
 	}
-	return fnmatch(pattern, string, fnm_flags);
+	if (item->magic & PATHSPEC_GLOB)
+		return wildmatch(pattern, string, 0);
+	else
+		/* wildmatch has not learned no FNM_PATHNAME mode yet */
+		return fnmatch(pattern, string, 0);
 }
 
 static size_t common_prefix_len(const struct pathspec *pathspec)
@@ -64,7 +66,10 @@ static size_t common_prefix_len(const struct pathspec *pathspec)
 	int n;
 	size_t max = 0;
 
-	GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+	GUARD_PATHSPEC(pathspec,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB);
 
 	for (n = 0; n < pathspec->nr; n++) {
 		size_t i = 0, len = 0;
@@ -159,8 +164,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
 	}
 
 	if (item->nowildcard_len < item->len &&
-	    !git_fnmatch(match, name,
-			 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+	    !git_fnmatch(item, match, name,
 			 item->nowildcard_len - prefix))
 		return MATCHED_FNMATCH;
 
@@ -181,7 +185,10 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
 	int i, retval = 0;
 
-	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+	GUARD_PATHSPEC(ps,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
@@ -1230,7 +1237,10 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru
 	 * Check out create_simplify()
 	 */
 	if (pathspec)
-		GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+		GUARD_PATHSPEC(pathspec,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB);
 
 	if (has_symlink_leading_path(path, len))
 		return dir->nr;
diff --git a/dir.h b/dir.h
index a03af80..b6da4b7 100644
--- a/dir.h
+++ b/dir.h
@@ -168,10 +168,8 @@ extern int fnmatch_icase(const char *pattern, const char *string, int flags);
 /*
  * The prefix part of pattern must not contains wildcards.
  */
-#define GFNM_PATHNAME 1		/* similar to FNM_PATHNAME */
-#define GFNM_ONESTAR  2		/* there is only _one_ wildcard, a star */
-
-extern int git_fnmatch(const char *pattern, const char *string,
-		       int flags, int prefix);
+extern int git_fnmatch(const struct pathspec_item *item,
+		       const char *pattern, const char *string,
+		       int prefix);
 
 #endif
diff --git a/setup.c b/setup.c
index c4af05e..b3e146d 100644
--- a/setup.c
+++ b/setup.c
@@ -170,6 +170,7 @@ static struct pathspec_magic {
 } pathspec_magic[] = {
 	{ PATHSPEC_FROMTOP, '/', "top" },
 	{ PATHSPEC_LITERAL,   0, "literal" },
+	{ PATHSPEC_GLOB,   '\0', "glob" },
 };
 
 /*
diff --git a/tree-walk.c b/tree-walk.c
index d4ed51f..1679ce7 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -635,7 +635,10 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 	enum interesting never_interesting = ps->has_wildcard ?
 		entry_not_interesting : all_entries_not_interesting;
 
-	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+	GUARD_PATHSPEC(ps,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
@@ -677,8 +680,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 				return entry_interesting;
 
 			if (item->nowildcard_len < item->len) {
-				if (!git_fnmatch(match + baselen, entry->path,
-						 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+				if (!git_fnmatch(item, match + baselen, entry->path,
 						 item->nowildcard_len - baselen))
 					return entry_interesting;
 
@@ -719,8 +721,7 @@ match_wildcards:
 
 		strbuf_add(base, entry->path, pathlen);
 
-		if (!git_fnmatch(match, base->buf + base_offset,
-				 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+		if (!git_fnmatch(item, match, base->buf + base_offset,
 				 item->nowildcard_len)) {
 			strbuf_setlen(base, base_offset + baselen);
 			return entry_interesting;
-- 
1.8.0.rc2.23.g1fb49df

  parent reply	other threads:[~2013-01-13 12:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 02/10] parse_pathspec: make sure the prefix part is wildcard-free Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 03/10] pathspec: support :(literal) syntax for noglob pathspec Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 04/10] parse_pathspec: save prefix information Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy [this message]
2013-01-13 12:49 ` [PATCH/WIP 06/10] Enable :(glob)path syntax for a lot of commands Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 07/10] parse_pathspec: accept :(icase)path syntax Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 08/10] common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 09/10] pathspec: support icase in match_pathspec_depth and tree_entry_interesting Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 10/10] Enable ls-files and ls-tree for testing PATHSPEC_ICASE Nguyễn Thái Ngọc Duy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1358081379-17752-6-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).