settings: Optionally keep track of removed/replaced values
authorTobias Brunner <tobias@strongswan.org>
Fri, 7 Mar 2014 16:51:36 +0000 (17:51 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 15 May 2014 09:28:06 +0000 (11:28 +0200)
src/libstrongswan/settings/settings_parser.y
src/libstrongswan/settings/settings_types.c
src/libstrongswan/settings/settings_types.h

index 3f0877c..fda3497 100644 (file)
@@ -85,8 +85,8 @@ static void add_setting(parser_helper_t *ctx, kv_t *kv);
 /* properly destroy string tokens that are strdup()ed on error */
 %destructor { free($$); } NAME STRING value valuepart
 /* properly destroy parse results on error */
-%destructor { pop_section(ctx); settings_section_destroy($$); } section_start section
-%destructor { settings_kv_destroy($$); } setting
+%destructor { pop_section(ctx); settings_section_destroy($$, NULL); } section_start section
+%destructor { settings_kv_destroy($$, NULL); } setting
 
 /* there are two shift/reduce conflicts because of the "NAME = NAME" and
  * "NAME {" ambiguity, and the "NAME =" rule) */
@@ -226,8 +226,8 @@ static void add_section(parser_helper_t *ctx, section_t *section)
        }
        else
        {       /* extend the existing section */
-               settings_section_extend(existing, section);
-               settings_section_destroy(section);
+               settings_section_extend(existing, section, NULL);
+               settings_section_destroy(section, NULL);
        }
 }
 
@@ -251,7 +251,7 @@ static void add_setting(parser_helper_t *ctx, kv_t *kv)
                free(existing->value);
                existing->value = kv->value;
                kv->value = NULL;
-               settings_kv_destroy(kv);
+               settings_kv_destroy(kv, NULL);
        }
 }
 
index 015fd3f..4976a3b 100644 (file)
@@ -32,10 +32,17 @@ kv_t *settings_kv_create(char *key, char *value)
 /*
  * Described in header
  */
-void settings_kv_destroy(kv_t *this)
+void settings_kv_destroy(kv_t *this, array_t *contents)
 {
        free(this->key);
-       free(this->value);
+       if (contents)
+       {
+               array_insert(contents, ARRAY_TAIL, this->value);
+       }
+       else
+       {
+               free(this->value);
+       }
        free(this);
 }
 
@@ -52,13 +59,23 @@ section_t *settings_section_create(char *name)
        return this;
 }
 
+static void section_destroy(section_t *section, int idx, array_t *contents)
+{
+       settings_section_destroy(section, contents);
+}
+
+static void kv_destroy(kv_t *kv, int idx, array_t *contents)
+{
+       settings_kv_destroy(kv, contents);
+}
+
 /*
  * Described in header
  */
-void settings_section_destroy(section_t *this)
+void settings_section_destroy(section_t *this, array_t *contents)
 {
-       array_destroy_function(this->sections, (void*)settings_section_destroy, NULL);
-       array_destroy_function(this->kv, (void*)settings_kv_destroy, NULL);
+       array_destroy_function(this->sections, (void*)section_destroy, contents);
+       array_destroy_function(this->kv, (void*)kv_destroy, contents);
        array_destroy(this->fallbacks);
        free(this->name);
        free(this);
@@ -67,7 +84,8 @@ void settings_section_destroy(section_t *this)
 /*
  * Described in header
  */
-void settings_section_extend(section_t *base, section_t *extension)
+void settings_section_extend(section_t *base, section_t *extension,
+                                                        array_t *contents)
 {
        enumerator_t *enumerator;
        section_t *sec;
@@ -80,7 +98,7 @@ void settings_section_extend(section_t *base, section_t *extension)
                if (array_bsearch(base->sections, sec->name, settings_section_find,
                        &found) != -1)
                {
-                       settings_section_extend(found, sec);
+                       settings_section_extend(found, sec, contents);
                }
                else
                {
@@ -97,7 +115,14 @@ void settings_section_extend(section_t *base, section_t *extension)
                kv_t *found;
                if (array_bsearch(base->kv, kv->key, settings_kv_find, &found) != -1)
                {
-                       free(found->value);
+                       if (contents)
+                       {
+                               array_insert(contents, ARRAY_TAIL, found->value);
+                       }
+                       else
+                       {
+                               free(found->value);
+                       }
                        found->value = kv->value;
                        kv->value = NULL;
                }
index 79e8dbf..28e7fd6 100644 (file)
@@ -83,8 +83,9 @@ kv_t *settings_kv_create(char *key, char *value);
  * Destroy a key/value pair.
  *
  * @param this         key/value pair to destroy
+ * @param contents     optional array to store the value in
  */
-void settings_kv_destroy(kv_t *this);
+void settings_kv_destroy(kv_t *this, array_t *contents);
 
 /**
  * Create a section with the given name.
@@ -98,8 +99,9 @@ section_t *settings_section_create(char *name);
  * Destroy a section.
  *
  * @param this         section to destroy
+ * @param contents     optional array to store values of removed key/value pairs
  */
-void settings_section_destroy(section_t *this);
+void settings_section_destroy(section_t *this, array_t *contents);
 
 /**
  * Extend the first section with the values and sub-sections of the second
@@ -108,8 +110,10 @@ void settings_section_destroy(section_t *this);
  *
  * @param base         base section to extend
  * @param extension    section whose data is extracted
+ * @param contents     optional array to store replaced values in
  */
-void settings_section_extend(section_t *base, section_t *extension);
+void settings_section_extend(section_t *base, section_t *extension,
+                                                        array_t *contents);
 
 /**
  * Callback to find a section by name