@matheusbsbs / matheus-bagliano / commits / 58c4d66619
Fork 0

tree_entry_interesting(): refactor into separate smaller functions

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 Dec 15, 2010 at 22:02 UTC 58c4d66619eb21fa23a1305401e0ec4988c1c17e
1 file changed +93 -77
tree-walk.c
+93 -77
@@ -456,6 +456,90 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
456 return retval;
457 }
458
459 +static int match_entry(const struct name_entry *entry, int pathlen,
460 + const char *match, int matchlen,
461 + int *never_interesting)
462 +{
463 + int m = -1; /* signals that we haven't called strncmp() */
464 +
465 + if (*never_interesting) {
466 + /*
467 + * We have not seen any match that sorts later
468 + * than the current path.
469 + */
470 +
471 + /*
472 + * Does match sort strictly earlier than path
473 + * with their common parts?
474 + */
475 + m = strncmp(match, entry->path,
476 + (matchlen < pathlen) ? matchlen : pathlen);
477 + if (m < 0)
478 + return 0;
479 +
480 + /*
481 + * If we come here even once, that means there is at
482 + * least one pathspec that would sort equal to or
483 + * later than the path we are currently looking at.
484 + * In other words, if we have never reached this point
485 + * after iterating all pathspecs, it means all
486 + * pathspecs are either outside of base, or inside the
487 + * base but sorts strictly earlier than the current
488 + * one. In either case, they will never match the
489 + * subsequent entries. In such a case, we initialized
490 + * the variable to -1 and that is what will be
491 + * returned, allowing the caller to terminate early.
492 + */
493 + *never_interesting = 0;
494 + }
495 +
496 + if (pathlen > matchlen)
497 + return 0;
498 +
499 + if (matchlen > pathlen) {
500 + if (match[pathlen] != '/')
501 + return 0;
502 + if (!S_ISDIR(entry->mode))
503 + return 0;
504 + }
505 +
506 + if (m == -1)
507 + /*
508 + * we cheated and did not do strncmp(), so we do
509 + * that here.
510 + */
511 + m = strncmp(match, entry->path, pathlen);
512 +
513 + /*
514 + * If common part matched earlier then it is a hit,
515 + * because we rejected the case where path is not a
516 + * leading directory and is shorter than match.
517 + */
518 + if (!m)
519 + return 1;
520 +
521 + return 0;
522 +}
523 +
524 +static int match_dir_prefix(const char *base, int baselen,
525 + const char *match, int matchlen)
526 +{
527 + if (strncmp(base, match, matchlen))
528 + return 0;
529 +
530 + /*
531 + * If the base is a subdirectory of a path which
532 + * was specified, all of them are interesting.
533 + */
534 + if (!matchlen ||
535 + base[matchlen] == '/' ||
536 + match[matchlen - 1] == '/')
537 + return 1;
538 +
539 + /* Just a random prefix match */
540 + return 0;
541 +}
542 +
543 /*
544 * Is a tree entry interesting given the pathspec we have?
545 *
@@ -468,13 +552,12 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
552 * - negative for "no, and no subsequent entries will be either"
553 */
554 int tree_entry_interesting(const struct name_entry *entry,
471 - const struct strbuf *base_buf,
555 + const struct strbuf *base,
556 const struct pathspec *ps)
557 {
558 int i;
475 - int pathlen, baselen = base_buf->len;
559 + int pathlen, baselen = base->len;
560 int never_interesting = -1;
477 - const char *base = base_buf->buf;
561
562 if (!ps || !ps->nr)
563 return 2;
@@ -485,88 +568,21 @@ int tree_entry_interesting(const struct name_entry *entry,
568 const struct pathspec_item *item = ps->items+i;
569 const char *match = item->match;
570 int matchlen = item->len;
488 - int m = -1; /* signals that we haven't called strncmp() */
571
572 if (baselen >= matchlen) {
573 /* If it doesn't match, move along... */
492 - if (strncmp(base, match, matchlen))
574 + if (!match_dir_prefix(base->buf, baselen, match, matchlen))
575 continue;
494 -
495 - /*
496 - * If the base is a subdirectory of a path which
497 - * was specified, all of them are interesting.
498 - */
499 - if (!matchlen ||
500 - base[matchlen] == '/' ||
501 - match[matchlen - 1] == '/')
502 - return 2;
503 -
504 - /* Just a random prefix match */
505 - continue;
576 + return 2;
577 }
578
579 /* Does the base match? */
509 - if (strncmp(base, match, baselen))
510 - continue;
511 -
512 - match += baselen;
513 - matchlen -= baselen;
514 -
515 - if (never_interesting) {
516 - /*
517 - * We have not seen any match that sorts later
518 - * than the current path.
519 - */
520 -
521 - /*
522 - * Does match sort strictly earlier than path
523 - * with their common parts?
524 - */
525 - m = strncmp(match, entry->path,
526 - (matchlen < pathlen) ? matchlen : pathlen);
527 - if (m < 0)
528 - continue;
529 -
530 - /*
531 - * If we come here even once, that means there is at
532 - * least one pathspec that would sort equal to or
533 - * later than the path we are currently looking at.
534 - * In other words, if we have never reached this point
535 - * after iterating all pathspecs, it means all
536 - * pathspecs are either outside of base, or inside the
537 - * base but sorts strictly earlier than the current
538 - * one. In either case, they will never match the
539 - * subsequent entries. In such a case, we initialized
540 - * the variable to -1 and that is what will be
541 - * returned, allowing the caller to terminate early.
542 - */
543 - never_interesting = 0;
580 + if (!strncmp(base->buf, match, baselen)) {
581 + if (match_entry(entry, pathlen,
582 + match + baselen, matchlen - baselen,
583 + &never_interesting))
584 + return 1;
585 }
545 -
546 - if (pathlen > matchlen)
547 - continue;
548 -
549 - if (matchlen > pathlen) {
550 - if (match[pathlen] != '/')
551 - continue;
552 - if (!S_ISDIR(entry->mode))
553 - continue;
554 - }
555 -
556 - if (m == -1)
557 - /*
558 - * we cheated and did not do strncmp(), so we do
559 - * that here.
560 - */
561 - m = strncmp(match, entry->path, pathlen);
562 -
563 - /*
564 - * If common part matched earlier then it is a hit,
565 - * because we rejected the case where path is not a
566 - * leading directory and is shorter than match.
567 - */
568 - if (!m)
569 - return 1;
586 }
587 return never_interesting; /* No matches */
588 }