From: Chunyan Liu <cy...@suse.com> The qemu_opts_append() function is intended to merge to different QemuOptsList's. The resulting list must be freed by its user.
Signed-off-by: Chunyan Liu <cy...@suse.com> Signed-off-by: Leandro Dorileo <l...@dorileo.org> --- include/qemu/option.h | 1 + util/qemu-option.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/include/qemu/option.h b/include/qemu/option.h index f0d4798..3f4976d 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -157,6 +157,7 @@ int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id); QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists, Error **errp); +QemuOptsList *qemu_opts_append(QemuOptsList *head, QemuOptsList *tail); void qemu_opts_reset(QemuOptsList *list); void qemu_opts_loc_restore(QemuOpts *opts); int qemu_opts_set(QemuOptsList *list, const char *id, diff --git a/util/qemu-option.c b/util/qemu-option.c index 612a966..026d2ff 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -863,6 +863,75 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, return opts; } +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; +} + +/** + * Merge two QEMUOptsList. First argument's QemuOptDesc members take precedence + * over second's. + * + * @note The result's name and implied_opt_name are not copied from them. + * Both merge_lists should not be set. Both lists can be NULL. + * + * The resulting QemuOptsList should be freed by this functions caller. + */ +QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list) +{ + size_t num_opts, num_dst_opts; + QemuOptsList *tmp; + QemuOptDesc *desc; + + if (!dst && !list) { + return NULL; + } + + num_opts = count_opts_list(dst); + num_opts += count_opts_list(list); + tmp = g_malloc0(sizeof(QemuOptsList) + + (num_opts + 1) * sizeof(QemuOptDesc)); + QTAILQ_INIT(&tmp->head); + num_dst_opts = 0; + + /* copy dst->desc to new list */ + if (dst) { + desc = dst->desc; + while (desc && desc->name) { + tmp->desc[num_dst_opts++] = *desc; + tmp->desc[num_dst_opts].name = NULL; + desc++; + } + } + + /* add list->desc to new list */ + if (list) { + desc = list->desc; + while (desc && desc->name) { + if (find_desc_by_name(tmp->desc, desc->name) == NULL) { + tmp->desc[num_dst_opts++] = *desc; + tmp->desc[num_dst_opts].name = NULL; + } + desc++; + } + } + + return tmp; +} + void qemu_opts_reset(QemuOptsList *list) { QemuOpts *opts, *next_opts; -- 1.9.0