From: Tobias Brunner Date: Tue, 11 Mar 2014 11:33:43 +0000 (+0100) Subject: settings: Maintain order of sections and settings while enumerating X-Git-Tag: 5.2.0dr4~1^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5dd274ab8aab6255b34f1f580a79a99dbdb2fa1;p=thirdparty%2Fstrongswan.git settings: Maintain order of sections and settings while enumerating --- diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c index 0acf9bf932..c6ebe894a2 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, ¤t); 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 50359108fb..e22d95165b 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(§ion->kv, ARRAY_TAIL, kv); array_sort(section->kv, settings_kv_sort, NULL); + array_insert_create(§ion->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**)§ion)) { - 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 5bc322f0a5..fdca4a5802 100644 --- a/src/libstrongswan/settings/settings_types.h +++ b/src/libstrongswan/settings/settings_types.h @@ -64,10 +64,20 @@ 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 b66ecd5e9b..f58c54a6de 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, ¤t)) - { - 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, §ion)) + ver = verifier->create_enumerator(verifier); + while (enumerator->enumerate(enumerator, §ion) && + ver->enumerate(ver, ¤t)) { - 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, ¤t_key) && + while (enumerator->enumerate(enumerator, &key, &value) && + enum_keys->enumerate(enum_keys, ¤t_key) && enum_values->enumerate(enum_values, ¤t_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);