summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2015-08-30 18:35:57 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2015-08-30 18:55:18 -0400
commit1af84271dd221343bc199207f3eb923781124928 (patch)
tree43c3ac782b508b4e0d4a21e3aa143459e73c65bf
parent4a0dbeb0d35343ded24b51906f2a8f8ef6c7910b (diff)
downloadlibgit2-1af84271dd221343bc199207f3eb923781124928.tar.gz
tree_iterator: use a pathlist
-rw-r--r--src/iterator.c35
-rw-r--r--tests/repo/iterator.c114
2 files changed, 148 insertions, 1 deletions
diff --git a/src/iterator.c b/src/iterator.c
index bad24d13e..9bf56b650 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -560,7 +560,7 @@ static int tree_iterator__update_entry(tree_iterator *ti)
return 0;
}
-static int tree_iterator__current(
+static int tree_iterator__current_internal(
const git_index_entry **entry, git_iterator *self)
{
int error;
@@ -583,6 +583,39 @@ static int tree_iterator__current(
return 0;
}
+int tree_iterator__advance(
+ const git_index_entry **out, git_iterator *self);
+
+static int tree_iterator__current(
+ const git_index_entry **out, git_iterator *self)
+{
+ git_index_entry *entry = NULL;
+ iterator_pathlist__match_t m;
+ int error;
+
+ do {
+ if ((error = tree_iterator__current_internal(&entry, self)) < 0)
+ return error;
+
+ if (self->pathlist.length) {
+ m = iterator_pathlist__match(
+ self, entry->path, strlen(entry->path));
+
+ if (m != ITERATOR_PATHLIST_MATCH) {
+ if ((error = tree_iterator__advance(&entry, self)) < 0)
+ return error;
+
+ entry = NULL;
+ }
+ }
+ } while (!entry);
+
+ if (out)
+ *out = entry;
+
+ return error;
+}
+
static int tree_iterator__advance_into(
const git_index_entry **entry, git_iterator *self)
{
diff --git a/tests/repo/iterator.c b/tests/repo/iterator.c
index 5420aad40..cb9d4cd4b 100644
--- a/tests/repo/iterator.c
+++ b/tests/repo/iterator.c
@@ -1332,3 +1332,117 @@ void test_repo_iterator__workdirfilelist_icase(void)
git_vector_free(&filelist);
}
+
+void test_repo_iterator__treefilelist(void)
+{
+ git_iterator *i;
+ git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
+ git_vector filelist;
+ git_tree *tree;
+ bool default_icase;
+ int expect;
+
+ cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
+ cl_git_pass(git_vector_insert(&filelist, "a"));
+ cl_git_pass(git_vector_insert(&filelist, "B"));
+ cl_git_pass(git_vector_insert(&filelist, "c"));
+ cl_git_pass(git_vector_insert(&filelist, "D"));
+ cl_git_pass(git_vector_insert(&filelist, "e"));
+ cl_git_pass(git_vector_insert(&filelist, "k.a"));
+ cl_git_pass(git_vector_insert(&filelist, "k.b"));
+ cl_git_pass(git_vector_insert(&filelist, "k/1"));
+ cl_git_pass(git_vector_insert(&filelist, "k/a"));
+ cl_git_pass(git_vector_insert(&filelist, "kZZZZZZZ"));
+ cl_git_pass(git_vector_insert(&filelist, "L/1"));
+
+ g_repo = cl_git_sandbox_init("icase");
+ git_repository_head_tree(&tree, g_repo);
+
+ /* All indexfilelist iterator tests are "autoexpand with no tree entries" */
+ /* In this test we DO NOT force a case on the iteratords and verify default behavior. */
+
+ i_opts.pathlist.strings = (char **)filelist.contents;
+ i_opts.pathlist.count = filelist.length;
+
+ cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
+ expect_iterator_items(i, 8, NULL, 8, NULL);
+ git_iterator_free(i);
+
+ i_opts.start = "c";
+ i_opts.end = NULL;
+ cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
+ default_icase = git_iterator_ignore_case(i);
+ /* (c D e k/1 k/a L ==> 6) vs (c e k/1 k/a ==> 4) */
+ expect = ((default_icase) ? 6 : 4);
+ expect_iterator_items(i, expect, NULL, expect, NULL);
+ git_iterator_free(i);
+
+ i_opts.start = NULL;
+ i_opts.end = "e";
+ cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
+ default_icase = git_iterator_ignore_case(i);
+ /* (a B c D e ==> 5) vs (B D L/1 a c e ==> 6) */
+ expect = ((default_icase) ? 5 : 6);
+ expect_iterator_items(i, expect, NULL, expect, NULL);
+ git_iterator_free(i);
+
+ git_vector_free(&filelist);
+ git_tree_free(tree);
+}
+
+void test_repo_iterator__treefilelist_icase(void)
+{
+ git_iterator *i;
+ git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
+ git_vector filelist;
+ git_tree *tree;
+
+ cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
+ cl_git_pass(git_vector_insert(&filelist, "a"));
+ cl_git_pass(git_vector_insert(&filelist, "B"));
+ cl_git_pass(git_vector_insert(&filelist, "c"));
+ cl_git_pass(git_vector_insert(&filelist, "D"));
+ cl_git_pass(git_vector_insert(&filelist, "e"));
+ cl_git_pass(git_vector_insert(&filelist, "k.a"));
+ cl_git_pass(git_vector_insert(&filelist, "k.b"));
+ cl_git_pass(git_vector_insert(&filelist, "k/1"));
+ cl_git_pass(git_vector_insert(&filelist, "k/a"));
+ cl_git_pass(git_vector_insert(&filelist, "kZZZZ"));
+ cl_git_pass(git_vector_insert(&filelist, "L/1"));
+
+ g_repo = cl_git_sandbox_init("icase");
+ git_repository_head_tree(&tree, g_repo);
+
+ i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
+ i_opts.pathlist.strings = (char **)filelist.contents;
+ i_opts.pathlist.count = filelist.length;
+
+ i_opts.start = "c";
+ i_opts.end = "k/D";
+ cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
+ expect_iterator_items(i, 3, NULL, 3, NULL);
+ git_iterator_free(i);
+
+ i_opts.start = "k";
+ i_opts.end = "k/Z";
+ cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
+ expect_iterator_items(i, 1, NULL, 1, NULL);
+ git_iterator_free(i);
+
+ i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
+
+ i_opts.start = "c";
+ i_opts.end = "k/D";
+ cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
+ expect_iterator_items(i, 5, NULL, 5, NULL);
+ git_iterator_free(i);
+
+ i_opts.start = "k";
+ i_opts.end = "k/Z";
+ cl_git_pass(git_iterator_for_tree(&i, tree, &i_opts));
+ expect_iterator_items(i, 2, NULL, 2, NULL);
+ git_iterator_free(i);
+
+ git_vector_free(&filelist);
+ git_tree_free(tree);
+}