settings: Add methods and a constructor to parse settings from strings

This commit is contained in:
Tobias Brunner
2015-07-28 13:27:32 +02:00
parent 0dba2690c4
commit 08b45fc516
2 changed files with 112 additions and 11 deletions
+58 -11
View File
@@ -37,9 +37,10 @@
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 sections and values are added relative to "parent".
* All files (even included ones) have to be loaded successfully. * All files (even included ones) have to be loaded successfully.
* If merge is FALSE the contents of parent are replaced with the parsed * If merge is FALSE the contents of parent are replaced with the parsed
* contents, otherwise they are merged together. * contents, otherwise they are merged together.
*/ */
static bool load_files_internal(private_settings_t *this, section_t *parent, static bool load_internal(private_settings_t *this, section_t *parent,
char *pattern, bool merge) char *pattern, bool merge, bool string)
{ {
section_t *section; section_t *section;
bool loaded;
if (pattern == NULL || !pattern[0]) if (pattern == NULL || !pattern[0])
{ /* TODO: Clear parent if merge is FALSE? */ { /* 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); settings_section_destroy(section, NULL);
return FALSE; return FALSE;
@@ -877,7 +881,7 @@ static bool load_files_internal(private_settings_t *this, section_t *parent,
METHOD(settings_t, load_files, bool, METHOD(settings_t, load_files, bool,
private_settings_t *this, char *pattern, bool merge) 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);
} }
/* static private_settings_t *settings_create_base()
* see header file
*/
settings_t *settings_create(char *file)
{ {
private_settings_t *this; private_settings_t *this;
@@ -931,14 +955,37 @@ settings_t *settings_create(char *file)
.add_fallback = _add_fallback, .add_fallback = _add_fallback,
.load_files = _load_files, .load_files = _load_files,
.load_files_section = _load_files_section, .load_files_section = _load_files_section,
.load_string = _load_string,
.load_string_section = _load_string_section,
.destroy = _destroy, .destroy = _destroy,
}, },
.top = settings_section_create(NULL), .top = settings_section_create(NULL),
.contents = array_create(0, 0), .contents = array_create(0, 0),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT), .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); load_files(this, file, FALSE);
return &this->public; 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;
}
+54
View File
@@ -334,6 +334,50 @@ struct settings_t {
bool (*load_files_section)(settings_t *this, char *pattern, bool merge, bool (*load_files_section)(settings_t *this, char *pattern, bool merge,
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. * Destroy a settings instance.
*/ */
@@ -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_ @}*/