Commit 5a7e0b3c380652e666f0bf0d0c5ff6cd3c846419

Patrick Steinhardt 2018-08-10T18:49:38

config_entries: abstract away iteration over entries The nice thing about our `git_config_iterator` interfaces is that nobody needs to know anything about the implementation details. All that is required is to obtain the iterator via any backend and then use it by executing generic functions. We can thus completely internalize all the implementation details of how to iterate over entries into the config entries store and simply create such an iterator in our config file backend when we want to iterate its entries. This further decouples the config file backend from the config entries store.

diff --git a/src/config_entries.c b/src/config_entries.c
index a852045..ef05d7f 100644
--- a/src/config_entries.c
+++ b/src/config_entries.c
@@ -7,6 +7,11 @@
 
 #include "config_entries.h"
 
+typedef struct config_entries_iterator {
+	git_config_iterator parent;
+	config_entry_list *head;
+} config_entries_iterator;
+
 static void config_entry_list_free(config_entry_list *list)
 {
 	config_entry_list *next;
@@ -174,7 +179,7 @@ int config_iterator_next(
 	git_config_entry **entry,
 	git_config_iterator *iter)
 {
-	git_config_file_iter *it = (git_config_file_iter *) iter;
+	config_entries_iterator *it = (config_entries_iterator *) iter;
 
 	if (!it->head)
 		return GIT_ITEROVER;
@@ -184,3 +189,19 @@ int config_iterator_next(
 
 	return 0;
 }
+
+int git_config_entries_iterator_new(git_config_iterator **out, git_config_backend *backend, git_config_entries *entries)
+{
+	config_entries_iterator *it;
+
+	it = git__calloc(1, sizeof(config_entries_iterator));
+	GITERR_CHECK_ALLOC(it);
+	it->parent.backend = backend;
+	it->head = entries->list;
+	it->parent.next = config_iterator_next;
+	it->parent.free = config_iterator_free;
+
+	*out = &it->parent;
+
+	return 0;
+}
diff --git a/src/config_entries.h b/src/config_entries.h
index 555f9be..674b7a8 100644
--- a/src/config_entries.h
+++ b/src/config_entries.h
@@ -22,18 +22,10 @@ typedef struct {
 	config_entry_list *list;
 } git_config_entries;
 
-typedef struct git_config_file_iter {
-	git_config_iterator parent;
-	config_entry_list *head;
-} git_config_file_iter;
-
 int git_config_entries_new(git_config_entries **out);
 void git_config_entries_free(git_config_entries *entries);
 /* Add or append the new config option */
 int git_config_entries_append(git_config_entries *entries, git_config_entry *entry);
 int git_config_entries_get(git_config_entry **out, git_config_entries *entries, const char *key);
 int git_config_entries_get_unique(git_config_entry **out, git_config_entries *entries, const char *key);
-
-void config_iterator_free(git_config_iterator* iter);
-int config_iterator_next(git_config_entry **entry,
-	git_config_iterator *iter);
+int git_config_entries_iterator_new(git_config_iterator **out, git_config_backend *backend, git_config_entries *entries);
diff --git a/src/config_file.c b/src/config_file.c
index 71de2b6..8c05fd9 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -229,8 +229,6 @@ static int config_iterator_new(
 	git_config_iterator **iter,
 	struct git_config_backend* backend)
 {
-	diskfile_header *h;
-	git_config_file_iter *it;
 	git_config_backend *snapshot;
 	diskfile_header *bh = (diskfile_header *) backend;
 	int error;
@@ -241,19 +239,7 @@ static int config_iterator_new(
 	if ((error = snapshot->open(snapshot, bh->level, bh->repo)) < 0)
 		return error;
 
-	it = git__calloc(1, sizeof(git_config_file_iter));
-	GITERR_CHECK_ALLOC(it);
-
-	h = (diskfile_header *)snapshot;
-
-	it->parent.backend = snapshot;
-	it->head = h->entries->list;
-	it->parent.next = config_iterator_next;
-	it->parent.free = config_iterator_free;
-
-	*iter = (git_config_iterator *) it;
-
-	return 0;
+	return git_config_entries_iterator_new(iter, snapshot, bh->entries);
 }
 
 static int config_set(git_config_backend *cfg, const char *name, const char *value)