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 */