Skip to content

Commit b559263

Browse files
pcloudsgitster
authored andcommitted
exclude: split pathname matching code into a separate function
Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a3ea4d7 commit b559263

File tree

1 file changed

+53
-32
lines changed

1 file changed

+53
-32
lines changed

dir.c

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,53 @@ static int match_basename(const char *basename, int basenamelen,
522522
return 0;
523523
}
524524

525+
static int match_pathname(const char *pathname, int pathlen,
526+
const char *base, int baselen,
527+
const char *pattern, int prefix, int patternlen,
528+
int flags)
529+
{
530+
const char *name;
531+
int namelen;
532+
533+
/*
534+
* match with FNM_PATHNAME; the pattern has base implicitly
535+
* in front of it.
536+
*/
537+
if (*pattern == '/') {
538+
pattern++;
539+
prefix--;
540+
}
541+
542+
/*
543+
* baselen does not count the trailing slash. base[] may or
544+
* may not end with a trailing slash though.
545+
*/
546+
if (pathlen < baselen + 1 ||
547+
(baselen && pathname[baselen] != '/') ||
548+
strncmp_icase(pathname, base, baselen))
549+
return 0;
550+
551+
namelen = baselen ? pathlen - baselen - 1 : pathlen;
552+
name = pathname + pathlen - namelen;
553+
554+
if (prefix) {
555+
/*
556+
* if the non-wildcard part is longer than the
557+
* remaining pathname, surely it cannot match.
558+
*/
559+
if (prefix > namelen)
560+
return 0;
561+
562+
if (strncmp_icase(pattern, name, prefix))
563+
return 0;
564+
pattern += prefix;
565+
name += prefix;
566+
namelen -= prefix;
567+
}
568+
569+
return fnmatch_icase(pattern, name, FNM_PATHNAME) == 0;
570+
}
571+
525572
/* Scan the list and let the last match determine the fate.
526573
* Return 1 for exclude, 0 for include and -1 for undecided.
527574
*/
@@ -536,9 +583,9 @@ int excluded_from_list(const char *pathname,
536583

537584
for (i = el->nr - 1; 0 <= i; i--) {
538585
struct exclude *x = el->excludes[i];
539-
const char *name, *exclude = x->pattern;
586+
const char *exclude = x->pattern;
540587
int to_exclude = x->to_exclude;
541-
int namelen, prefix = x->nowildcardlen;
588+
int prefix = x->nowildcardlen;
542589

543590
if (x->flags & EXC_FLAG_MUSTBEDIR) {
544591
if (*dtype == DT_UNKNOWN)
@@ -556,36 +603,10 @@ int excluded_from_list(const char *pathname,
556603
continue;
557604
}
558605

559-
/* match with FNM_PATHNAME:
560-
* exclude has base (baselen long) implicitly in front of it.
561-
*/
562-
if (*exclude == '/') {
563-
exclude++;
564-
prefix--;
565-
}
566-
567-
if (pathlen < x->baselen ||
568-
(x->baselen && pathname[x->baselen-1] != '/') ||
569-
strncmp_icase(pathname, x->base, x->baselen))
570-
continue;
571-
572-
namelen = x->baselen ? pathlen - x->baselen : pathlen;
573-
name = pathname + pathlen - namelen;
574-
575-
/* if the non-wildcard part is longer than the
576-
remaining pathname, surely it cannot match */
577-
if (prefix > namelen)
578-
continue;
579-
580-
if (prefix) {
581-
if (strncmp_icase(exclude, name, prefix))
582-
continue;
583-
exclude += prefix;
584-
name += prefix;
585-
namelen -= prefix;
586-
}
587-
588-
if (!fnmatch_icase(exclude, name, FNM_PATHNAME))
606+
assert(x->baselen == 0 || x->base[x->baselen - 1] == '/');
607+
if (match_pathname(pathname, pathlen,
608+
x->base, x->baselen ? x->baselen - 1 : 0,
609+
exclude, prefix, x->patternlen, x->flags))
589610
return to_exclude;
590611
}
591612
return -1; /* undecided */

0 commit comments

Comments
 (0)