Commit 6a15f657 by Patrick Steinhardt

config_file: iterate over keys in the order they were added

Currently, all configuration entries were only held in a string map,
making iteration order mostly based on the hash of each entry's key. Now
that we have extended the `diskfile_entries` structure by a list of
config entries, we can effectively iterate through entries in the order
they were added, though.
parent 3a82475f
...@@ -30,8 +30,7 @@ typedef struct config_entry_list { ...@@ -30,8 +30,7 @@ typedef struct config_entry_list {
typedef struct git_config_file_iter { typedef struct git_config_file_iter {
git_config_iterator parent; git_config_iterator parent;
git_strmap_iter iter; config_entry_list *head;
config_entry_list* next_var;
} git_config_file_iter; } git_config_file_iter;
/* Max depth for [include] directives */ /* Max depth for [include] directives */
...@@ -378,24 +377,12 @@ static int config_iterator_next( ...@@ -378,24 +377,12 @@ static int config_iterator_next(
git_config_iterator *iter) git_config_iterator *iter)
{ {
git_config_file_iter *it = (git_config_file_iter *) iter; git_config_file_iter *it = (git_config_file_iter *) iter;
diskfile_header *h = (diskfile_header *) it->parent.backend;
git_strmap *entry_map = h->entries->map;
int err = 0;
config_entry_list * var;
if (it->next_var == NULL) { if (!it->head)
err = git_strmap_next((void**) &var, &(it->iter), entry_map); return GIT_ITEROVER;
} else {
var = it->next_var;
}
if (err < 0) {
it->next_var = NULL;
return err;
}
*entry = var->entry; *entry = it->head->entry;
it->next_var = var->next; it->head = it->head->next;
return 0; return 0;
} }
...@@ -421,15 +408,11 @@ static int config_iterator_new( ...@@ -421,15 +408,11 @@ static int config_iterator_new(
h = (diskfile_header *)snapshot; h = (diskfile_header *)snapshot;
/* strmap_begin() is currently a macro returning 0 */
GIT_UNUSED(h);
it->parent.backend = snapshot; it->parent.backend = snapshot;
it->iter = git_strmap_begin(h->values); it->head = h->entries->list;
it->next_var = NULL;
it->parent.next = config_iterator_next; it->parent.next = config_iterator_next;
it->parent.free = config_iterator_free; it->parent.free = config_iterator_free;
*iter = (git_config_iterator *) it; *iter = (git_config_iterator *) it;
return 0; return 0;
......
...@@ -306,6 +306,15 @@ void test_config_read__foreach(void) ...@@ -306,6 +306,15 @@ void test_config_read__foreach(void)
void test_config_read__iterator(void) void test_config_read__iterator(void)
{ {
const char *keys[] = {
"core.dummy2",
"core.verylong",
"core.dummy",
"remote.ab.url",
"remote.abba.url",
"core.dummy2",
"core.global"
};
git_config *cfg; git_config *cfg;
git_config_iterator *iter; git_config_iterator *iter;
git_config_entry *entry; git_config_entry *entry;
...@@ -321,6 +330,7 @@ void test_config_read__iterator(void) ...@@ -321,6 +330,7 @@ void test_config_read__iterator(void)
cl_git_pass(git_config_iterator_new(&iter, cfg)); cl_git_pass(git_config_iterator_new(&iter, cfg));
while ((ret = git_config_next(&entry, iter)) == 0) { while ((ret = git_config_next(&entry, iter)) == 0) {
cl_assert_equal_s(entry->name, keys[count]);
count++; count++;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment