summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/config_entries.c50
-rw-r--r--src/config_entries.h3
-rw-r--r--src/config_file.c13
3 files changed, 53 insertions, 13 deletions
diff --git a/src/config_entries.c b/src/config_entries.c
index 2e02c31dc..fccce2773 100644
--- a/src/config_entries.c
+++ b/src/config_entries.c
@@ -15,6 +15,7 @@ typedef struct config_entry_list {
typedef struct config_entries_iterator {
git_config_iterator parent;
+ git_config_entries *entries;
config_entry_list *head;
} config_entries_iterator;
@@ -66,6 +67,40 @@ int git_config_entries_new(git_config_entries **out)
return error;
}
+int git_config_entries_dup(git_config_entries **out, git_config_entries *entries)
+{
+ git_config_entries *result = NULL;
+ config_entry_list *head;
+ int error;
+
+ if ((error = git_config_entries_new(&result)) < 0)
+ goto out;
+
+ for (head = entries->list; head; head = head->next) {
+ git_config_entry *dup;
+
+ dup = git__calloc(1, sizeof(git_config_entry));
+ dup->name = git__strdup(head->entry->name);
+ GITERR_CHECK_ALLOC(dup->name);
+ if (head->entry->value) {
+ dup->value = git__strdup(head->entry->value);
+ GITERR_CHECK_ALLOC(dup->value);
+ }
+ dup->level = head->entry->level;
+ dup->include_depth = head->entry->include_depth;
+
+ if ((error = git_config_entries_append(result, dup)) < 0)
+ goto out;
+ }
+
+ *out = result;
+ result = NULL;
+
+out:
+ git_config_entries_free(result);
+ return error;
+}
+
void git_config_entries_incref(git_config_entries *entries)
{
GIT_REFCOUNT_INC(entries);
@@ -184,11 +219,11 @@ int git_config_entries_get_unique(git_config_entry **out, git_config_entries *en
return 0;
}
-void config_iterator_free(
- git_config_iterator* iter)
+void config_iterator_free(git_config_iterator *iter)
{
- iter->backend->free(iter->backend);
- git__free(iter);
+ config_entries_iterator *it = (config_entries_iterator *) iter;
+ git_config_entries_free(it->entries);
+ git__free(it);
}
int config_iterator_next(
@@ -206,17 +241,18 @@ int config_iterator_next(
return 0;
}
-int git_config_entries_iterator_new(git_config_iterator **out, git_config_backend *backend, git_config_entries *entries)
+int git_config_entries_iterator_new(git_config_iterator **out, 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;
+ it->head = entries->list;
+ it->entries = entries;
+ git_config_entries_incref(entries);
*out = &it->parent;
return 0;
diff --git a/src/config_entries.h b/src/config_entries.h
index 02292e27a..6fdbc41ba 100644
--- a/src/config_entries.h
+++ b/src/config_entries.h
@@ -13,10 +13,11 @@
typedef struct git_config_entries git_config_entries;
int git_config_entries_new(git_config_entries **out);
+int git_config_entries_dup(git_config_entries **out, git_config_entries *entries);
void git_config_entries_incref(git_config_entries *entries);
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);
-int git_config_entries_iterator_new(git_config_iterator **out, git_config_backend *backend, git_config_entries *entries);
+int git_config_entries_iterator_new(git_config_iterator **out, git_config_entries *entries);
diff --git a/src/config_file.c b/src/config_file.c
index 7a7f35f06..e8740d35f 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -229,17 +229,20 @@ static int config_iterator_new(
git_config_iterator **iter,
struct git_config_backend* backend)
{
- git_config_backend *snapshot;
diskfile_header *bh = (diskfile_header *) backend;
+ git_config_entries *entries;
int error;
- if ((error = config_snapshot(&snapshot, backend)) < 0)
+ if ((error = git_config_entries_dup(&entries, bh->entries)) < 0)
return error;
- if ((error = snapshot->open(snapshot, bh->level, bh->repo)) < 0)
- return error;
+ if ((error = git_config_entries_iterator_new(iter, entries)) < 0)
+ goto out;
- return git_config_entries_iterator_new(iter, snapshot, bh->entries);
+out:
+ /* Let iterator delete duplicated entries when it's done */
+ git_config_entries_free(entries);
+ return error;
}
static int config_set(git_config_backend *cfg, const char *name, const char *value)