Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to