summaryrefslogtreecommitdiff
path: root/src/iterator.h
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-05-31 12:18:43 -0700
committerRussell Belfer <rb@github.com>2013-05-31 12:18:43 -0700
commitcee695ae6b9a9f586d32d0b9460a358bfdc4fe1b (patch)
tree33fa5cceec1bbb24ab919ccb21732cd1487d4fec /src/iterator.h
parent1ed356dcfef449313bac3ce795f26d19423c744c (diff)
downloadlibgit2-cee695ae6b9a9f586d32d0b9460a358bfdc4fe1b.tar.gz
Make iterators use GIT_ITEROVER & smart advance
1. internal iterators now return GIT_ITEROVER when you go past the last item in the iteration. 2. git_iterator_advance will "advance" to the first item in the iteration if it is called immediately after creating the iterator, which allows a simpler idiom for basic iteration. 3. if git_iterator_advance encounters an error reading data (e.g. a missing tree or an unreadable file), it returns the error but also attempts to advance past the invalid data to prevent an infinite loop. Updated all tests and internal usage of iterators to account for these new behaviors.
Diffstat (limited to 'src/iterator.h')
-rw-r--r--src/iterator.h38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/iterator.h b/src/iterator.h
index 7998f7c6b..493ff4b2a 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -142,9 +142,9 @@ GIT_INLINE(int) git_iterator_advance(
*
* If the current item is not a tree, this is a no-op.
*
- * For working directory iterators only, a tree (i.e. directory) can be
- * empty. In that case, this function returns GIT_ENOTFOUND and does not
- * advance. That can't happen for tree and index iterators.
+ * For filesystem and working directory iterators, a tree (i.e. directory)
+ * can be empty. In that case, this function returns GIT_ENOTFOUND and
+ * does not advance. That can't happen for tree and index iterators.
*/
GIT_INLINE(int) git_iterator_advance_into(
const git_index_entry **entry, git_iterator *iter)
@@ -152,18 +152,50 @@ GIT_INLINE(int) git_iterator_advance_into(
return iter->cb->advance_into(entry, iter);
}
+/**
+ * Advance into a tree or skip over it if it is empty.
+ *
+ * Because `git_iterator_advance_into` may return GIT_ENOTFOUND if the
+ * directory is empty (only with filesystem and working directory
+ * iterators) and a common response is to just call `git_iterator_advance`
+ * when that happens, this bundles the two into a single simple call.
+ */
+GIT_INLINE(int) git_iterator_advance_into_or_over(
+ const git_index_entry **entry, git_iterator *iter)
+{
+ int error = iter->cb->advance_into(entry, iter);
+ if (error == GIT_ENOTFOUND) {
+ giterr_clear();
+ error = iter->cb->advance(entry, iter);
+ }
+ return error;
+}
+
+/* Seek is currently unimplemented */
GIT_INLINE(int) git_iterator_seek(
git_iterator *iter, const char *prefix)
{
return iter->cb->seek(iter, prefix);
}
+/**
+ * Go back to the start of the iteration.
+ *
+ * This resets the iterator to the start of the iteration. It also allows
+ * you to reset the `start` and `end` pathname boundaries of the iteration
+ * when doing so.
+ */
GIT_INLINE(int) git_iterator_reset(
git_iterator *iter, const char *start, const char *end)
{
return iter->cb->reset(iter, start, end);
}
+/**
+ * Check if the iterator is at the end
+ *
+ * @return 0 if not at end, >0 if at end
+ */
GIT_INLINE(int) git_iterator_at_end(git_iterator *iter)
{
return iter->cb->at_end(iter);