iterator.h 3.98 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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 {
16
	GIT_ITERATOR_EMPTY = 0,
17 18 19 20 21 22 23
	GIT_ITERATOR_TREE = 1,
	GIT_ITERATOR_INDEX = 2,
	GIT_ITERATOR_WORKDIR = 3
} git_iterator_type_t;

struct git_iterator {
	git_iterator_type_t type;
24 25
	char *start;
	char *end;
26 27
	int (*current)(git_iterator *, const git_index_entry **);
	int (*at_end)(git_iterator *);
28
	int (*advance)(git_iterator *, const git_index_entry **);
29
	int (*seek)(git_iterator *, const char *prefix);
30
	int (*reset)(git_iterator *);
31 32 33
	void (*free)(git_iterator *);
};

34
extern int git_iterator_for_nothing(git_iterator **iter);
35

36 37 38
extern int git_iterator_for_tree_range(
	git_iterator **iter, git_repository *repo, git_tree *tree,
	const char *start, const char *end);
39

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
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);
}
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85


/* 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);
}

86 87
GIT_INLINE(int) git_iterator_advance(
	git_iterator *iter, const git_index_entry **entry)
88
{
89
	return iter->advance(iter, entry);
90 91
}

92 93 94 95 96 97
GIT_INLINE(int) git_iterator_seek(
	git_iterator *iter, const char *prefix)
{
	return iter->seek(iter, prefix);
}

98 99 100 101 102
GIT_INLINE(int) git_iterator_reset(git_iterator *iter)
{
	return iter->reset(iter);
}

103 104
GIT_INLINE(void) git_iterator_free(git_iterator *iter)
{
105 106 107
	if (iter == NULL)
		return;

108
	iter->free(iter);
109 110 111 112 113 114

	git__free(iter->start);
	git__free(iter->end);

	memset(iter, 0, sizeof(*iter));

115 116 117 118 119 120 121 122 123 124 125 126 127 128
	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);

/**
129 130 131 132 133 134 135 136
 * 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.
137
 *
138 139 140
 * 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.
141
 *
142 143
 * On non-workdir iterators or if not pointing at a directory, this is a
 * no-op and will not advance the iterator.
144
 */
145 146
extern int git_iterator_advance_into_directory(
	git_iterator *iter, const git_index_entry **entry);
147

148 149 150
extern int git_iterator_cmp(
	git_iterator *iter, const char *path_prefix);

151
#endif