diff options
author | Markus Armbruster | 2020-04-15 09:49:20 +0200 |
---|---|---|
committer | Markus Armbruster | 2020-04-29 08:01:51 +0200 |
commit | 6129803b55553b90805aa5012077b21c6c6eacdc (patch) | |
tree | 4561a55eb793b0dab9c316dcbd00f02db6abb6d5 | |
parent | tests-qemu-opts: Cover has_help_option(), qemu_opt_has_help_opt() (diff) | |
download | qemu-6129803b55553b90805aa5012077b21c6c6eacdc.tar.gz qemu-6129803b55553b90805aa5012077b21c6c6eacdc.tar.xz qemu-6129803b55553b90805aa5012077b21c6c6eacdc.zip |
qemu-options: Factor out get_opt_name_value() helper
The next commits will put it to use.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200415074927.19897-3-armbru@redhat.com>
-rw-r--r-- | util/qemu-option.c | 102 |
1 files changed, 56 insertions, 46 deletions
diff --git a/util/qemu-option.c b/util/qemu-option.c index 97172b5eaa..f08f4bc458 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -805,61 +805,71 @@ void qemu_opts_print(QemuOpts *opts, const char *separator) } } +static const char *get_opt_name_value(const char *params, + const char *firstname, + char **name, char **value) +{ + const char *p, *pe, *pc; + + pe = strchr(params, '='); + pc = strchr(params, ','); + + if (!pe || (pc && pc < pe)) { + /* found "foo,more" */ + if (firstname) { + /* implicitly named first option */ + *name = g_strdup(firstname); + p = get_opt_value(params, value); + } else { + /* option without value, must be a flag */ + p = get_opt_name(params, name, ','); + if (strncmp(*name, "no", 2) == 0) { + memmove(*name, *name + 2, strlen(*name + 2) + 1); + *value = g_strdup("off"); + } else { + *value = g_strdup("on"); + } + } + } else { + /* found "foo=bar,more" */ + p = get_opt_name(params, name, '='); + assert(*p == '='); + p++; + p = get_opt_value(p, value); + } + + assert(!*p || *p == ','); + if (*p == ',') { + p++; + } + return p; +} + static void opts_do_parse(QemuOpts *opts, const char *params, const char *firstname, bool prepend, bool *invalidp, Error **errp) { - char *option = NULL; - char *value = NULL; - const char *p,*pe,*pc; Error *local_err = NULL; + char *option, *value; + const char *p; - for (p = params; *p != '\0'; p++) { - pe = strchr(p, '='); - pc = strchr(p, ','); - if (!pe || (pc && pc < pe)) { - /* found "foo,more" */ - if (p == params && firstname) { - /* implicitly named first option */ - option = g_strdup(firstname); - p = get_opt_value(p, &value); - } else { - /* option without value, probably a flag */ - p = get_opt_name(p, &option, ','); - if (strncmp(option, "no", 2) == 0) { - memmove(option, option+2, strlen(option+2)+1); - value = g_strdup("off"); - } else { - value = g_strdup("on"); - } - } - } else { - /* found "foo=bar,more" */ - p = get_opt_name(p, &option, '='); - assert(*p == '='); - p++; - p = get_opt_value(p, &value); - } - if (strcmp(option, "id") != 0) { - /* store and parse */ - opt_set(opts, option, value, prepend, invalidp, &local_err); - value = NULL; - if (local_err) { - error_propagate(errp, local_err); - goto cleanup; - } - } - if (*p != ',') { - break; + for (p = params; *p;) { + p = get_opt_name_value(p, firstname, &option, &value); + firstname = NULL; + + if (!strcmp(option, "id")) { + g_free(option); + g_free(value); + continue; } + + opt_set(opts, option, value, prepend, invalidp, &local_err); g_free(option); - g_free(value); - option = value = NULL; + if (local_err) { + error_propagate(errp, local_err); + return; + } } - - cleanup: - g_free(option); - g_free(value); } /** |