mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-11 18:17:54 +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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tree_iterator__advance(
|
static int tree_iterator__advance_into_internal(git_iterator *self)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
tree_iterator *ti = (tree_iterator *)self;
|
tree_iterator *ti = (tree_iterator *)self;
|
||||||
|
|
||||||
iterator__clear_entry(entry);
|
|
||||||
|
|
||||||
if (tree_iterator__at_tree(ti))
|
if (tree_iterator__at_tree(ti))
|
||||||
error = tree_iterator__push_frame(ti);
|
error = tree_iterator__push_frame(ti);
|
||||||
|
|
||||||
if (!error && entry)
|
|
||||||
error = tree_iterator__current(entry, self);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tree_iterator__advance(
|
static int tree_iterator__advance_internal(git_iterator *self)
|
||||||
const git_index_entry **entry, git_iterator *self)
|
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
tree_iterator *ti = (tree_iterator *)self;
|
tree_iterator *ti = (tree_iterator *)self;
|
||||||
tree_iterator_frame *tf = ti->head;
|
tree_iterator_frame *tf = ti->head;
|
||||||
|
|
||||||
iterator__clear_entry(entry);
|
|
||||||
|
|
||||||
if (tf->current >= tf->n_entries)
|
if (tf->current >= tf->n_entries)
|
||||||
return GIT_ITEROVER;
|
return GIT_ITEROVER;
|
||||||
|
|
||||||
if (!iterator__has_been_accessed(ti))
|
if (!iterator__has_been_accessed(ti))
|
||||||
return tree_iterator__current(entry, self);
|
return 0;
|
||||||
|
|
||||||
if (iterator__do_autoexpand(ti) && iterator__include_trees(ti) &&
|
if (iterator__do_autoexpand(ti) && iterator__include_trees(ti) &&
|
||||||
tree_iterator__at_tree(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) {
|
if (ti->path_has_filename) {
|
||||||
git_buf_rtruncate_at_char(&ti->path, '/');
|
git_buf_rtruncate_at_char(&ti->path, '/');
|
||||||
@ -725,7 +683,63 @@ static int tree_iterator__advance(
|
|||||||
|
|
||||||
/* deal with include_trees / auto_expand as needed */
|
/* deal with include_trees / auto_expand as needed */
|
||||||
if (!iterator__include_trees(ti) && tree_iterator__at_tree(ti))
|
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);
|
return tree_iterator__current(entry, self);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user