treat_leading_path: 0.000 0.000 read_directory: 3.578 3.501 +treat_one_path: 2.323 2.257 ++is_excluded: 2.117 2.056 +++prep_exclude: 0.224 0.216 +++matching: 1.544 1.493 ++dir_exist: 0.035 0.035 ++index_name_exists: 0.290 0.292 lazy_init_name_hash: 0.258 0.256 +simplify_away: 0.087 0.084 +dir_add_name: 0.445 0.447 Suggested-by: Fredrik Gustafsson <iveqy@xxxxxxxxx> Suggested-by: Antoine Pelisse <apelisse@xxxxxxxxx> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- dir.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/dir.c b/dir.c index a2ab200..26c3b3a 100644 --- a/dir.c +++ b/dir.c @@ -47,6 +47,29 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, in int check_only, const struct path_simplify *simplify); static int get_dtype(struct dirent *de, const char *path, int len); +static inline int memequal_icase(const char *a, const char *b, int n) +{ + if (!memcmp(a, b, n)) + return 1; + + if (!ignore_case) + return 0; + + /* + * This assumes that ASCII is used in most repositories. We + * try the ascii-only version first (i.e. Git's + * toupper). Failing that, fall back to normal strncasecmp. + */ + while (n && toupper(*a) == toupper(*b)) { + a++; + b++; + n--; + } + if (!n) + return 1; + return !strncasecmp(a, b, n); +} + inline int git_fnmatch(const char *pattern, const char *string, int flags, int prefix) { @@ -637,11 +660,11 @@ int match_basename(const char *basename, int basenamelen, { if (prefix == patternlen) { if (patternlen == basenamelen && - !strncmp_icase(pattern, basename, patternlen)) + memequal_icase(pattern, basename, patternlen)) return 1; } else if (flags & EXC_FLAG_ENDSWITH) { if (patternlen - 1 <= basenamelen && - !strncmp_icase(pattern + 1, + memequal_icase(pattern + 1, basename + basenamelen - patternlen + 1, patternlen - 1)) return 1; @@ -675,7 +698,7 @@ int match_pathname(const char *pathname, int pathlen, */ if (pathlen < baselen + 1 || (baselen && (pathname[baselen] != '/' || - strncmp_icase(pathname, base, baselen)))) + !memequal_icase(pathname, base, baselen)))) return 0; namelen = baselen ? pathlen - baselen - 1 : pathlen; @@ -689,7 +712,7 @@ int match_pathname(const char *pathname, int pathlen, if (prefix > namelen) return 0; - if (strncmp_icase(pattern, name, prefix)) + if (!memequal_icase(pattern, name, prefix)) return 0; pattern += prefix; name += prefix; -- 1.8.1.2.536.gf441e6d -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html