Merge pull request #3420 from ethomson/iterator iterator: advance the tree iterator smartly
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
diff --git a/src/iterator.c b/src/iterator.c
index e35c8dc..9f3f7a9 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -640,8 +640,53 @@ static int tree_iterator__current_internal(
return 0;
}
-static int tree_iterator__advance(
- const git_index_entry **out, git_iterator *self);
+static int tree_iterator__advance_into_internal(git_iterator *self)
+{
+ int error = 0;
+ tree_iterator *ti = (tree_iterator *)self;
+
+ if (tree_iterator__at_tree(ti))
+ error = tree_iterator__push_frame(ti);
+
+ return error;
+}
+
+static int tree_iterator__advance_internal(git_iterator *self)
+{
+ int error;
+ tree_iterator *ti = (tree_iterator *)self;
+ tree_iterator_frame *tf = ti->head;
+
+ if (tf->current >= tf->n_entries)
+ return GIT_ITEROVER;
+
+ if (!iterator__has_been_accessed(ti))
+ return 0;
+
+ if (iterator__do_autoexpand(ti) && iterator__include_trees(ti) &&
+ tree_iterator__at_tree(ti))
+ return tree_iterator__advance_into_internal(self);
+
+ if (ti->path_has_filename) {
+ git_buf_rtruncate_at_char(&ti->path, '/');
+ ti->path_has_filename = ti->entry_is_current = false;
+ }
+
+ /* scan forward and up, advancing in frame or popping frame when done */
+ while (!tree_iterator__move_to_next(ti, tf) &&
+ tree_iterator__pop_frame(ti, false))
+ tf = ti->head;
+
+ /* find next and load trees */
+ if ((error = tree_iterator__set_next(ti, tf)) < 0)
+ return error;
+
+ /* deal with include_trees / auto_expand as needed */
+ if (!iterator__include_trees(ti) && tree_iterator__at_tree(ti))
+ return tree_iterator__advance_into_internal(self);
+
+ return 0;
+}
static int tree_iterator__current(
const git_index_entry **out, git_iterator *self)
@@ -659,7 +704,7 @@ static int tree_iterator__current(
self, entry->path, strlen(entry->path));
if (m != ITERATOR_PATHLIST_MATCH) {
- if ((error = tree_iterator__advance(&entry, self)) < 0)
+ if ((error = tree_iterator__advance_internal(self)) < 0)
return error;
entry = NULL;
@@ -673,60 +718,29 @@ static int tree_iterator__current(
return error;
}
-static int tree_iterator__advance_into(
+static int tree_iterator__advance(
const git_index_entry **entry, git_iterator *self)
{
- int error = 0;
- tree_iterator *ti = (tree_iterator *)self;
+ int error = tree_iterator__advance_internal(self);
iterator__clear_entry(entry);
- if (tree_iterator__at_tree(ti))
- error = tree_iterator__push_frame(ti);
-
- if (!error && entry)
- error = tree_iterator__current(entry, self);
+ if (error < 0)
+ return error;
- return error;
+ return tree_iterator__current(entry, self);
}
-static int tree_iterator__advance(
+static int tree_iterator__advance_into(
const git_index_entry **entry, git_iterator *self)
{
- int error;
- tree_iterator *ti = (tree_iterator *)self;
- tree_iterator_frame *tf = ti->head;
+ int error = tree_iterator__advance_into_internal(self);
iterator__clear_entry(entry);
- if (tf->current >= tf->n_entries)
- return GIT_ITEROVER;
-
- if (!iterator__has_been_accessed(ti))
- return tree_iterator__current(entry, self);
-
- if (iterator__do_autoexpand(ti) && iterator__include_trees(ti) &&
- tree_iterator__at_tree(ti))
- return tree_iterator__advance_into(entry, self);
-
- if (ti->path_has_filename) {
- git_buf_rtruncate_at_char(&ti->path, '/');
- ti->path_has_filename = ti->entry_is_current = false;
- }
-
- /* scan forward and up, advancing in frame or popping frame when done */
- while (!tree_iterator__move_to_next(ti, tf) &&
- tree_iterator__pop_frame(ti, false))
- tf = ti->head;
-
- /* find next and load trees */
- if ((error = tree_iterator__set_next(ti, tf)) < 0)
+ if (error < 0)
return error;
- /* deal with include_trees / auto_expand as needed */
- if (!iterator__include_trees(ti) && tree_iterator__at_tree(ti))
- return tree_iterator__advance_into(entry, self);
-
return tree_iterator__current(entry, self);
}