aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstrongswan/settings/settings.c16
-rw-r--r--src/libstrongswan/settings/settings_types.c18
-rw-r--r--src/libstrongswan/settings/settings_types.h10
-rw-r--r--src/libstrongswan/tests/suites/test_settings.c81
4 files changed, 59 insertions, 66 deletions
diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c
index 0acf9bf93..c6ebe894a 100644
--- a/src/libstrongswan/settings/settings.c
+++ b/src/libstrongswan/settings/settings.c
@@ -80,18 +80,23 @@ static void kv_destroy(kv_t *kv, int idx, array_t *contents)
static bool section_purge(section_t *this, array_t *contents)
{
section_t *current;
- int i;
+ int i, idx;
array_destroy_function(this->kv, (void*)kv_destroy, contents);
this->kv = NULL;
+ array_destroy(this->kv_order);
+ this->kv_order = NULL;
/* we ensure sections used as fallback, or configured with fallbacks (or
* having any such subsections) are not removed */
- for (i = array_count(this->sections) - 1; i >= 0; i--)
+ for (i = array_count(this->sections_order) - 1; i >= 0; i--)
{
array_get(this->sections, i, &current);
if (section_purge(current, contents))
{
- array_remove(this->sections, i, NULL);
+ array_remove(this->sections_order, i, NULL);
+ idx = array_bsearch(this->sections, current->name,
+ settings_section_find, NULL);
+ array_remove(this->sections, idx, NULL);
settings_section_destroy(current, contents);
}
}
@@ -758,7 +763,8 @@ static bool section_filter(hashtable_t *seen, section_t **in, char **out)
static enumerator_t *section_enumerator(section_t *section,
enumerator_data_t *data)
{
- return enumerator_create_filter(array_create_enumerator(section->sections),
+ return enumerator_create_filter(
+ array_create_enumerator(section->sections_order),
(void*)section_filter, data->seen, NULL);
}
@@ -809,7 +815,7 @@ static bool kv_filter(hashtable_t *seen, kv_t **in, char **key,
*/
static enumerator_t *kv_enumerator(section_t *section, enumerator_data_t *data)
{
- return enumerator_create_filter(array_create_enumerator(section->kv),
+ return enumerator_create_filter(array_create_enumerator(section->kv_order),
(void*)kv_filter, data->seen, NULL);
}
diff --git a/src/libstrongswan/settings/settings_types.c b/src/libstrongswan/settings/settings_types.c
index 50359108f..e22d95165 100644
--- a/src/libstrongswan/settings/settings_types.c
+++ b/src/libstrongswan/settings/settings_types.c
@@ -75,7 +75,9 @@ static void kv_destroy(kv_t *kv, int idx, array_t *contents)
void settings_section_destroy(section_t *this, array_t *contents)
{
array_destroy_function(this->sections, (void*)section_destroy, contents);
+ array_destroy(this->sections_order);
array_destroy_function(this->kv, (void*)kv_destroy, contents);
+ array_destroy(this->kv_order);
array_destroy(this->fallbacks);
free(this->name);
free(this);
@@ -117,6 +119,7 @@ void settings_kv_add(section_t *section, kv_t *kv, array_t *contents)
{
array_insert_create(&section->kv, ARRAY_TAIL, kv);
array_sort(section->kv, settings_kv_sort, NULL);
+ array_insert_create(&section->kv_order, ARRAY_TAIL, kv);
}
else
{
@@ -139,6 +142,7 @@ void settings_section_add(section_t *parent, section_t *section,
{
array_insert_create(&parent->sections, ARRAY_TAIL, section);
array_sort(parent->sections, settings_section_sort, NULL);
+ array_insert_create(&parent->sections_order, ARRAY_TAIL, section);
}
else
{
@@ -156,19 +160,25 @@ void settings_section_extend(section_t *base, section_t *extension,
enumerator_t *enumerator;
section_t *section;
kv_t *kv;
+ int idx;
- enumerator = array_create_enumerator(extension->sections);
+ enumerator = array_create_enumerator(extension->sections_order);
while (enumerator->enumerate(enumerator, (void**)&section))
{
- array_remove_at(extension->sections, enumerator);
+ idx = array_bsearch(extension->sections, section->name,
+ settings_section_find, NULL);
+ array_remove(extension->sections, idx, NULL);
+ array_remove_at(extension->sections_order, enumerator);
settings_section_add(base, section, contents);
}
enumerator->destroy(enumerator);
- enumerator = array_create_enumerator(extension->kv);
+ enumerator = array_create_enumerator(extension->kv_order);
while (enumerator->enumerate(enumerator, (void**)&kv))
{
- array_remove_at(extension->kv, enumerator);
+ idx = array_bsearch(extension->kv, kv->key, settings_kv_find, NULL);
+ array_remove(extension->kv, idx, NULL);
+ array_remove_at(extension->kv_order, enumerator);
settings_kv_add(base, kv, contents);
}
enumerator->destroy(enumerator);
diff --git a/src/libstrongswan/settings/settings_types.h b/src/libstrongswan/settings/settings_types.h
index 5bc322f0a..fdca4a580 100644
--- a/src/libstrongswan/settings/settings_types.h
+++ b/src/libstrongswan/settings/settings_types.h
@@ -65,9 +65,19 @@ struct section_t {
array_t *sections;
/**
+ * Subsections in original order, as section_t (pointer to obj in sections).
+ */
+ array_t *sections_order;
+
+ /**
* Key value pairs, as kv_t.
*/
array_t *kv;
+
+ /**
+ * Key value pairs in original order, as kv_t (pointer to obj in kv).
+ */
+ array_t *kv_order;
};
/**
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index b66ecd5e9..f58c54a6d 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -420,37 +420,21 @@ START_TEST(test_set_time)
}
END_TEST
-static bool verify_section(linked_list_t *verifier, char *section)
-{
- enumerator_t *enumerator;
- char *current;
- bool result = FALSE;
-
- enumerator = verifier->create_enumerator(verifier);
- while (enumerator->enumerate(enumerator, &current))
- {
- if (streq(current, section))
- {
- verifier->remove_at(verifier, enumerator);
- result = TRUE;
- break;
- }
- }
- enumerator->destroy(enumerator);
- return result;
-}
-
static void verify_sections(linked_list_t *verifier, char *parent)
{
- enumerator_t *enumerator;
- char *section;
+ enumerator_t *enumerator, *ver;
+ char *section, *current;
enumerator = settings->create_section_enumerator(settings, parent);
- while (enumerator->enumerate(enumerator, &section))
+ ver = verifier->create_enumerator(verifier);
+ while (enumerator->enumerate(enumerator, &section) &&
+ ver->enumerate(ver, &current))
{
- ck_assert(verify_section(verifier, section));
+ ck_assert_str_eq(section, current);
+ verifier->remove_at(verifier, ver);
}
enumerator->destroy(enumerator);
+ ver->destroy(ver);
ck_assert_int_eq(0, verifier->get_count(verifier));
verifier->destroy(verifier);
}
@@ -462,8 +446,8 @@ START_TEST(test_section_enumerator)
verifier = linked_list_create_with_items("sub1", "sub%", NULL);
verify_sections(verifier, "main");
- settings->set_str(settings, "main.sub2.new", "added");
- verifier = linked_list_create_with_items("sub1", "sub%", "sub2", NULL);
+ settings->set_str(settings, "main.sub0.new", "added");
+ verifier = linked_list_create_with_items("sub1", "sub%", "sub0", NULL);
verify_sections(verifier, "main");
verifier = linked_list_create_with_items("subsub", NULL);
@@ -480,44 +464,27 @@ START_TEST(test_section_enumerator)
}
END_TEST
-static bool verify_key_value(linked_list_t *keys, linked_list_t *values,
- char *key, char *value)
+static void verify_key_values(linked_list_t *keys, linked_list_t *values,
+ char *parent)
{
- enumerator_t *enum_keys, *enum_values;
- char *current_key, *current_value;
- bool result = FALSE;
+ enumerator_t *enumerator, *enum_keys, *enum_values;
+ char *key, *value, *current_key, *current_value;
+ enumerator = settings->create_key_value_enumerator(settings, parent);
enum_keys = keys->create_enumerator(keys);
enum_values = values->create_enumerator(values);
- while (enum_keys->enumerate(enum_keys, &current_key) &&
+ while (enumerator->enumerate(enumerator, &key, &value) &&
+ enum_keys->enumerate(enum_keys, &current_key) &&
enum_values->enumerate(enum_values, &current_value))
{
- if (streq(current_key, key))
- {
- ck_assert_str_eq(current_value, value);
- keys->remove_at(keys, enum_keys);
- values->remove_at(values, enum_values);
- result = TRUE;
- break;
- }
+ ck_assert_str_eq(current_key, key);
+ ck_assert_str_eq(current_value, value);
+ keys->remove_at(keys, enum_keys);
+ values->remove_at(values, enum_values);
}
+ enumerator->destroy(enumerator);
enum_keys->destroy(enum_keys);
enum_values->destroy(enum_values);
- return result;
-}
-
-static void verify_key_values(linked_list_t *keys, linked_list_t *values,
- char *parent)
-{
- enumerator_t *enumerator;
- char *key, *value;
-
- enumerator = settings->create_key_value_enumerator(settings, parent);
- while (enumerator->enumerate(enumerator, &key, &value))
- {
- ck_assert(verify_key_value(keys, values, key, value));
- }
- enumerator->destroy(enumerator);
ck_assert_int_eq(0, keys->get_count(keys));
keys->destroy(keys);
values->destroy(values);
@@ -527,8 +494,8 @@ START_TEST(test_key_value_enumerator)
{
linked_list_t *keys, *values;
- keys = linked_list_create_with_items("key1", "key2", "key3", "empty", NULL);
- values = linked_list_create_with_items("val1", "with space", "string with\nnewline", "", NULL);
+ keys = linked_list_create_with_items("key1", "key2", "empty", "key3", NULL);
+ values = linked_list_create_with_items("val1", "with space", "", "string with\nnewline", NULL);
verify_key_values(keys, values, "main");
keys = linked_list_create_with_items("key", "key2", "subsub", NULL);