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
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.