exclude: split pathname matching code into a separate function
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Oct 15, 2012 at 13:24 UTC
b559263216146b3f452c35ea1b12937d5533c89e
1 file changed
+53
-32
dir.c
+53
-32
@@ -522,6 +522,53 @@ static int match_basename(const char *basename, int basenamelen,
522
return 0;
523
}
524
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
+
572
/* Scan the list and let the last match determine the fate.
573
* Return 1 for exclude, 0 for include and -1 for undecided.
574
*/
@@ -536,9 +583,9 @@ int excluded_from_list(const char *pathname,
583
584
for (i = el->nr - 1; 0 <= i; i--) {
585
struct exclude *x = el->excludes[i];
539
- const char *name, *exclude = x->pattern;
586
+ const char *exclude = x->pattern;
587
int to_exclude = x->to_exclude;
541
- int namelen, prefix = x->nowildcardlen;
588
+ int prefix = x->nowildcardlen;
589
590
if (x->flags & EXC_FLAG_MUSTBEDIR) {
591
if (*dtype == DT_UNKNOWN)
@@ -556,36 +603,10 @@ int excluded_from_list(const char *pathname,
603
continue;
604
}
605
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))
610
return to_exclude;
611
}
612
return -1; /* undecided */