[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v14 09/21] qapi: permit auto-creating single ele
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v14 09/21] qapi: permit auto-creating single element lists |
Date: |
Wed, 12 Oct 2016 11:18:21 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) |
"Daniel P. Berrange" <address@hidden> writes:
> When converting QemuOpts to a QObject, there is no information
> about compound types available,
Yes, that's a drawback of splitting the conversion into a QemuOpts ->
QObject part that is oblivious of types, and a QObject -> QAPI object
part that knows the types.
> so when visiting a list, the
> corresponding QObject is not guaranteed to be a QList. We
> therefore need to be able to auto-create a single element QList
> from whatever type we find.
>
> This mode should only be enabled if you have compatibility
> requirements for
>
> -arg foo=hello,foo=world
>
> to be treated as equivalent to the preferred syntax:
>
> -arg foo.0=hello,foo.1=world
Not sure this is "preferred". "More powerfully warty" is probably
closer to the truth ;)
How is "-arg foo=hello,foo=world" treated if this mode isn't enabled?
What would be the drawbacks of doing this always instead of only when we
"have compatibility requirements"?
> Signed-off-by: Daniel P. Berrange <address@hidden>
> ---
> include/qapi/qobject-input-visitor.h | 20 +++++++-
> qapi/qobject-input-visitor.c | 27 +++++++++--
> tests/test-qobject-input-visitor.c | 88
> +++++++++++++++++++++++++++++++-----
> 3 files changed, 117 insertions(+), 18 deletions(-)
>
> diff --git a/include/qapi/qobject-input-visitor.h
> b/include/qapi/qobject-input-visitor.h
> index f134d90..1809f48 100644
> --- a/include/qapi/qobject-input-visitor.h
> +++ b/include/qapi/qobject-input-visitor.h
> @@ -42,6 +42,19 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool
> strict);
> * represented as strings. i.e. if visiting a boolean, the value should
> * be a QString whose contents represent a valid boolean.
> *
> + * If @autocreate_list is true, then as an alternative to a normal QList,
> + * list values can be stored as a QString or QDict instead, which will
> + * be interpreted as representing single element lists. This should only
> + * by used if compatibility is required with the OptsVisitor which allowed
> + * repeated keys, without list indexes, to represent lists. e.g. set this
> + * to true if you have compatibility requirements for
> + *
> + * -arg foo=hello,foo=world
> + *
> + * to be treated as equivalent to the preferred syntax:
> + *
> + * -arg foo.0=hello,foo.1=world
> + *
> * The visitor always operates in strict mode, requiring all dict keys
> * to be consumed during visitation. An error will be reported if this
> * does not happen.
> @@ -49,7 +62,8 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool
> strict);
> * The returned input visitor should be released by calling
> * visit_free() when no longer required.
> */
> -Visitor *qobject_input_visitor_new_autocast(QObject *obj);
> +Visitor *qobject_input_visitor_new_autocast(QObject *obj,
> + bool autocreate_list);
>
>
> /**
> @@ -64,6 +78,8 @@ Visitor *qobject_input_visitor_new_autocast(QObject *obj);
> * The returned input visitor should be released by calling
> * visit_free() when no longer required.
> */
> -Visitor *qobject_input_visitor_new_opts(const QemuOpts *opts, Error **errp);
> +Visitor *qobject_input_visitor_new_opts(const QemuOpts *opts,
> + bool autocreate_list,
> + Error **errp);
>
> #endif
> diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
> index d9269c9..d88e9f9 100644
> --- a/qapi/qobject-input-visitor.c
> +++ b/qapi/qobject-input-visitor.c
> @@ -48,6 +48,10 @@ struct QObjectInputVisitor
>
> /* True to reject parse in visit_end_struct() if unvisited keys remain.
> */
> bool strict;
> +
> + /* Whether we can auto-create single element lists when
> + * encountering a non-QList type */
> + bool autocreate_list;
> };
>
> static QObjectInputVisitor *to_qiv(Visitor *v)
> @@ -108,6 +112,7 @@ static const QListEntry
> *qobject_input_push(QObjectInputVisitor *qiv,
> assert(obj);
> tos->obj = obj;
> tos->qapi = qapi;
> + qobject_incref(obj);
>
> if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
> h = g_hash_table_new(g_str_hash, g_str_equal);
> @@ -147,6 +152,7 @@ static void qobject_input_stack_object_free(StackObject
> *tos)
> if (tos->h) {
> g_hash_table_unref(tos->h);
> }
> + qobject_decref(tos->obj);
>
> g_free(tos);
> }
Can you explain the reference counting change?
> @@ -197,7 +203,7 @@ static void qobject_input_start_list(Visitor *v, const
> char *name,
> QObject *qobj = qobject_input_get_object(qiv, name, true);
> const QListEntry *entry;
>
> - if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
> + if (!qobj || (!qiv->autocreate_list && qobject_type(qobj) !=
> QTYPE_QLIST)) {
Long line, but I believe it'll go away when you rebase for commit
1382d4a.
> if (list) {
> *list = NULL;
> }
> @@ -206,7 +212,16 @@ static void qobject_input_start_list(Visitor *v, const
> char *name,
> return;
> }
>
> - entry = qobject_input_push(qiv, qobj, list, errp);
> + if (qobject_type(qobj) != QTYPE_QLIST) {
> + QList *tmplist = qlist_new();
> + qlist_append_obj(tmplist, qobj);
> + qobject_incref(qobj);
> + entry = qobject_input_push(qiv, QOBJECT(tmplist), list, errp);
> + QDECREF(tmplist);
> + } else {
> + entry = qobject_input_push(qiv, qobj, list, errp);
> + }
> +
> if (list) {
> if (entry) {
> *list = g_malloc0(size);
Buries autolist behavior in the middle of things. What about doing it
first, so it's more separate?
QObjectInputVisitor *qiv = to_qiv(v);
QObject *qobj = qobject_input_get_object_(qiv, name, true, errp);
const QListEntry *entry;
if (!qobj) {
return;
}
+ if (qiv->autocreate_list && qobject_type(qobj) != QTYPE_QLIST) {
+ QList *auto_list = qlist_new();
+ qlist_append_obj(auto_list, qobj);
+ qobj = auto_list;
+ }
+
if (qobject_type(qobj) != QTYPE_QLIST) {
I ignored reference counting here, because I don't yet understand how
and why you're changing it.
> @@ -514,7 +529,8 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool
> strict)
> return &v->visitor;
> }
>
> -Visitor *qobject_input_visitor_new_autocast(QObject *obj)
> +Visitor *qobject_input_visitor_new_autocast(QObject *obj,
> + bool autocreate_list)
> {
> QObjectInputVisitor *v;
>
> @@ -539,6 +555,7 @@ Visitor *qobject_input_visitor_new_autocast(QObject *obj)
> v->visitor.optional = qobject_input_optional;
> v->visitor.free = qobject_input_free;
> v->strict = true;
> + v->autocreate_list = autocreate_list;
>
> v->root = obj;
> qobject_incref(obj);
> @@ -548,6 +565,7 @@ Visitor *qobject_input_visitor_new_autocast(QObject *obj)
>
>
> Visitor *qobject_input_visitor_new_opts(const QemuOpts *opts,
> + bool autocreate_list,
> Error **errp)
> {
> QDict *pdict;
> @@ -564,7 +582,8 @@ Visitor *qobject_input_visitor_new_opts(const QemuOpts
> *opts,
> goto cleanup;
> }
>
> - v = qobject_input_visitor_new_autocast(pobj);
> + v = qobject_input_visitor_new_autocast(pobj,
> + autocreate_list);
> cleanup:
> qobject_decref(pobj);
> QDECREF(pdict);
[Skipping test updates for now...]
- Re: [Qemu-devel] [PATCH v14 09/21] qapi: permit auto-creating single element lists,
Markus Armbruster <=