mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 18:22:16 +00:00
iterator: advance the tree iterator smartly
While advancing the tree iterator, if we advance over things that we aren't interested in, then call `current`. Which may *itself* call advance. While advancing the tree iterator, if we advance over things that we aren't interested in, then call `current`. Which may *itself* call advance. While advancing the tree iterator, if we advance over things that we aren't interested in, then call `current`. Which may *itself* call advance. While advancing the tree iterator, if we advance over things that we aren't interested in, then call `current`. Which may *itself* call advance. While advancing the tree iterator, if we advance over things that we aren't interested in, then call `current`. Which may *itself* call advance. Error: stack overflow.
This commit is contained in:
parent
6c21211c38
commit
a1859e21f3
108
src/iterator.c
108
src/iterator.c
@ -640,74 +640,32 @@ 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__current(
|
||||
const git_index_entry **out, git_iterator *self)
|
||||
{
|
||||
const git_index_entry *entry = NULL;
|
||||
iterator_pathlist__match_t m;
|
||||
int error;
|
||||
|
||||
do {
|
||||
if ((error = tree_iterator__current_internal(&entry, self)) < 0)
|
||||
return error;
|
||||
|
||||
if (self->pathlist.length) {
|
||||
m = iterator_pathlist__match(
|
||||
self, entry->path, strlen(entry->path));
|
||||
|
||||
if (m != ITERATOR_PATHLIST_MATCH) {
|
||||
if ((error = tree_iterator__advance(&entry, self)) < 0)
|
||||
return error;
|
||||
|
||||
entry = NULL;
|
||||
}
|
||||
}
|
||||
} while (!entry);
|
||||
|
||||
if (out)
|
||||
*out = entry;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int tree_iterator__advance_into(
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
static int tree_iterator__advance_into_internal(git_iterator *self)
|
||||
{
|
||||
int error = 0;
|
||||
tree_iterator *ti = (tree_iterator *)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);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int tree_iterator__advance(
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
static int tree_iterator__advance_internal(git_iterator *self)
|
||||
{
|
||||
int error;
|
||||
tree_iterator *ti = (tree_iterator *)self;
|
||||
tree_iterator_frame *tf = ti->head;
|
||||
|
||||
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);
|
||||
return 0;
|
||||
|
||||
if (iterator__do_autoexpand(ti) && iterator__include_trees(ti) &&
|
||||
tree_iterator__at_tree(ti))
|
||||
return tree_iterator__advance_into(entry, self);
|
||||
return tree_iterator__advance_into_internal(self);
|
||||
|
||||
if (ti->path_has_filename) {
|
||||
git_buf_rtruncate_at_char(&ti->path, '/');
|
||||
@ -725,7 +683,63 @@ static int tree_iterator__advance(
|
||||
|
||||
/* 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__advance_into_internal(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tree_iterator__current(
|
||||
const git_index_entry **out, git_iterator *self)
|
||||
{
|
||||
const git_index_entry *entry = NULL;
|
||||
iterator_pathlist__match_t m;
|
||||
int error;
|
||||
|
||||
do {
|
||||
if ((error = tree_iterator__current_internal(&entry, self)) < 0)
|
||||
return error;
|
||||
|
||||
if (self->pathlist.length) {
|
||||
m = iterator_pathlist__match(
|
||||
self, entry->path, strlen(entry->path));
|
||||
|
||||
if (m != ITERATOR_PATHLIST_MATCH) {
|
||||
if ((error = tree_iterator__advance_internal(self)) < 0)
|
||||
return error;
|
||||
|
||||
entry = NULL;
|
||||
}
|
||||
}
|
||||
} while (!entry);
|
||||
|
||||
if (out)
|
||||
*out = entry;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int tree_iterator__advance(
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
int error = tree_iterator__advance_internal(self);
|
||||
|
||||
iterator__clear_entry(entry);
|
||||
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
return tree_iterator__current(entry, self);
|
||||
}
|
||||
|
||||
static int tree_iterator__advance_into(
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
int error = tree_iterator__advance_into_internal(self);
|
||||
|
||||
iterator__clear_entry(entry);
|
||||
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
return tree_iterator__current(entry, self);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user