| /* |
| * 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 |