]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
settings: Maintain order of sections and settings while enumerating
authorTobias Brunner <tobias@strongswan.org>
Tue, 11 Mar 2014 11:33:43 +0000 (12:33 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 15 May 2014 09:28:08 +0000 (11:28 +0200)
src/libstrongswan/settings/settings.c
src/libstrongswan/settings/settings_types.c
src/libstrongswan/settings/settings_types.h
src/libstrongswan/tests/suites/test_settings.c

index 0acf9bf93293fa5db075387dbe10f31be4cf5e5f..c6ebe894a273bef5aa9768f47ec55ae9a7962b0c 100644 (file)
@@ -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);
 }
 
index 50359108fbc5dffb07289fd7e13e6bbea2e4139e..e22d95165b50e9461797af563ddf4ed3dafb6eee 100644 (file)
@@ -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);
index 5bc322f0a5852c0a2aaf3792ad81bec86937cd48..fdca4a58028b62bcca744d185e071fefbc735298 100644 (file)
@@ -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;
 };
 
 /**
index b66ecd5e9bbc7b2d3706455771972a800be9c8b7..f58c54a6decc582a6f2a852f46210a690971bb99 100644 (file)
@@ -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);