Git-Raw
view release on metacpan or search on metacpan
deps/libgit2/src/libgit2/iterator.c view on Meta::CPAN
static void empty_iterator_free(git_iterator *i)
{
GIT_UNUSED(i);
}
typedef struct {
git_iterator base;
git_iterator_callbacks cb;
} empty_iterator;
int git_iterator_for_nothing(
git_iterator **out,
git_iterator_options *options)
{
empty_iterator *iter;
static git_iterator_callbacks callbacks = {
empty_iterator_noop,
empty_iterator_noop,
empty_iterator_noop,
empty_iterator_advance_over,
empty_iterator_reset,
empty_iterator_free
};
*out = NULL;
iter = git__calloc(1, sizeof(empty_iterator));
GIT_ERROR_CHECK_ALLOC(iter);
iter->base.type = GIT_ITERATOR_EMPTY;
iter->base.cb = &callbacks;
iter->base.flags = options->flags;
*out = &iter->base;
return 0;
}
/* Tree iterator */
typedef struct {
git_tree_entry *tree_entry;
const char *parent_path;
} tree_iterator_entry;
typedef struct {
git_tree *tree;
/* path to this particular frame (folder) */
git_str path;
/* a sorted list of the entries for this frame (folder), these are
* actually pointers to the iterator's entry pool.
*/
git_vector entries;
tree_iterator_entry *current;
size_t next_idx;
/* on case insensitive iterations, we also have an array of other
* paths that were case insensitively equal to this one, and their
* tree objects. we have coalesced the tree entries into this frame.
* a child `tree_iterator_entry` will contain a pointer to its actual
* parent path.
*/
git_vector similar_trees;
git_array_t(git_str) similar_paths;
} tree_iterator_frame;
typedef struct {
git_iterator base;
git_tree *root;
git_array_t(tree_iterator_frame) frames;
git_index_entry entry;
git_str entry_path;
/* a pool of entries to reduce the number of allocations */
git_pool entry_pool;
} tree_iterator;
GIT_INLINE(tree_iterator_frame *) tree_iterator_parent_frame(
tree_iterator *iter)
{
return iter->frames.size > 1 ?
&iter->frames.ptr[iter->frames.size-2] : NULL;
}
GIT_INLINE(tree_iterator_frame *) tree_iterator_current_frame(
tree_iterator *iter)
{
return iter->frames.size ? &iter->frames.ptr[iter->frames.size-1] : NULL;
}
GIT_INLINE(int) tree_entry_cmp(
const git_tree_entry *a, const git_tree_entry *b, bool icase)
{
return git_fs_path_cmp(
a->filename, a->filename_len, a->attr == GIT_FILEMODE_TREE,
b->filename, b->filename_len, b->attr == GIT_FILEMODE_TREE,
icase ? git__strncasecmp : git__strncmp);
}
GIT_INLINE(int) tree_iterator_entry_cmp_icase(
const void *ptr_a, const void *ptr_b)
{
const tree_iterator_entry *a = (const tree_iterator_entry *)ptr_a;
const tree_iterator_entry *b = (const tree_iterator_entry *)ptr_b;
return tree_entry_cmp(a->tree_entry, b->tree_entry, true);
}
static int tree_iterator_entry_sort_icase(const void *ptr_a, const void *ptr_b)
{
const tree_iterator_entry *a = (const tree_iterator_entry *)ptr_a;
const tree_iterator_entry *b = (const tree_iterator_entry *)ptr_b;
int c = tree_entry_cmp(a->tree_entry, b->tree_entry, true);
/* stabilize the sort order for filenames that are (case insensitively)
( run in 2.856 seconds using v1.01-cache-2.11-cpan-71847e10f99 )