diff options
Diffstat (limited to 'src/iterator.h')
-rw-r--r-- | src/iterator.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/iterator.h b/src/iterator.h new file mode 100644 index 000000000..b916a9080 --- /dev/null +++ b/src/iterator.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_iterator_h__ +#define INCLUDE_iterator_h__ + +#include "common.h" +#include "git2/index.h" + +typedef struct git_iterator git_iterator; + +typedef enum { + GIT_ITERATOR_EMPTY = 0, + GIT_ITERATOR_TREE = 1, + GIT_ITERATOR_INDEX = 2, + GIT_ITERATOR_WORKDIR = 3 +} git_iterator_type_t; + +struct git_iterator { + git_iterator_type_t type; + char *start; + char *end; + int (*current)(git_iterator *, const git_index_entry **); + int (*at_end)(git_iterator *); + int (*advance)(git_iterator *, const git_index_entry **); + int (*seek)(git_iterator *, const char *prefix); + int (*reset)(git_iterator *); + void (*free)(git_iterator *); +}; + +extern int git_iterator_for_nothing(git_iterator **iter); + +extern int git_iterator_for_tree_range( + git_iterator **iter, git_repository *repo, git_tree *tree, + const char *start, const char *end); + +GIT_INLINE(int) git_iterator_for_tree( + git_iterator **iter, git_repository *repo, git_tree *tree) +{ + return git_iterator_for_tree_range(iter, repo, tree, NULL, NULL); +} + +extern int git_iterator_for_index_range( + git_iterator **iter, git_repository *repo, + const char *start, const char *end); + +GIT_INLINE(int) git_iterator_for_index( + git_iterator **iter, git_repository *repo) +{ + return git_iterator_for_index_range(iter, repo, NULL, NULL); +} + +extern int git_iterator_for_workdir_range( + git_iterator **iter, git_repository *repo, + const char *start, const char *end); + +GIT_INLINE(int) git_iterator_for_workdir( + git_iterator **iter, git_repository *repo) +{ + return git_iterator_for_workdir_range(iter, repo, NULL, NULL); +} + + +/* Entry is not guaranteed to be fully populated. For a tree iterator, + * we will only populate the mode, oid and path, for example. For a workdir + * iterator, we will not populate the oid. + * + * You do not need to free the entry. It is still "owned" by the iterator. + * Once you call `git_iterator_advance`, then content of the old entry is + * no longer guaranteed to be valid. + */ +GIT_INLINE(int) git_iterator_current( + git_iterator *iter, const git_index_entry **entry) +{ + return iter->current(iter, entry); +} + +GIT_INLINE(int) git_iterator_at_end(git_iterator *iter) +{ + return iter->at_end(iter); +} + +GIT_INLINE(int) git_iterator_advance( + git_iterator *iter, const git_index_entry **entry) +{ + return iter->advance(iter, entry); +} + +GIT_INLINE(int) git_iterator_seek( + git_iterator *iter, const char *prefix) +{ + return iter->seek(iter, prefix); +} + +GIT_INLINE(int) git_iterator_reset(git_iterator *iter) +{ + return iter->reset(iter); +} + +GIT_INLINE(void) git_iterator_free(git_iterator *iter) +{ + if (iter == NULL) + return; + + iter->free(iter); + + git__free(iter->start); + git__free(iter->end); + + memset(iter, 0, sizeof(*iter)); + + git__free(iter); +} + +GIT_INLINE(git_iterator_type_t) git_iterator_type(git_iterator *iter) +{ + return iter->type; +} + +extern int git_iterator_current_tree_entry( + git_iterator *iter, const git_tree_entry **tree_entry); + +extern int git_iterator_current_is_ignored(git_iterator *iter); + +/** + * Iterate into a workdir directory. + * + * Workdir iterators do not automatically descend into directories (so that + * when comparing two iterator entries you can detect a newly created + * directory in the workdir). As a result, you may get S_ISDIR items from + * a workdir iterator. If you wish to iterate over the contents of the + * directories you encounter, then call this function when you encounter + * a directory. + * + * If there are no files in the directory, this will end up acting like a + * regular advance and will skip past the directory, so you should be + * prepared for that case. + * + * On non-workdir iterators or if not pointing at a directory, this is a + * no-op and will not advance the iterator. + */ +extern int git_iterator_advance_into_directory( + git_iterator *iter, const git_index_entry **entry); + +extern int git_iterator_cmp( + git_iterator *iter, const char *path_prefix); + +#endif |