Skip to content

Commit

Permalink
keyval: introduce keyval_parse_into
Browse files Browse the repository at this point in the history
Allow parsing multiple keyval sequences into the same dictionary.
This will be used to simplify the parsing of the -M command line
option, which is currently a .merge_lists = true QemuOpts group.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini committed Jul 6, 2021
1 parent 9176e80 commit c445909
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
2 changes: 2 additions & 0 deletions include/qemu/option.h
Expand Up @@ -147,6 +147,8 @@ void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
void qemu_opts_free(QemuOptsList *list);
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);

QDict *keyval_parse_into(QDict *qdict, const char *params, const char *implied_key,
bool *p_help, Error **errp);
QDict *keyval_parse(const char *params, const char *implied_key,
bool *help, Error **errp);
void keyval_merge(QDict *old, const QDict *new, Error **errp);
Expand Down
43 changes: 35 additions & 8 deletions util/keyval.c
Expand Up @@ -511,13 +511,14 @@ static QObject *keyval_listify(QDict *cur, GSList *key_of_cur, Error **errp)
* If @p_help is not NULL, store whether help is requested there.
* If @p_help is NULL and help is requested, fail.
*
* On success, return a dictionary of the parsed keys and values.
* On failure, store an error through @errp and return NULL.
* On success, return @dict, now filled with the parsed keys and values.
*
* On failure, store an error through @errp and return NULL. Any keys
* and values parsed so far will be in @dict nevertheless.
*/
QDict *keyval_parse(const char *params, const char *implied_key,
bool *p_help, Error **errp)
QDict *keyval_parse_into(QDict *qdict, const char *params, const char *implied_key,
bool *p_help, Error **errp)
{
QDict *qdict = qdict_new();
QObject *listified;
const char *s;
bool help = false;
Expand All @@ -526,7 +527,6 @@ QDict *keyval_parse(const char *params, const char *implied_key,
while (*s) {
s = keyval_parse_one(qdict, s, implied_key, &help, errp);
if (!s) {
qobject_unref(qdict);
return NULL;
}
implied_key = NULL;
Expand All @@ -536,15 +536,42 @@ QDict *keyval_parse(const char *params, const char *implied_key,
*p_help = help;
} else if (help) {
error_setg(errp, "Help is not available for this option");
qobject_unref(qdict);
return NULL;
}

listified = keyval_listify(qdict, NULL, errp);
if (!listified) {
qobject_unref(qdict);
return NULL;
}
assert(listified == QOBJECT(qdict));
return qdict;
}

/*
* Parse @params in QEMU's traditional KEY=VALUE,... syntax.
*
* If @implied_key, the first KEY= can be omitted. @implied_key is
* implied then, and VALUE can't be empty or contain ',' or '='.
*
* A parameter "help" or "?" without a value isn't added to the
* resulting dictionary, but instead is interpreted as help request.
* All other options are parsed and returned normally so that context
* specific help can be printed.
*
* If @p_help is not NULL, store whether help is requested there.
* If @p_help is NULL and help is requested, fail.
*
* On success, return a dictionary of the parsed keys and values.
* On failure, store an error through @errp and return NULL.
*/
QDict *keyval_parse(const char *params, const char *implied_key,
bool *p_help, Error **errp)
{
QDict *qdict = qdict_new();
QDict *ret = keyval_parse_into(qdict, params, implied_key, p_help, errp);

if (!ret) {
qobject_unref(qdict);
}
return ret;
}

0 comments on commit c445909

Please sign in to comment.