We could also optimize for ignore_case, assuming that non-ascii characters are not used in most repositories. We could check that all patterns and pathnames are ascii-only, then use git's toupper() before after user 0m0.516s 0m0.433s user 0m0.523s 0m0.437s user 0m0.532s 0m0.443s user 0m0.533s 0m0.448s user 0m0.535s 0m0.449s user 0m0.542s 0m0.452s user 0m0.546s 0m0.453s user 0m0.551s 0m0.458s user 0m0.556s 0m0.459s user 0m0.561s 0m0.462s Suggested-by: Fredrik Gustafsson <iveqy@xxxxxxxxx> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- dir.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/dir.c b/dir.c index 46b24db..7b6a625 100644 --- a/dir.c +++ b/dir.c @@ -21,6 +21,25 @@ 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); +/* + * This function is more like memequal_icase than strnequal_icase as + * it does not check for NUL. The caller is not supposed to pass a + * length longer than both input strings + */ +static inline strnequal_icase(const char *a, const char *b, int n) +{ + if (!ignore_case) { + while (n && *a == *b) { + a++; + b++; + n--; + } + return n == 0; + } + + return !strncmp_icase(a, b, n); +} + inline int git_fnmatch(const char *pattern, const char *string, int flags, int prefix) { @@ -611,11 +630,11 @@ int match_basename(const char *basename, int basenamelen, { if (prefix == patternlen) { if (patternlen == basenamelen && - !strncmp_icase(pattern, basename, patternlen)) + strnequal_icase(pattern, basename, patternlen)) return 1; } else if (flags & EXC_FLAG_ENDSWITH) { if (patternlen - 1 <= basenamelen && - !strncmp_icase(pattern + 1, + strnequal_icase(pattern + 1, basename + basenamelen - patternlen + 1, patternlen - 1)) return 1; @@ -649,7 +668,7 @@ int match_pathname(const char *pathname, int pathlen, */ if (pathlen < baselen + 1 || (baselen && (pathname[baselen] != '/' || - strncmp_icase(pathname, base, baselen)))) + !strnequal_icase(pathname, base, baselen)))) return 0; namelen = baselen ? pathlen - baselen - 1 : pathlen; @@ -663,7 +682,7 @@ int match_pathname(const char *pathname, int pathlen, if (prefix > namelen) return 0; - if (strncmp_icase(pattern, name, prefix)) + if (!strnequal_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