settings: Add methods and a constructor to parse settings from strings
authorTobias Brunner <tobias@strongswan.org>
Thu, 23 Oct 2014 14:57:47 +0000 (16:57 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 28 Jul 2015 11:27:32 +0000 (13:27 +0200)
src/libstrongswan/settings/settings.c
src/libstrongswan/settings/settings.h

index acf9160..305ebe6 100644 (file)
 typedef struct private_settings_t private_settings_t;
 
 /**
 typedef struct private_settings_t private_settings_t;
 
 /**
- * Parse function provided by the generated parser.
+ * Parse functions provided by the generated parser.
  */
 bool settings_parser_parse_file(section_t *root, char *name);
  */
 bool settings_parser_parse_file(section_t *root, char *name);
+bool settings_parser_parse_string(section_t *root, char *settings);
 
 /**
  * Private data of settings
 
 /**
  * Private data of settings
@@ -843,16 +844,17 @@ METHOD(settings_t, add_fallback, void,
 }
 
 /**
 }
 
 /**
- * Load settings from files matching the given file pattern.
+ * Load settings from files matching the given file pattern or from a string.
  * All sections and values are added relative to "parent".
  * All files (even included ones) have to be loaded successfully.
  * If merge is FALSE the contents of parent are replaced with the parsed
  * contents, otherwise they are merged together.
  */
  * All sections and values are added relative to "parent".
  * All files (even included ones) have to be loaded successfully.
  * If merge is FALSE the contents of parent are replaced with the parsed
  * contents, otherwise they are merged together.
  */
-static bool load_files_internal(private_settings_t *this, section_t *parent,
-                                                               char *pattern, bool merge)
+static bool load_internal(private_settings_t *this, section_t *parent,
+                                                 char *pattern, bool merge, bool string)
 {
        section_t *section;
 {
        section_t *section;
+       bool loaded;
 
        if (pattern == NULL || !pattern[0])
        {       /* TODO: Clear parent if merge is FALSE? */
 
        if (pattern == NULL || !pattern[0])
        {       /* TODO: Clear parent if merge is FALSE? */
@@ -860,7 +862,9 @@ static bool load_files_internal(private_settings_t *this, section_t *parent,
        }
 
        section = settings_section_create(NULL);
        }
 
        section = settings_section_create(NULL);
-       if (!settings_parser_parse_file(section, pattern))
+       loaded = string ? settings_parser_parse_string(section, pattern) :
+                                         settings_parser_parse_file(section, pattern);
+       if (!loaded)
        {
                settings_section_destroy(section, NULL);
                return FALSE;
        {
                settings_section_destroy(section, NULL);
                return FALSE;
@@ -877,7 +881,7 @@ static bool load_files_internal(private_settings_t *this, section_t *parent,
 METHOD(settings_t, load_files, bool,
        private_settings_t *this, char *pattern, bool merge)
 {
 METHOD(settings_t, load_files, bool,
        private_settings_t *this, char *pattern, bool merge)
 {
-       return load_files_internal(this, this->top, pattern, merge);
+       return load_internal(this, this->top, pattern, merge, FALSE);
 }
 
 METHOD(settings_t, load_files_section, bool,
 }
 
 METHOD(settings_t, load_files_section, bool,
@@ -894,7 +898,30 @@ METHOD(settings_t, load_files_section, bool,
        {
                return FALSE;
        }
        {
                return FALSE;
        }
-       return load_files_internal(this, section, pattern, merge);
+       return load_internal(this, section, pattern, merge, FALSE);
+}
+
+METHOD(settings_t, load_string, bool,
+       private_settings_t *this, char *settings, bool merge)
+{
+       return load_internal(this, this->top, settings, merge, TRUE);
+}
+
+METHOD(settings_t, load_string_section, bool,
+       private_settings_t *this, char *settings, bool merge, char *key, ...)
+{
+       section_t *section;
+       va_list args;
+
+       va_start(args, key);
+       section = ensure_section(this, this->top, key, args);
+       va_end(args);
+
+       if (!section)
+       {
+               return FALSE;
+       }
+       return load_internal(this, section, settings, merge, TRUE);
 }
 
 METHOD(settings_t, destroy, void,
 }
 
 METHOD(settings_t, destroy, void,
@@ -906,10 +933,7 @@ METHOD(settings_t, destroy, void,
        free(this);
 }
 
        free(this);
 }
 
-/*
- * see header file
- */
-settings_t *settings_create(char *file)
+static private_settings_t *settings_create_base()
 {
        private_settings_t *this;
 
 {
        private_settings_t *this;
 
@@ -931,14 +955,37 @@ settings_t *settings_create(char *file)
                        .add_fallback = _add_fallback,
                        .load_files = _load_files,
                        .load_files_section = _load_files_section,
                        .add_fallback = _add_fallback,
                        .load_files = _load_files,
                        .load_files_section = _load_files_section,
+                       .load_string = _load_string,
+                       .load_string_section = _load_string_section,
                        .destroy = _destroy,
                },
                .top = settings_section_create(NULL),
                .contents = array_create(0, 0),
                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        );
                        .destroy = _destroy,
                },
                .top = settings_section_create(NULL),
                .contents = array_create(0, 0),
                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        );
+       return this;
+}
+
+/*
+ * see header file
+ */
+settings_t *settings_create(char *file)
+{
+       private_settings_t *this = settings_create_base();
 
        load_files(this, file, FALSE);
 
        return &this->public;
 }
 
        load_files(this, file, FALSE);
 
        return &this->public;
 }
+
+/*
+ * see header file
+ */
+settings_t *settings_create_string(char *settings)
+{
+       private_settings_t *this = settings_create_base();
+
+       load_string(this, settings, FALSE);
+
+       return &this->public;
+}
index 3b87c8f..4ef80d0 100644 (file)
@@ -335,6 +335,50 @@ struct settings_t {
                                                           char *section, ...);
 
        /**
                                                           char *section, ...);
 
        /**
+        * Load settings from the given string.
+        *
+        * If merge is TRUE, existing sections are extended, existing values
+        * replaced, by those found in the string. If it is FALSE, existing
+        * sections are purged before reading the new config.
+        *
+        * @note If the string contains _include_ statements they should be
+        * absolute paths.
+        *
+        * @note If any failures occur, no settings are added at all. So, it's all
+        * or nothing.
+        *
+        * @param settings      string to parse
+        * @param merge         TRUE to merge config with existing values
+        * @return                      TRUE, if settings were loaded successfully
+        */
+       bool (*load_string)(settings_t *this, char *settings, bool merge);
+
+       /**
+        * Load settings from the given string.
+        *
+        * If merge is TRUE, existing sections are extended, existing values
+        * replaced, by those found in the string. If it is FALSE, existing
+        * sections are purged before reading the new config.
+        *
+        * All settings are loaded relative to the given section. The section is
+        * created, if it does not yet exist.
+        *
+        * @note If the string contains _include_ statements they should be
+        * absolute paths.
+        *
+        * @note If any failures occur, no settings are added at all. So, it's all
+        * or nothing.
+        *
+        * @param settings      string to parse
+        * @param merge         TRUE to merge config with existing values
+        * @param section       section name of parent section, printf style
+        * @param ...           argument list for section
+        * @return                      TRUE, if settings were loaded successfully
+        */
+       bool (*load_string_section)(settings_t *this, char *settings, bool merge,
+                                                               char *section, ...);
+
+       /**
         * Destroy a settings instance.
         */
        void (*destroy)(settings_t *this);
         * Destroy a settings instance.
         */
        void (*destroy)(settings_t *this);
@@ -350,4 +394,14 @@ struct settings_t {
  */
 settings_t *settings_create(char *file);
 
  */
 settings_t *settings_create(char *file);
 
+/**
+ * Load settings from a string.
+ *
+ * @note If parsing the file fails the object is still created.
+ *
+ * @param settings             string to read settings from
+ * @return                             settings object, or NULL
+ */
+settings_t *settings_create_string(char *settings);
+
 #endif /** SETTINGS_H_ @}*/
 #endif /** SETTINGS_H_ @}*/