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 2/3] wildmatch: support "no FNM_PATHNAME" mode
Date: Wed, 19 Dec 2012 20:08:07 +0700 [thread overview]
Message-ID: <1355922488-20976-3-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1355922488-20976-1-git-send-email-pclouds@gmail.com>
By default wildmatch(,, 0) is equivalent with fnmatch(,, FNM_PATHNAME).
This patch makes wildmatch behave more like fnmatch: FNM_PATHNAME
behavior is always applied when FNM_PATHNAME is passed to
wildmatch. Without FNM_PATHNAME, wildmatch accepts '/' in '?' and '[]'
and treats '*' like '**' in the original version.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
The choice of name "pathspec" is not good. I couldn't think of
anything appropriate and just did not care enough at this point.
dir.c | 2 +-
t/t3070-wildmatch.sh | 27 +++++++++++++++++++++++++++
test-wildmatch.c | 4 +++-
wildmatch.c | 12 ++++++++----
4 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/dir.c b/dir.c
index cb7328b..7bbd6f8 100644
--- a/dir.c
+++ b/dir.c
@@ -595,7 +595,7 @@ int match_pathname(const char *pathname, int pathlen,
}
return wildmatch(pattern, name,
- ignore_case ? FNM_CASEFOLD : 0) == 0;
+ FNM_PATHNAME | (ignore_case ? FNM_CASEFOLD : 0)) == 0;
}
/* Scan the list and let the last match determine the fate.
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index 3155eab..ca4ac46 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -29,6 +29,18 @@ match() {
fi
}
+pathspec() {
+ if [ $1 = 1 ]; then
+ test_expect_success "pathspec: match '$2' '$3'" "
+ test-wildmatch pathspec '$2' '$3'
+ "
+ else
+ test_expect_success "pathspec: no match '$2' '$3'" "
+ ! test-wildmatch pathspec '$2' '$3'
+ "
+ fi
+}
+
# Basic wildmat features
match 1 1 foo foo
match 0 0 foo bar
@@ -192,4 +204,19 @@ match 0 0 'XXX/adobe/courier/bold/o/normal//12/120/75/75/X/70/iso8859/1' 'XXX/*/
match 1 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt' '**/*a*b*g*n*t'
match 0 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txtz' '**/*a*b*g*n*t'
+pathspec 1 foo foo
+pathspec 0 foo fo
+pathspec 1 foo/bar foo/bar
+pathspec 1 foo/bar 'foo/*'
+pathspec 1 foo/bba/arr 'foo/*'
+pathspec 1 foo/bba/arr 'foo/**'
+pathspec 1 foo/bba/arr 'foo*'
+pathspec 1 foo/bba/arr 'foo**'
+pathspec 1 foo/bba/arr 'foo/*arr'
+pathspec 1 foo/bba/arr 'foo/**arr'
+pathspec 0 foo/bba/arr 'foo/*z'
+pathspec 0 foo/bba/arr 'foo/**z'
+pathspec 1 foo/bar 'foo?bar'
+pathspec 1 foo/bar 'foo[/]bar'
+
test_done
diff --git a/test-wildmatch.c b/test-wildmatch.c
index e384c8e..7fefa4f 100644
--- a/test-wildmatch.c
+++ b/test-wildmatch.c
@@ -12,9 +12,11 @@ int main(int argc, char **argv)
argv[i] += 3;
}
if (!strcmp(argv[1], "wildmatch"))
+ return !!wildmatch(argv[3], argv[2], FNM_PATHNAME);
+ else if (!strcmp(argv[1], "pathspec"))
return !!wildmatch(argv[3], argv[2], 0);
else if (!strcmp(argv[1], "iwildmatch"))
- return !!wildmatch(argv[3], argv[2], FNM_CASEFOLD);
+ return !!wildmatch(argv[3], argv[2], FNM_PATHNAME | FNM_CASEFOLD);
else if (!strcmp(argv[1], "fnmatch"))
return !!fnmatch(argv[3], argv[2], FNM_PATHNAME);
else
diff --git a/wildmatch.c b/wildmatch.c
index 9586ed9..6aa034f 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -80,14 +80,17 @@ static int dowild(const uchar *p, const uchar *text, int flags)
continue;
case '?':
/* Match anything but '/'. */
- if (t_ch == '/')
+ if (flags & FNM_PATHNAME && t_ch == '/')
return NOMATCH;
continue;
case '*':
if (*++p == '*') {
const uchar *prev_p = p - 2;
while (*++p == '*') {}
- if ((prev_p == text || *prev_p == '/') ||
+ if (!(flags & FNM_PATHNAME))
+ /* without FNM_PATHNAME, '*' == '**' */
+ special = TRUE;
+ else if ((prev_p == text || *prev_p == '/') ||
(*p == '\0' || *p == '/' ||
(p[0] == '\\' && p[1] == '/'))) {
/*
@@ -106,7 +109,7 @@ static int dowild(const uchar *p, const uchar *text, int flags)
} else
return ABORT_MALFORMED;
} else
- special = FALSE;
+ special = flags & FNM_PATHNAME ? FALSE: TRUE;
if (*p == '\0') {
/* Trailing "**" matches everything. Trailing "*" matches
* only if there are no more slash characters. */
@@ -217,7 +220,8 @@ static int dowild(const uchar *p, const uchar *text, int flags)
} else if (t_ch == p_ch)
matched = TRUE;
} while (prev_ch = p_ch, (p_ch = *++p) != ']');
- if (matched == special || t_ch == '/')
+ if (matched == special ||
+ (flags & FNM_PATHNAME && t_ch == '/'))
return NOMATCH;
continue;
}
--
1.8.0.rc2.23.g1fb49df
next prev parent reply other threads:[~2012-12-19 13:33 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-19 13:08 [PATCH/WIP 0/3] Bye bye fnmatch() Nguyễn Thái Ngọc Duy
2012-12-19 13:08 ` [PATCH 1/3] wildmatch: make dowild() take arbitrary flags Nguyễn Thái Ngọc Duy
2012-12-19 16:32 ` Junio C Hamano
2012-12-19 13:08 ` Nguyễn Thái Ngọc Duy [this message]
2012-12-19 17:24 ` [PATCH 2/3] wildmatch: support "no FNM_PATHNAME" mode Junio C Hamano
2012-12-20 1:55 ` Nguyen Thai Ngoc Duy
2012-12-20 13:34 ` Nguyen Thai Ngoc Duy
2012-12-19 13:08 ` [PATCH 3/3] Convert all fnmatch() calls to wildmatch() Nguyễn Thái Ngọc Duy
2012-12-19 18:36 ` Junio C Hamano
2012-12-20 12:36 ` Nguyen Thai Ngoc Duy
2012-12-19 13:21 ` [PATCH/WIP 0/3] Bye bye fnmatch() Nguyen Thai Ngoc 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=1355922488-20976-3-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).