summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-09-13 19:43:39 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-09-13 19:43:39 +0200
commite78aeefa188eb1e13a2fa9ac5f707c39a0c9a5ae (patch)
treed61470051ba8e8d1bc78cfa80ec29f13d395b520
parent9562ebcd6b26e321f638a2a9795e2c1b493e033e (diff)
parenta1859e21f36f47f05771ef7915dfe89840d4f2c6 (diff)
downloadlibgit2-e78aeefa188eb1e13a2fa9ac5f707c39a0c9a5ae.tar.gz
Merge pull request #3420 from ethomson/iterator
iterator: advance the tree iterator smartly
-rw-r--r--src/iterator.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/src/iterator.c b/src/iterator.c
index e35c8dc85..9f3f7a9c7 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);
}