Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
---
cache.h | 17 +++++++++++++++++
dir.c | 18 +++++++++++-------
tree-walk.c | 30 +++++++++++++++++++-----------
3 files changed, 47 insertions(+), 18 deletions(-)
diff --git a/cache.h b/cache.h
index c3b5585..216f87c 100644
--- a/cache.h
+++ b/cache.h
@@ -522,6 +522,23 @@ extern void free_pathspec(struct pathspec *);
extern int ce_path_match(const struct cache_entry *ce, const struct pathspec
*pathspec);
extern int limit_pathspec_to_literal(void);
+static inline int ps_strncmp(const struct pathspec_item *item,
+ const char *s1, const char *s2, size_t n)
+{
+ if (item->magic & PATHSPEC_ICASE)
+ return strncasecmp(s1, s2, n);
+ else
+ return strncmp(s1, s2, n);
+}
+
+static inline int ps_strcmp(const struct pathspec_item *item,
+ const char *s1, const char *s2)
+{
+ if (item->magic & PATHSPEC_ICASE)
+ return strcasecmp(s1, s2);
+ else
+ return strcmp(s1, s2);
+}
#define HASH_WRITE_OBJECT 1
#define HASH_FORMAT_CHECK 2
diff --git a/dir.c b/dir.c
index d0e7ca8..e9edb65 100644
--- a/dir.c
+++ b/dir.c
@@ -42,7 +42,7 @@ inline int git_fnmatch(const struct pathspec_item *item,
int prefix)
{
if (prefix > 0) {
- if (strncmp(pattern, string, prefix))
+ if (ps_strncmp(item, pattern, string, prefix))
return FNM_NOMATCH;
pattern += prefix;
string += prefix;
@@ -51,14 +51,16 @@ inline int git_fnmatch(const struct pathspec_item *item,
int pattern_len = strlen(++pattern);
int string_len = strlen(string);
return string_len < pattern_len ||
- strcmp(pattern,
- string + string_len - pattern_len);
+ ps_strcmp(item, pattern,
+ string + string_len - pattern_len);
}
if (item->magic & PATHSPEC_GLOB)
- return wildmatch(pattern, string, 0);
+ return wildmatch(pattern, string,
+ item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD :
0);
else
/* wildmatch has not learned no FNM_PATHNAME mode yet */
- return fnmatch(pattern, string, 0);
+ return fnmatch(pattern, string,
+ item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0);
}
static size_t common_prefix_len(const struct pathspec *pathspec)
@@ -162,7 +164,7 @@ static int match_pathspec_item(const struct pathspec_item
*item, int prefix,
if (!*match)
return MATCHED_RECURSIVELY;
- if (matchlen <= namelen && !strncmp(match, name, matchlen)) {
+ if (matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) {
if (matchlen == namelen)
return MATCHED_EXACTLY;
@@ -192,10 +194,12 @@ int match_pathspec_depth(const struct pathspec *ps,
{
int i, retval = 0;
+ /* BUG: we should not match icase on the prefix part */
GUARD_PATHSPEC(ps,
PATHSPEC_FROMTOP |
PATHSPEC_LITERAL |
- PATHSPEC_GLOB);
+ PATHSPEC_GLOB |
+ PATHSPEC_ICASE);
if (!ps->nr) {
if (!ps->recursive || ps->max_depth == -1)
diff --git a/tree-walk.c b/tree-walk.c
index 1679ce7..3d9c2ba 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -488,7 +488,8 @@ int get_tree_entry(const unsigned char *tree_sha1, const
char *name, unsigned ch
return retval;
}
-static int match_entry(const struct name_entry *entry, int pathlen,
+static int match_entry(const struct pathspec_item *item,
+ const struct name_entry *entry, int pathlen,
const char *match, int matchlen,
enum interesting *never_interesting)
{
@@ -504,8 +505,8 @@ static int match_entry(const struct name_entry *entry, int
pathlen,
* Does match sort strictly earlier than path
* with their common parts?
*/
- m = strncmp(match, entry->path,
- (matchlen < pathlen) ? matchlen : pathlen);
+ m = ps_strncmp(item, match, entry->path,
+ (matchlen < pathlen) ? matchlen : pathlen);
if (m < 0)
return 0;
@@ -540,7 +541,7 @@ static int match_entry(const struct name_entry *entry, int
pathlen,
* we cheated and did not do strncmp(), so we do
* that here.
*/
- m = strncmp(match, entry->path, pathlen);
+ m = ps_strncmp(item, match, entry->path, pathlen);
/*
* If common part matched earlier then it is a hit,
@@ -553,10 +554,11 @@ static int match_entry(const struct name_entry *entry,
int pathlen,
return 0;
}
-static int match_dir_prefix(const char *base,
+static int match_dir_prefix(const struct pathspec_item *item,
+ const char *base,
const char *match, int matchlen)
{
- if (strncmp(base, match, matchlen))
+ if (ps_strncmp(item, base, match, matchlen))
return 0;
/*
@@ -593,7 +595,7 @@ static int match_wildcard_base(const struct pathspec_item
*item,
*/
if (baselen >= matchlen) {
*matched = matchlen;
- return !strncmp(base, match, matchlen);
+ return !ps_strncmp(item, base, match, matchlen);
}
dirlen = matchlen;
@@ -606,7 +608,7 @@ static int match_wildcard_base(const struct pathspec_item
*item,
* base ends with '/' so we are sure it really matches
* directory
*/
- if (strncmp(base, match, baselen))
+ if (ps_strncmp(item, base, match, baselen))
return 0;
*matched = baselen;
} else
@@ -635,10 +637,16 @@ enum interesting tree_entry_interesting(const struct
name_entry *entry,
enum interesting never_interesting = ps->has_wildcard ?
entry_not_interesting : all_entries_not_interesting;
+ /*
+ * BUG: we should not match icase on the prefix part. The
+ * prefix length is in 'ps'. Although using it won't be easy
+ * as the pattern is cut into pieces...
+ */
GUARD_PATHSPEC(ps,
PATHSPEC_FROMTOP |
PATHSPEC_LITERAL |
- PATHSPEC_GLOB);
+ PATHSPEC_GLOB |
+ PATHSPEC_ICASE);
if (!ps->nr) {
if (!ps->recursive || ps->max_depth == -1)
@@ -659,7 +667,7 @@ enum interesting tree_entry_interesting(const struct
name_entry *entry,
if (baselen >= matchlen) {
/* If it doesn't match, move along... */
- if (!match_dir_prefix(base_str, match, matchlen))
+ if (!match_dir_prefix(item, base_str, match, matchlen))
goto match_wildcards;
if (!ps->recursive || ps->max_depth == -1)
@@ -674,7 +682,7 @@ enum interesting tree_entry_interesting(const struct
name_entry *entry,
/* Either there must be no base, or the base must match. */
if (baselen == 0 || !strncmp(base_str, match, baselen)) {
- if (match_entry(entry, pathlen,
+ if (match_entry(item, entry, pathlen,
match + baselen, matchlen - baselen,
&never_interesting))
return entry_interesting;
--
1.8.0.rc2.23.g1fb49df
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html