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
}