On Tue, Apr 29, 2014 at 05:08:18PM +0800, Chunyan Liu wrote: > Add two temp conversion functions between QEMUOptionParameter to QemuOpts, > so that next patch can use it. It will simplify later patch for easier > review. And will be finally removed after all backend drivers switch to > QemuOpts. > > Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com> > Reviewed-by: Eric Blake <ebl...@redhat.com> > Signed-off-by: Chunyan Liu <cy...@suse.com>
Reviewed-by: Leandro Dorileo <l...@dorileo.org> > --- > include/qemu/option.h | 9 +++ > util/qemu-option.c | 153 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 162 insertions(+) > > diff --git a/include/qemu/option.h b/include/qemu/option.h > index fbf5dc2..e98e8ef 100644 > --- a/include/qemu/option.h > +++ b/include/qemu/option.h > @@ -103,6 +103,12 @@ typedef struct QemuOptDesc { > } QemuOptDesc; > > struct QemuOptsList { > + /* FIXME: Temp used for QEMUOptionParamter->QemuOpts conversion to > + * indicate the need to free memory. Will remove after all drivers > + * switch to QemuOpts. > + */ > + bool allocated; > + > const char *name; > const char *implied_opt_name; > bool merge_lists; /* Merge multiple uses of option into a single list? > */ > @@ -167,5 +173,8 @@ void qemu_opts_print(QemuOpts *opts); > int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void > *opaque, > int abort_on_failure); > void qemu_opts_print_help(QemuOptsList *list); > +void qemu_opts_free(QemuOptsList *list); > +QEMUOptionParameter *opts_to_params(QemuOpts *opts); > +QemuOptsList *params_to_opts(QEMUOptionParameter *list); > > #endif > diff --git a/util/qemu-option.c b/util/qemu-option.c > index adb7c3c..93ffcd5 100644 > --- a/util/qemu-option.c > +++ b/util/qemu-option.c > @@ -1345,3 +1345,156 @@ int qemu_opts_foreach(QemuOptsList *list, > qemu_opts_loopfunc func, void *opaque, > loc_pop(&loc); > return rc; > } > + > +static size_t count_opts_list(QemuOptsList *list) > +{ > + QemuOptDesc *desc = NULL; > + size_t num_opts = 0; > + > + if (!list) { > + return 0; > + } > + > + desc = list->desc; > + while (desc && desc->name) { > + num_opts++; > + desc++; > + } > + > + return num_opts; > +} > + > +/* Convert QEMUOptionParameter to QemuOpts > + * FIXME: this function will be removed after all drivers > + * switch to QemuOpts > + */ > +QemuOptsList *params_to_opts(QEMUOptionParameter *list) > +{ > + QemuOptsList *opts = NULL; > + size_t num_opts, i = 0; > + > + if (!list) { > + return NULL; > + } > + > + num_opts = count_option_parameters(list); > + opts = g_malloc0(sizeof(QemuOptsList) + > + (num_opts + 1) * sizeof(QemuOptDesc)); > + QTAILQ_INIT(&opts->head); > + /* (const char *) members will point to malloced space and need to free > */ > + opts->allocated = true; > + > + while (list && list->name) { > + opts->desc[i].name = g_strdup(list->name); > + opts->desc[i].help = g_strdup(list->help); > + switch (list->type) { > + case OPT_FLAG: > + opts->desc[i].type = QEMU_OPT_BOOL; > + opts->desc[i].def_value_str = > + g_strdup(list->value.n ? "on" : "off"); > + break; > + > + case OPT_NUMBER: > + opts->desc[i].type = QEMU_OPT_NUMBER; > + if (list->value.n) { > + opts->desc[i].def_value_str = > + g_strdup_printf("%" PRIu64, list->value.n); > + } > + break; > + > + case OPT_SIZE: > + opts->desc[i].type = QEMU_OPT_SIZE; > + if (list->value.n) { > + opts->desc[i].def_value_str = > + g_strdup_printf("%" PRIu64, list->value.n); > + } > + break; > + > + case OPT_STRING: > + opts->desc[i].type = QEMU_OPT_STRING; > + opts->desc[i].def_value_str = g_strdup(list->value.s); > + break; > + } > + > + i++; > + list++; > + } > + > + return opts; > +} > + > +/* convert QemuOpts to QEMUOptionParameter > + * Note: result QEMUOptionParameter has shorter lifetime than > + * input QemuOpts. > + * FIXME: this function will be removed after all drivers > + * switch to QemuOpts > + */ > +QEMUOptionParameter *opts_to_params(QemuOpts *opts) > +{ > + QEMUOptionParameter *dest = NULL; > + QemuOptDesc *desc; > + size_t num_opts, i = 0; > + const char *tmp; > + > + if (!opts || !opts->list || !opts->list->desc) { > + return NULL; > + } > + assert(!opts_accepts_any(opts)); > + > + num_opts = count_opts_list(opts->list); > + dest = g_malloc0((num_opts + 1) * sizeof(QEMUOptionParameter)); > + > + desc = opts->list->desc; > + while (desc && desc->name) { > + dest[i].name = desc->name; > + dest[i].help = desc->help; > + dest[i].assigned = qemu_opt_find(opts, desc->name) ? true : false; > + switch (desc->type) { > + case QEMU_OPT_STRING: > + dest[i].type = OPT_STRING; > + tmp = qemu_opt_get(opts, desc->name); > + dest[i].value.s = g_strdup(tmp); > + break; > + > + case QEMU_OPT_BOOL: > + dest[i].type = OPT_FLAG; > + dest[i].value.n = qemu_opt_get_bool(opts, desc->name, 0) ? 1 : 0; > + break; > + > + case QEMU_OPT_NUMBER: > + dest[i].type = OPT_NUMBER; > + dest[i].value.n = qemu_opt_get_number(opts, desc->name, 0); > + break; > + > + case QEMU_OPT_SIZE: > + dest[i].type = OPT_SIZE; > + dest[i].value.n = qemu_opt_get_size(opts, desc->name, 0); > + break; > + } > + > + i++; > + desc++; > + } > + > + return dest; > +} > + > +void qemu_opts_free(QemuOptsList *list) > +{ > + /* List members point to new malloced space and need to be freed. > + * FIXME: > + * Introduced for QEMUOptionParamter->QemuOpts conversion. > + * Will remove after all drivers switch to QemuOpts. > + */ > + if (list && list->allocated) { > + QemuOptDesc *desc = list->desc; > + while (desc && desc->name) { > + g_free((char *)desc->name); > + g_free((char *)desc->help); > + g_free((char *)desc->def_value_str); > + desc++; > + } > + } > + > + g_free(list); > +} > -- > 1.8.4.5 > > -- Leandro Dorileo