settings: Add methods and a constructor to parse settings from strings
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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_ @}*/
|
||||||
|
|||||||
Reference in New Issue
Block a user