conf: introduce snd_config_load_string()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2021-12-01 10:14:12 +01:00
parent a95942f1af
commit ebb8a6c7a1
4 changed files with 65 additions and 28 deletions

View File

@ -89,6 +89,7 @@ const char *snd_config_topdir(void);
int snd_config_top(snd_config_t **config);
int snd_config_load(snd_config_t *config, snd_input_t *in);
int snd_config_load_string(snd_config_t **config, const char *s, size_t size);
int snd_config_load_override(snd_config_t *config, snd_input_t *in);
int snd_config_save(snd_config_t *config, snd_output_t *out);
int snd_config_update(void);

View File

@ -2050,6 +2050,49 @@ int snd_config_load(snd_config_t *config, snd_input_t *in)
return _snd_config_load_with_include(config, in, 0, NULL);
}
/**
* \brief Loads a configuration tree from a string.
* \param[out] The function puts the handle to the configuration
* node loaded from the file(s) at the address specified
* by \a config.
* \param[in] s String with the ASCII configuration
* \param[in] size String size, if zero, a C string is expected (with termination)
* \return Zero if successful, otherwise a negative error code.
*
* The definitions loaded from the string are put to \a config, which
* is created as a new top node.
*
* \par Errors:
* Any errors encountered when parsing the input or returned by hooks or
* functions.
*/
int snd_config_load_string(snd_config_t **config, const char *s, size_t size)
{
snd_input_t *input;
snd_config_t *dst;
int err;
assert(config && s);
if (size == 0)
size = strlen(s);
err = snd_input_buffer_open(&input, s, size);
if (err < 0)
return err;
err = snd_config_top(&dst);
if (err < 0) {
snd_input_close(input);
return err;
}
err = snd_config_load(dst, input);
snd_input_close(input);
if (err < 0) {
snd_config_delete(dst);
return err;
}
*config = dst;
return 0;
}
/**
* \brief Loads a configuration tree and overrides existing configuration nodes.
* \param config Handle to a top level configuration node.

View File

@ -213,32 +213,6 @@ struct lookup_iterate {
void *info;
};
static snd_config_t *parse_lookup_query(const char *query)
{
snd_input_t *input;
snd_config_t *config;
int err;
err = snd_input_buffer_open(&input, query, strlen(query));
if (err < 0) {
uc_error("unable to create memory input buffer");
return NULL;
}
err = snd_config_top(&config);
if (err < 0) {
snd_input_close(input);
return NULL;
}
err = snd_config_load(config, input);
snd_input_close(input);
if (err < 0) {
snd_config_delete(config);
uc_error("wrong arguments '%s'", query);
return NULL;
}
return config;
}
static char *rval_lookup_main(snd_use_case_mgr_t *uc_mgr,
const char *query,
struct lookup_iterate *iter)
@ -257,9 +231,11 @@ static char *rval_lookup_main(snd_use_case_mgr_t *uc_mgr,
return NULL;
}
config = parse_lookup_query(query);
if (config == NULL)
err = snd_config_load_string(&config, query, 0);
if (err < 0) {
uc_error("The lookup arguments '%s' are invalid", query);
return NULL;
}
if (iter->init && iter->init(uc_mgr, iter, config))
goto null;
if (snd_config_search(config, "field", &d)) {

View File

@ -598,6 +598,22 @@ static void test_evaluate_string(void)
}
}
static void test_load_string(void)
{
const char **cfg, *configs[] = {
"a=1,b=2",
"j 3;z 15;",
"x 0 y -1",
NULL
};
snd_config_t *dst;
for (cfg = configs; *cfg; cfg++) {
ALSA_CHECK(snd_config_load_string(&dst, *cfg, 0));
ALSA_CHECK(snd_config_delete(dst));
}
}
int main(void)
{
test_top();
@ -629,5 +645,6 @@ int main(void)
test_iterators();
test_for_each();
test_evaluate_string();
test_load_string();
return TEST_EXIT_CODE();
}