summaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2013-08-09 09:05:19 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2013-08-12 11:40:57 +0200
commit5880962d90958bc37c08c21d37c9da480ef20e7f (patch)
tree2e710422d0012d078a278ff2fd2a7d410b7fa193 /src/config.c
parenta319ffaead9290bfe35a0f105ff17dacaf7b6e7f (diff)
downloadlibgit2-5880962d90958bc37c08c21d37c9da480ef20e7f.tar.gz
config: introduce _iterator_new()
As the name suggests, it iterates over all the entries
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c123
1 files changed, 94 insertions, 29 deletions
diff --git a/src/config.c b/src/config.c
index 42273cde8..f7ea6f795 100644
--- a/src/config.c
+++ b/src/config.c
@@ -315,6 +315,99 @@ int git_config_refresh(git_config *cfg)
* Loop over all the variables
*/
+typedef struct {
+ git_config_iterator parent;
+ git_config_iterator *current;
+ const git_config *cfg;
+ size_t i;
+} all_iter;
+
+static int find_next_backend(size_t *out, const git_config *cfg, size_t i)
+{
+ file_internal *internal;
+
+ for (; i > 0; --i) {
+ internal = git_vector_get(&cfg->files, i - 1);
+ if (!internal || !internal->file)
+ continue;
+
+ *out = i;
+ return 0;
+ }
+
+ return -1;
+}
+
+static int all_iter_next(git_config_entry **entry, git_config_iterator *_iter)
+{
+ all_iter *iter = (all_iter *) _iter;
+ file_internal *internal;
+ git_config_backend *backend;
+ size_t i;
+ int error = 0;
+
+ if (iter->current != NULL &&
+ (error = iter->current->next(entry, iter->current)) == 0) {
+ return 0;
+ }
+
+ if (error < 0 && error != GIT_ITEROVER)
+ return error;
+
+ do {
+ if (find_next_backend(&i, iter->cfg, iter->i) < 0)
+ return GIT_ITEROVER;
+
+ internal = git_vector_get(&iter->cfg->files, i - 1);
+ backend = internal->file;
+ iter->i = i - 1;
+
+ if (iter->current)
+ iter->current->free(iter->current);
+
+ iter->current = NULL;
+ error = backend->iterator(&iter->current, backend);
+ if (error == GIT_ENOTFOUND)
+ continue;
+
+ if (error < 0)
+ return error;
+
+ return iter->current->next(entry, iter->current);
+
+ } while(1);
+
+ return GIT_ITEROVER;
+}
+
+static void all_iter_free(git_config_iterator *_iter)
+{
+ all_iter *iter = (all_iter *) _iter;
+
+ if (iter->current)
+ iter->current->free(iter->current);
+
+ git__free(iter);
+}
+
+int git_config_iterator_new(git_config_iterator **out, const git_config *cfg)
+{
+ all_iter *iter;
+
+ iter = git__calloc(1, sizeof(all_iter));
+ GITERR_CHECK_ALLOC(iter);
+
+ iter->parent.free = all_iter_free;
+ iter->parent.next = all_iter_next;
+
+ iter->i = cfg->files.length;
+ iter->cfg = cfg;
+
+ *out = (git_config_iterator *) iter;
+
+ return 0;
+}
+
int git_config_foreach(
const git_config *cfg, git_config_foreach_cb cb, void *payload)
{
@@ -613,30 +706,6 @@ typedef struct {
size_t i;
} multivar_iter;
-static int find_next_backend(size_t *out, const git_config *cfg, size_t i)
-{
- file_internal *internal;
-
- for (; i > 0; --i) {
- internal = git_vector_get(&cfg->files, i - 1);
- if (!internal || !internal->file)
- continue;
-
- *out = i;
- return 0;
- }
-
- return -1;
-}
-
-static int multivar_iter_next_empty(git_config_entry **entry, git_config_iterator *_iter)
-{
- GIT_UNUSED(entry);
- GIT_UNUSED(_iter);
-
- return GIT_ITEROVER;
-}
-
static int multivar_iter_next(git_config_entry **entry, git_config_iterator *_iter)
{
multivar_iter *iter = (multivar_iter *) _iter;
@@ -695,7 +764,6 @@ void multivar_iter_free(git_config_iterator *_iter)
int git_config_get_multivar(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp)
{
multivar_iter *iter;
- size_t i;
iter = git__calloc(1, sizeof(multivar_iter));
GITERR_CHECK_ALLOC(iter);
@@ -709,10 +777,7 @@ int git_config_get_multivar(git_config_iterator **out, const git_config *cfg, co
}
iter->parent.free = multivar_iter_free;
- if (find_next_backend(&i, cfg, cfg->files.length) < 0)
- iter->parent.next = multivar_iter_next_empty;
- else
- iter->parent.next = multivar_iter_next;
+ iter->parent.next = multivar_iter_next;
iter->i = cfg->files.length;
iter->cfg = cfg;