Commit eba7399251cfa95d9346b9b41ca78dc5d43a840d

Carlos Martín Nieto 2013-08-08T14:39:32

config: move next() and free() into the iterator Like we have in the references iterator, next and free belong in the iterator itself.

diff --git a/include/git2/config.h b/include/git2/config.h
index a0dc11b..9503125 100644
--- a/include/git2/config.h
+++ b/include/git2/config.h
@@ -61,7 +61,7 @@ typedef struct {
 } git_config_entry;
 
 typedef int  (*git_config_foreach_cb)(const git_config_entry *, void *);
-typedef struct git_config_backend_iter git_config_backend_iter;
+typedef struct git_config_iterator git_config_iterator;
 
 typedef enum {
 	GIT_CVAR_FALSE = 0,
diff --git a/include/git2/sys/config.h b/include/git2/sys/config.h
index 09c7963..45599dc 100644
--- a/include/git2/sys/config.h
+++ b/include/git2/sys/config.h
@@ -21,6 +21,32 @@
 GIT_BEGIN_DECL
 
 /**
+ * Every iterator must have this struct as its first element, so the
+ * API can talk to it. You'd define your iterator as
+ *
+ *     struct my_iterator {
+ *             git_config_iterator parent;
+ *             ...
+ *     }
+ *
+ * and assign `iter->parent.backend` to your `git_config_backend`.
+ */
+struct git_config_iterator {
+	git_config_backend *backend;
+	unsigned int flags;
+
+	/**
+	 * Return the current entry and advance the iterator
+	 */
+	int (*next)(git_config_entry *entry, git_config_iterator *iter);
+
+	/**
+	 * Free the iterator
+	 */
+	void (*free)(git_config_iterator *iter);
+};
+
+/**
  * Generic backend that implements the interface to
  * access a configuration file
  */
@@ -35,9 +61,7 @@ struct git_config_backend {
 	int (*set)(struct git_config_backend *, const char *key, const char *value);
 	int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value);
 	int (*del)(struct git_config_backend *, const char *key);
-	int (*iterator_new)(git_config_backend_iter **, struct git_config_backend *);
-	void (*iterator_free)(git_config_backend_iter *);
-	int (*next)(git_config_entry *, git_config_backend_iter *);
+	int (*iterator)(git_config_iterator **, struct git_config_backend *);
 	int (*refresh)(struct git_config_backend *);
 	void (*free)(struct git_config_backend *);
 };
diff --git a/src/config.c b/src/config.c
index a4627c9..5bec0f0 100644
--- a/src/config.c
+++ b/src/config.c
@@ -328,7 +328,7 @@ int git_config_backend_foreach_match(
 	void *data)
 {
 	git_config_entry entry;
-	git_config_backend_iter* iter;
+	git_config_iterator* iter;
 	regex_t regex;
 	int result = 0;
 
@@ -340,12 +340,12 @@ int git_config_backend_foreach_match(
 		}
 	}
 
-	if ((result = backend->iterator_new(&iter, backend)) < 0) {
+	if ((result = backend->iterator(&iter, backend)) < 0) {
 		iter = NULL;
 		return -1;
 	}
 
-	while(!(backend->next(&entry, iter) < 0)) {
+	while(!(iter->next(&entry, iter) < 0)) {
 		/* skip non-matching keys if regexp was provided */
 		if (regexp && regexec(&regex, entry.name, 0, NULL, 0) != 0)
 			continue;
@@ -362,7 +362,7 @@ cleanup:
 	if (regexp != NULL)
 		regfree(&regex);
 
-	backend->iterator_free(iter);
+	iter->free(iter);
 
 	return result;
 }
diff --git a/src/config.h b/src/config.h
index 2f7c96d..c5c11ae 100644
--- a/src/config.h
+++ b/src/config.h
@@ -24,11 +24,6 @@ struct git_config {
 	git_vector files;
 };
 
-struct git_config_backend_iter {
-	git_config_backend *backend;
-	unsigned int flags;
-};
-
 extern int git_config_find_global_r(git_buf *global_config_path);
 extern int git_config_find_xdg_r(git_buf *system_config_path);
 extern int git_config_find_system_r(git_buf *system_config_path);
diff --git a/src/config_file.c b/src/config_file.c
index ed79624..3e0c6cc 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -28,9 +28,9 @@ typedef struct cvar_t {
 } cvar_t;
 
 typedef struct git_config_file_iter {
-	git_config_backend_iter parent;
+	git_config_iterator parent;
 	git_strmap_iter iter;
-	cvar_t* next;
+	cvar_t* next_var;
 } git_config_file_iter;
 
 
@@ -254,32 +254,15 @@ static void backend_free(git_config_backend *_backend)
 	git__free(backend);
 }
 
-static int config_iterator_new(
-	git_config_backend_iter **iter,
-	struct git_config_backend* backend)
-{
-	diskfile_backend *b = (diskfile_backend *)backend;
-	git_config_file_iter *it = git__calloc(1, sizeof(git_config_file_iter));
-
-	GITERR_CHECK_ALLOC(it);
-
-	it->parent.backend = backend;
-	it->iter = git_strmap_begin(b->values);
-	it->next = NULL;
-	*iter = (git_config_backend_iter *) it;
-
-	return 0;
-}
-
 static void config_iterator_free(
-	git_config_backend_iter* iter)
+	git_config_iterator* iter)
 {
 	git__free(iter);
 }
 
 static int config_iterator_next(
 	git_config_entry *entry,
-	git_config_backend_iter *iter)
+	git_config_iterator *iter)
 {
 	git_config_file_iter *it = (git_config_file_iter *) iter;
 	diskfile_backend *b = (diskfile_backend *) it->parent.backend;
@@ -287,22 +270,42 @@ static int config_iterator_next(
 	cvar_t * var;
 	const char* key;
 
-	if (it->next == NULL) {
+	if (it->next_var == NULL) {
 		err = git_strmap_next(&key, (void**) &var, &(it->iter), b->values);
 	} else {
-		key = it->next->entry->name;
-		var = it->next;
+		key = it->next_var->entry->name;
+		var = it->next_var;
 	}
 
 	if (err < 0) {
-		it->next = NULL;
+		it->next_var = NULL;
 		return -1;
 	}
 
 	entry->name = key;
 	entry->value = var->entry->value;
 	entry->level = var->entry->level;
-	it->next = CVAR_LIST_NEXT(var);
+	it->next_var = CVAR_LIST_NEXT(var);
+
+	return 0;
+}
+
+static int config_iterator_new(
+	git_config_iterator **iter,
+	struct git_config_backend* backend)
+{
+	diskfile_backend *b = (diskfile_backend *)backend;
+	git_config_file_iter *it = git__calloc(1, sizeof(git_config_file_iter));
+
+	GITERR_CHECK_ALLOC(it);
+
+	it->parent.backend = backend;
+	it->iter = git_strmap_begin(b->values);
+	it->next_var = NULL;
+
+	it->parent.next = config_iterator_next;
+	it->parent.free = config_iterator_free;
+	*iter = (git_config_iterator *) it;
 
 	return 0;
 }
@@ -607,9 +610,7 @@ int git_config_file__ondisk(git_config_backend **out, const char *path)
 	backend->parent.set = config_set;
 	backend->parent.set_multivar = config_set_multivar;
 	backend->parent.del = config_delete;
-	backend->parent.iterator_new = config_iterator_new;
-	backend->parent.iterator_free = config_iterator_free;
-	backend->parent.next = config_iterator_next;
+	backend->parent.iterator = config_iterator_new;
 	backend->parent.refresh = config_refresh;
 	backend->parent.free = backend_free;