summaryrefslogtreecommitdiff
path: root/src/iterator.h
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@github.com>2016-03-10 00:04:26 -0500
committerEdward Thomson <ethomson@github.com>2016-03-23 17:16:37 -0400
commit0e0589fcc383a0ca96d342896103e01d715df755 (patch)
tree90e0518ec567eade47a5ed4e6c07e9edb94162f6 /src/iterator.h
parentd051de243c28be01525d1bb2f2e716fd000892d8 (diff)
downloadlibgit2-0e0589fcc383a0ca96d342896103e01d715df755.tar.gz
iterator: combine fs+workdir iterators more completely
Drop some of the layers of indirection between the workdir and the filesystem iterators. This makes the code a little bit easier to follow, and reduces the number of unnecessary allocations a bit as well. (Prior to this, when we filter entries, we would allocate them, filter them and then free them; now we do the filtering before allocation.) Also, rename `git_iterator_advance_over_with_status` to just `git_iterator_advance_over`. Mostly because it's a fucking long-ass function name otherwise.
Diffstat (limited to 'src/iterator.h')
-rw-r--r--src/iterator.h68
1 files changed, 42 insertions, 26 deletions
diff --git a/src/iterator.h b/src/iterator.h
index 8cd774b9d..d64d63f8d 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -34,10 +34,19 @@ typedef enum {
GIT_ITERATOR_DONT_AUTOEXPAND = (1u << 3),
/** convert precomposed unicode to decomposed unicode */
GIT_ITERATOR_PRECOMPOSE_UNICODE = (1u << 4),
+ /** never convert precomposed unicode to decomposed unicode */
+ GIT_ITERATOR_DONT_PRECOMPOSE_UNICODE = (1u << 5),
/** include conflicts */
- GIT_ITERATOR_INCLUDE_CONFLICTS = (1u << 5),
+ GIT_ITERATOR_INCLUDE_CONFLICTS = (1u << 6),
} git_iterator_flag_t;
+typedef enum {
+ GIT_ITERATOR_STATUS_NORMAL = 0,
+ GIT_ITERATOR_STATUS_IGNORED = 1,
+ GIT_ITERATOR_STATUS_EMPTY = 2,
+ GIT_ITERATOR_STATUS_FILTERED = 3
+} git_iterator_status_t;
+
typedef struct {
const char *start;
const char *end;
@@ -57,6 +66,8 @@ typedef struct {
int (*current)(const git_index_entry **, git_iterator *);
int (*advance)(const git_index_entry **, git_iterator *);
int (*advance_into)(const git_index_entry **, git_iterator *);
+ int (*advance_over)(
+ const git_index_entry **, git_iterator_status_t *, git_iterator *);
int (*reset)(git_iterator *);
int (*reset_range)(git_iterator *, const char *start, const char *end);
int (*at_end)(git_iterator *);
@@ -67,8 +78,13 @@ struct git_iterator {
git_iterator_type_t type;
git_iterator_callbacks *cb;
git_repository *repo;
+
char *start;
+ size_t start_len;
+
char *end;
+ size_t end_len;
+
bool started;
bool ended;
git_vector pathlist;
@@ -76,6 +92,7 @@ struct git_iterator {
int (*strcomp)(const char *a, const char *b);
int (*strncomp)(const char *a, const char *b, size_t n);
int (*prefixcomp)(const char *str, const char *prefix);
+ int (*entry_srch)(const void *key, const void *array_member);
size_t stat_calls;
unsigned int flags;
};
@@ -183,6 +200,28 @@ GIT_INLINE(int) git_iterator_advance_into(
return iter->cb->advance_into(entry, iter);
}
+/* Advance over a directory and check if it contains no files or just
+ * ignored files.
+ *
+ * In a tree or the index, all directories will contain files, but in the
+ * working directory it is possible to have an empty directory tree or a
+ * tree that only contains ignored files. Many Git operations treat these
+ * cases specially. This advances over a directory (presumably an
+ * untracked directory) but checks during the scan if there are any files
+ * and any non-ignored files.
+ */
+GIT_INLINE(int) git_iterator_advance_over(
+ const git_index_entry **entry,
+ git_iterator_status_t *status,
+ git_iterator *iter)
+{
+ if (iter->cb->advance_over)
+ return iter->cb->advance_over(entry, status, iter);
+
+ *status = GIT_ITERATOR_STATUS_NORMAL;
+ return git_iterator_advance(entry, iter);
+}
+
/**
* Advance into a tree or skip over it if it is empty.
*
@@ -273,35 +312,12 @@ extern int git_iterator_cmp(
extern int git_iterator_current_workdir_path(
git_buf **path, git_iterator *iter);
-/* Return index pointer if index iterator, else NULL */
-extern git_index *git_iterator_get_index(git_iterator *iter);
-
-typedef enum {
- GIT_ITERATOR_STATUS_NORMAL = 0,
- GIT_ITERATOR_STATUS_IGNORED = 1,
- GIT_ITERATOR_STATUS_EMPTY = 2,
- GIT_ITERATOR_STATUS_FILTERED = 3
-} git_iterator_status_t;
-
-/* Advance over a directory and check if it contains no files or just
- * ignored files.
- *
- * In a tree or the index, all directories will contain files, but in the
- * working directory it is possible to have an empty directory tree or a
- * tree that only contains ignored files. Many Git operations treat these
- * cases specially. This advances over a directory (presumably an
- * untracked directory) but checks during the scan if there are any files
- * and any non-ignored files.
- */
-extern int git_iterator_advance_over_with_status(
- const git_index_entry **entry, git_iterator_status_t *status, git_iterator *iter);
-
/**
* Retrieve the index stored in the iterator.
*
- * Only implemented for the workdir iterator
+ * Only implemented for the workdir and index iterators.
*/
-extern int git_iterator_index(git_index **out, git_iterator *iter);
+extern git_index *git_iterator_index(git_iterator *iter);
typedef int (*git_iterator_walk_cb)(
const git_index_entry **entries,