* [Qemu-devel] [PATCH 01/14] qdict: add qdict_put_null() helper
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 5:52 ` Markus Armbruster
2017-08-25 12:53 ` Eduardo Habkost
2017-08-24 10:33 ` [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/ Marc-André Lureau
` (12 subsequent siblings)
13 siblings, 2 replies; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Paolo Bonzini, Richard Henderson,
Eduardo Habkost
A step towards completeness.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qdict.h | 4 +++-
target/i386/cpu.c | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 363e431106..6588c7f0c8 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -53,13 +53,15 @@ void qdict_destroy_obj(QObject *obj);
#define qdict_put(qdict, key, obj) \
qdict_put_obj(qdict, key, QOBJECT(obj))
-/* Helpers for int, bool, and string */
+/* Helpers for int, bool, null, and string */
#define qdict_put_int(qdict, key, value) \
qdict_put(qdict, key, qnum_from_int(value))
#define qdict_put_bool(qdict, key, value) \
qdict_put(qdict, key, qbool_from_bool(value))
#define qdict_put_str(qdict, key, value) \
qdict_put(qdict, key, qstring_from_str(value))
+#define qdict_put_null(qdict, key) \
+ qdict_put(qdict, key, qnull())
/* High level helpers */
double qdict_get_double(const QDict *qdict, const char *key);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ddc45abd70..bec2009a9c 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2454,7 +2454,7 @@ static QDict *x86_cpu_static_props(void)
d = qdict_new();
for (i = 0; props[i]; i++) {
- qdict_put(d, props[i], qnull());
+ qdict_put_null(d, props[i]);
}
for (w = 0; w < FEATURE_WORDS; w++) {
@@ -2464,7 +2464,7 @@ static QDict *x86_cpu_static_props(void)
if (!fi->feat_names[bit]) {
continue;
}
- qdict_put(d, fi->feat_names[bit], qnull());
+ qdict_put_null(d, fi->feat_names[bit]);
}
}
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 01/14] qdict: add qdict_put_null() helper
2017-08-24 10:33 ` [Qemu-devel] [PATCH 01/14] qdict: add qdict_put_null() helper Marc-André Lureau
@ 2017-08-25 5:52 ` Markus Armbruster
2017-08-25 12:53 ` Eduardo Habkost
1 sibling, 0 replies; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 5:52 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Richard Henderson, Eduardo Habkost, Paolo Bonzini
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> A step towards completeness.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 01/14] qdict: add qdict_put_null() helper
2017-08-24 10:33 ` [Qemu-devel] [PATCH 01/14] qdict: add qdict_put_null() helper Marc-André Lureau
2017-08-25 5:52 ` Markus Armbruster
@ 2017-08-25 12:53 ` Eduardo Habkost
1 sibling, 0 replies; 32+ messages in thread
From: Eduardo Habkost @ 2017-08-25 12:53 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, armbru, Paolo Bonzini, Richard Henderson
On Thu, Aug 24, 2017 at 12:33:37PM +0200, Marc-André Lureau wrote:
> A step towards completeness.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
--
Eduardo
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 01/14] qdict: add qdict_put_null() helper Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 5:55 ` Markus Armbruster
2017-09-01 0:06 ` Eduardo Habkost
2017-08-24 10:33 ` [Qemu-devel] [PATCH 03/14] qlit: use QLit prefix consistently Marc-André Lureau
` (11 subsequent siblings)
13 siblings, 2 replies; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Fix code style issues while at it, to please check-patch.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 49 +++++++++++++++++++++++++
qobject/qlit.c | 89 +++++++++++++++++++++++++++++++++++++++++++++
tests/check-qjson.c | 96 +------------------------------------------------
qobject/Makefile.objs | 2 +-
4 files changed, 140 insertions(+), 96 deletions(-)
create mode 100644 include/qapi/qmp/qlit.h
create mode 100644 qobject/qlit.c
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
new file mode 100644
index 0000000000..4e2e760ef1
--- /dev/null
+++ b/include/qapi/qmp/qlit.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright IBM, Corp. 2009
+ * Copyright (c) 2013, 2015, 2017 Red Hat Inc.
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Markus Armbruster <armbru@redhat.com>
+ * Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+#ifndef QLIT_H_
+#define QLIT_H_
+
+#include "qapi-types.h"
+#include "qobject.h"
+
+typedef struct LiteralQDictEntry LiteralQDictEntry;
+typedef struct LiteralQObject LiteralQObject;
+
+struct LiteralQObject {
+ int type;
+ union {
+ int64_t qnum;
+ const char *qstr;
+ LiteralQDictEntry *qdict;
+ LiteralQObject *qlist;
+ } value;
+};
+
+struct LiteralQDictEntry {
+ const char *key;
+ LiteralQObject value;
+};
+
+#define QLIT_QNUM(val) \
+ (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
+#define QLIT_QSTR(val) \
+ (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
+#define QLIT_QDICT(val) \
+ (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
+#define QLIT_QLIST(val) \
+ (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
+
+int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
+
+#endif /* QLIT_H_ */
diff --git a/qobject/qlit.c b/qobject/qlit.c
new file mode 100644
index 0000000000..5917c3584e
--- /dev/null
+++ b/qobject/qlit.c
@@ -0,0 +1,89 @@
+/*
+ * QLit literal qobject
+ *
+ * Copyright IBM, Corp. 2009
+ * Copyright (c) 2013, 2015, 2017 Red Hat Inc.
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Markus Armbruster <armbru@redhat.com>
+ * Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/qmp/qlit.h"
+#include "qapi/qmp/types.h"
+
+typedef struct QListCompareHelper {
+ int index;
+ LiteralQObject *objs;
+ int result;
+} QListCompareHelper;
+
+static void compare_helper(QObject *obj, void *opaque)
+{
+ QListCompareHelper *helper = opaque;
+
+ if (helper->result == 0) {
+ return;
+ }
+
+ if (helper->objs[helper->index].type == QTYPE_NONE) {
+ helper->result = 0;
+ return;
+ }
+
+ helper->result =
+ compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
+}
+
+int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
+{
+ int64_t val;
+
+ if (!rhs || lhs->type != qobject_type(rhs)) {
+ return 0;
+ }
+
+ switch (lhs->type) {
+ case QTYPE_QNUM:
+ g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val));
+ return lhs->value.qnum == val;
+ case QTYPE_QSTRING:
+ return (strcmp(lhs->value.qstr,
+ qstring_get_str(qobject_to_qstring(rhs))) == 0);
+ case QTYPE_QDICT: {
+ int i;
+
+ for (i = 0; lhs->value.qdict[i].key; i++) {
+ QObject *obj = qdict_get(qobject_to_qdict(rhs),
+ lhs->value.qdict[i].key);
+
+ if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
+ return 0;
+ }
+ }
+
+ return 1;
+ }
+ case QTYPE_QLIST: {
+ QListCompareHelper helper;
+
+ helper.index = 0;
+ helper.objs = lhs->value.qlist;
+ helper.result = 1;
+
+ qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
+
+ return helper.result;
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index a3a97b0d99..525f79e60b 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -16,6 +16,7 @@
#include "qapi/error.h"
#include "qapi/qmp/types.h"
#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qlit.h"
#include "qemu-common.h"
static void escaped_string(void)
@@ -1059,101 +1060,6 @@ static void keyword_literal(void)
QDECREF(null);
}
-typedef struct LiteralQDictEntry LiteralQDictEntry;
-typedef struct LiteralQObject LiteralQObject;
-
-struct LiteralQObject
-{
- int type;
- union {
- int64_t qnum;
- const char *qstr;
- LiteralQDictEntry *qdict;
- LiteralQObject *qlist;
- } value;
-};
-
-struct LiteralQDictEntry
-{
- const char *key;
- LiteralQObject value;
-};
-
-#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
-#define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
-#define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
-#define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
-
-typedef struct QListCompareHelper
-{
- int index;
- LiteralQObject *objs;
- int result;
-} QListCompareHelper;
-
-static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
-
-static void compare_helper(QObject *obj, void *opaque)
-{
- QListCompareHelper *helper = opaque;
-
- if (helper->result == 0) {
- return;
- }
-
- if (helper->objs[helper->index].type == QTYPE_NONE) {
- helper->result = 0;
- return;
- }
-
- helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
-}
-
-static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
-{
- int64_t val;
-
- if (!rhs || lhs->type != qobject_type(rhs)) {
- return 0;
- }
-
- switch (lhs->type) {
- case QTYPE_QNUM:
- g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val));
- return lhs->value.qnum == val;
- case QTYPE_QSTRING:
- return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
- case QTYPE_QDICT: {
- int i;
-
- for (i = 0; lhs->value.qdict[i].key; i++) {
- QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key);
-
- if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
- return 0;
- }
- }
-
- return 1;
- }
- case QTYPE_QLIST: {
- QListCompareHelper helper;
-
- helper.index = 0;
- helper.objs = lhs->value.qlist;
- helper.result = 1;
-
- qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
-
- return helper.result;
- }
- default:
- break;
- }
-
- return 0;
-}
-
static void simple_dict(void)
{
int i;
diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs
index fc8885c9a4..002d25873a 100644
--- a/qobject/Makefile.objs
+++ b/qobject/Makefile.objs
@@ -1,2 +1,2 @@
-util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o
+util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o qlit.o
util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/
2017-08-24 10:33 ` [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/ Marc-André Lureau
@ 2017-08-25 5:55 ` Markus Armbruster
2017-09-01 0:06 ` Eduardo Habkost
1 sibling, 0 replies; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 5:55 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Fix code style issues while at it, to please check-patch.
It's spelled checkpatch. Can touch up on commit.
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 49 +++++++++++++++++++++++++
> qobject/qlit.c | 89 +++++++++++++++++++++++++++++++++++++++++++++
> tests/check-qjson.c | 96 +------------------------------------------------
> qobject/Makefile.objs | 2 +-
> 4 files changed, 140 insertions(+), 96 deletions(-)
> create mode 100644 include/qapi/qmp/qlit.h
> create mode 100644 qobject/qlit.c
>
> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> new file mode 100644
> index 0000000000..4e2e760ef1
> --- /dev/null
> +++ b/include/qapi/qmp/qlit.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright IBM, Corp. 2009
> + * Copyright (c) 2013, 2015, 2017 Red Hat Inc.
> + *
> + * Authors:
> + * Anthony Liguori <aliguori@us.ibm.com>
> + * Markus Armbruster <armbru@redhat.com>
> + * Marc-André Lureau <marcandre.lureau@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +#ifndef QLIT_H_
> +#define QLIT_H_
QLIT_H (no trailing _), to match the other headers in this directory.
Can touch up on commit.
[...]
With the two spelling nits corrected:
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/
2017-08-24 10:33 ` [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/ Marc-André Lureau
2017-08-25 5:55 ` Markus Armbruster
@ 2017-09-01 0:06 ` Eduardo Habkost
2017-09-01 9:05 ` Markus Armbruster
1 sibling, 1 reply; 32+ messages in thread
From: Eduardo Habkost @ 2017-09-01 0:06 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
On Thu, Aug 24, 2017 at 12:33:38PM +0200, Marc-André Lureau wrote:
> Fix code style issues while at it, to please check-patch.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 49 +++++++++++++++++++++++++
> qobject/qlit.c | 89 +++++++++++++++++++++++++++++++++++++++++++++
> tests/check-qjson.c | 96 +------------------------------------------------
> qobject/Makefile.objs | 2 +-
> 4 files changed, 140 insertions(+), 96 deletions(-)
> create mode 100644 include/qapi/qmp/qlit.h
> create mode 100644 qobject/qlit.c
>
> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> new file mode 100644
> index 0000000000..4e2e760ef1
> --- /dev/null
> +++ b/include/qapi/qmp/qlit.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright IBM, Corp. 2009
> + * Copyright (c) 2013, 2015, 2017 Red Hat Inc.
> + *
> + * Authors:
> + * Anthony Liguori <aliguori@us.ibm.com>
> + * Markus Armbruster <armbru@redhat.com>
> + * Marc-André Lureau <marcandre.lureau@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +#ifndef QLIT_H_
> +#define QLIT_H_
> +
> +#include "qapi-types.h"
> +#include "qobject.h"
> +
> +typedef struct LiteralQDictEntry LiteralQDictEntry;
> +typedef struct LiteralQObject LiteralQObject;
> +
> +struct LiteralQObject {
> + int type;
> + union {
> + int64_t qnum;
> + const char *qstr;
> + LiteralQDictEntry *qdict;
> + LiteralQObject *qlist;
> + } value;
> +};
> +
> +struct LiteralQDictEntry {
> + const char *key;
> + LiteralQObject value;
> +};
> +
> +#define QLIT_QNUM(val) \
> + (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
> +#define QLIT_QSTR(val) \
> + (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
> +#define QLIT_QDICT(val) \
> + (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
> +#define QLIT_QLIST(val) \
> + (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
I'm still trying to understand why this exists. Doesn't this
provide exactly the same functionality as QObject?
> [...]
--
Eduardo
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/
2017-09-01 0:06 ` Eduardo Habkost
@ 2017-09-01 9:05 ` Markus Armbruster
2017-09-01 13:23 ` Eduardo Habkost
0 siblings, 1 reply; 32+ messages in thread
From: Markus Armbruster @ 2017-09-01 9:05 UTC (permalink / raw)
To: Eduardo Habkost; +Cc: Marc-André Lureau, qemu-devel
Eduardo Habkost <ehabkost@redhat.com> writes:
> On Thu, Aug 24, 2017 at 12:33:38PM +0200, Marc-André Lureau wrote:
>> Fix code style issues while at it, to please check-patch.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> include/qapi/qmp/qlit.h | 49 +++++++++++++++++++++++++
>> qobject/qlit.c | 89 +++++++++++++++++++++++++++++++++++++++++++++
>> tests/check-qjson.c | 96 +------------------------------------------------
>> qobject/Makefile.objs | 2 +-
>> 4 files changed, 140 insertions(+), 96 deletions(-)
>> create mode 100644 include/qapi/qmp/qlit.h
>> create mode 100644 qobject/qlit.c
>>
>> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
>> new file mode 100644
>> index 0000000000..4e2e760ef1
>> --- /dev/null
>> +++ b/include/qapi/qmp/qlit.h
>> @@ -0,0 +1,49 @@
>> +/*
>> + * Copyright IBM, Corp. 2009
>> + * Copyright (c) 2013, 2015, 2017 Red Hat Inc.
>> + *
>> + * Authors:
>> + * Anthony Liguori <aliguori@us.ibm.com>
>> + * Markus Armbruster <armbru@redhat.com>
>> + * Marc-André Lureau <marcandre.lureau@redhat.com>
>> + *
>> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
>> + * See the COPYING.LIB file in the top-level directory.
>> + *
>> + */
>> +#ifndef QLIT_H_
>> +#define QLIT_H_
>> +
>> +#include "qapi-types.h"
>> +#include "qobject.h"
>> +
>> +typedef struct LiteralQDictEntry LiteralQDictEntry;
>> +typedef struct LiteralQObject LiteralQObject;
>> +
>> +struct LiteralQObject {
>> + int type;
>> + union {
>> + int64_t qnum;
>> + const char *qstr;
>> + LiteralQDictEntry *qdict;
>> + LiteralQObject *qlist;
>> + } value;
>> +};
>> +
>> +struct LiteralQDictEntry {
>> + const char *key;
>> + LiteralQObject value;
>> +};
>> +
>> +#define QLIT_QNUM(val) \
>> + (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
>> +#define QLIT_QSTR(val) \
>> + (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
>> +#define QLIT_QDICT(val) \
>> + (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
>> +#define QLIT_QLIST(val) \
>> + (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
>
> I'm still trying to understand why this exists. Doesn't this
> provide exactly the same functionality as QObject?
The value-add is initializers. Check out check-qjson.c for examples.
Use cases:
* Specify expected output as data (QLitObject initializer), then use
qlit_equal_qobject() to verify actual output matches. Example:
check-qjson.c. I think it compares nicely to the qdict_get morass we
use elsewhere.
* Specify a QObject as data (QLitObject initializer), build it with
qobject_from_qlit(). Example: PATCH 14. I think it beats specifying
the QObject in code (qdict_new(), qdict_put(), ...) at least when the
QObject is big.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/
2017-09-01 9:05 ` Markus Armbruster
@ 2017-09-01 13:23 ` Eduardo Habkost
0 siblings, 0 replies; 32+ messages in thread
From: Eduardo Habkost @ 2017-09-01 13:23 UTC (permalink / raw)
To: Markus Armbruster; +Cc: Marc-André Lureau, qemu-devel
On Fri, Sep 01, 2017 at 11:05:11AM +0200, Markus Armbruster wrote:
> Eduardo Habkost <ehabkost@redhat.com> writes:
>
> > On Thu, Aug 24, 2017 at 12:33:38PM +0200, Marc-André Lureau wrote:
> >> Fix code style issues while at it, to please check-patch.
> >>
> >> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> >> ---
> >> include/qapi/qmp/qlit.h | 49 +++++++++++++++++++++++++
> >> qobject/qlit.c | 89 +++++++++++++++++++++++++++++++++++++++++++++
> >> tests/check-qjson.c | 96 +------------------------------------------------
> >> qobject/Makefile.objs | 2 +-
> >> 4 files changed, 140 insertions(+), 96 deletions(-)
> >> create mode 100644 include/qapi/qmp/qlit.h
> >> create mode 100644 qobject/qlit.c
> >>
> >> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> >> new file mode 100644
> >> index 0000000000..4e2e760ef1
> >> --- /dev/null
> >> +++ b/include/qapi/qmp/qlit.h
> >> @@ -0,0 +1,49 @@
> >> +/*
> >> + * Copyright IBM, Corp. 2009
> >> + * Copyright (c) 2013, 2015, 2017 Red Hat Inc.
> >> + *
> >> + * Authors:
> >> + * Anthony Liguori <aliguori@us.ibm.com>
> >> + * Markus Armbruster <armbru@redhat.com>
> >> + * Marc-André Lureau <marcandre.lureau@redhat.com>
> >> + *
> >> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> >> + * See the COPYING.LIB file in the top-level directory.
> >> + *
> >> + */
> >> +#ifndef QLIT_H_
> >> +#define QLIT_H_
> >> +
> >> +#include "qapi-types.h"
> >> +#include "qobject.h"
> >> +
> >> +typedef struct LiteralQDictEntry LiteralQDictEntry;
> >> +typedef struct LiteralQObject LiteralQObject;
> >> +
> >> +struct LiteralQObject {
> >> + int type;
> >> + union {
> >> + int64_t qnum;
> >> + const char *qstr;
> >> + LiteralQDictEntry *qdict;
> >> + LiteralQObject *qlist;
> >> + } value;
> >> +};
> >> +
> >> +struct LiteralQDictEntry {
> >> + const char *key;
> >> + LiteralQObject value;
> >> +};
> >> +
> >> +#define QLIT_QNUM(val) \
> >> + (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
> >> +#define QLIT_QSTR(val) \
> >> + (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
> >> +#define QLIT_QDICT(val) \
> >> + (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
> >> +#define QLIT_QLIST(val) \
> >> + (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
> >
> > I'm still trying to understand why this exists. Doesn't this
> > provide exactly the same functionality as QObject?
>
> The value-add is initializers. Check out check-qjson.c for examples.
Oh, I see.
QList and QDict seem to be the ones that require special code for
literals. Making initializers for QNull, QNum, QString, and
QBool seems possible.
>
> Use cases:
>
> * Specify expected output as data (QLitObject initializer), then use
> qlit_equal_qobject() to verify actual output matches. Example:
> check-qjson.c. I think it compares nicely to the qdict_get morass we
> use elsewhere.
Is any qlit_equal_qobject() user so performance-critical that it
couldn't be replaced by a QObject/QObject comparison function,
and implemented as qobject_equals(qobject_from_qlit(a), b)?
>
> * Specify a QObject as data (QLitObject initializer), build it with
> qobject_from_qlit(). Example: PATCH 14. I think it beats specifying
> the QObject in code (qdict_new(), qdict_put(), ...) at least when the
> QObject is big.
--
Eduardo
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 03/14] qlit: use QLit prefix consistently
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 01/14] qdict: add qdict_put_null() helper Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 02/14] qlit: move qlit from check-qjson to qobject/ Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 6:04 ` Markus Armbruster
2017-08-24 10:33 ` [Qemu-devel] [PATCH 04/14] qlit: remove needless type cast Marc-André Lureau
` (10 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Rename from LiteralQ to QLit.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 24 ++++++++++++------------
qobject/qlit.c | 4 ++--
tests/check-qjson.c | 40 ++++++++++++++++++++--------------------
3 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index 4e2e760ef1..f36bca4554 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -17,33 +17,33 @@
#include "qapi-types.h"
#include "qobject.h"
-typedef struct LiteralQDictEntry LiteralQDictEntry;
-typedef struct LiteralQObject LiteralQObject;
+typedef struct QLitDictEntry QLitDictEntry;
+typedef struct QLitObject QLitObject;
-struct LiteralQObject {
+struct QLitObject {
int type;
union {
int64_t qnum;
const char *qstr;
- LiteralQDictEntry *qdict;
- LiteralQObject *qlist;
+ QLitDictEntry *qdict;
+ QLitObject *qlist;
} value;
};
-struct LiteralQDictEntry {
+struct QLitDictEntry {
const char *key;
- LiteralQObject value;
+ QLitObject value;
};
#define QLIT_QNUM(val) \
- (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
+ (QLitObject){.type = QTYPE_QNUM, .value.qnum = (val)}
#define QLIT_QSTR(val) \
- (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
+ (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
#define QLIT_QDICT(val) \
- (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
+ (QLitObject){.type = QTYPE_QDICT, .value.qdict = (val)}
#define QLIT_QLIST(val) \
- (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
+ (QLitObject){.type = QTYPE_QLIST, .value.qlist = (val)}
-int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
+int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
#endif /* QLIT_H_ */
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 5917c3584e..262d64988d 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -20,7 +20,7 @@
typedef struct QListCompareHelper {
int index;
- LiteralQObject *objs;
+ QLitObject *objs;
int result;
} QListCompareHelper;
@@ -41,7 +41,7 @@ static void compare_helper(QObject *obj, void *opaque)
compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
}
-int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
+int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs)
{
int64_t val;
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 525f79e60b..82b3681327 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -1065,23 +1065,23 @@ static void simple_dict(void)
int i;
struct {
const char *encoded;
- LiteralQObject decoded;
+ QLitObject decoded;
} test_cases[] = {
{
.encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
- .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
+ .decoded = QLIT_QDICT(((QLitDictEntry[]){
{ "foo", QLIT_QNUM(42) },
{ "bar", QLIT_QSTR("hello world") },
{ }
})),
}, {
.encoded = "{}",
- .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
+ .decoded = QLIT_QDICT(((QLitDictEntry[]){
{ }
})),
}, {
.encoded = "{\"foo\": 43}",
- .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
+ .decoded = QLIT_QDICT(((QLitDictEntry[]){
{ "foo", QLIT_QNUM(43) },
{ }
})),
@@ -1163,11 +1163,11 @@ static void simple_list(void)
int i;
struct {
const char *encoded;
- LiteralQObject decoded;
+ QLitObject decoded;
} test_cases[] = {
{
.encoded = "[43,42]",
- .decoded = QLIT_QLIST(((LiteralQObject[]){
+ .decoded = QLIT_QLIST(((QLitObject[]){
QLIT_QNUM(43),
QLIT_QNUM(42),
{ }
@@ -1175,21 +1175,21 @@ static void simple_list(void)
},
{
.encoded = "[43]",
- .decoded = QLIT_QLIST(((LiteralQObject[]){
+ .decoded = QLIT_QLIST(((QLitObject[]){
QLIT_QNUM(43),
{ }
})),
},
{
.encoded = "[]",
- .decoded = QLIT_QLIST(((LiteralQObject[]){
+ .decoded = QLIT_QLIST(((QLitObject[]){
{ }
})),
},
{
.encoded = "[{}]",
- .decoded = QLIT_QLIST(((LiteralQObject[]){
- QLIT_QDICT(((LiteralQDictEntry[]){
+ .decoded = QLIT_QLIST(((QLitObject[]){
+ QLIT_QDICT(((QLitDictEntry[]){
{},
})),
{},
@@ -1220,11 +1220,11 @@ static void simple_whitespace(void)
int i;
struct {
const char *encoded;
- LiteralQObject decoded;
+ QLitObject decoded;
} test_cases[] = {
{
.encoded = " [ 43 , 42 ]",
- .decoded = QLIT_QLIST(((LiteralQObject[]){
+ .decoded = QLIT_QLIST(((QLitObject[]){
QLIT_QNUM(43),
QLIT_QNUM(42),
{ }
@@ -1232,12 +1232,12 @@ static void simple_whitespace(void)
},
{
.encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
- .decoded = QLIT_QLIST(((LiteralQObject[]){
+ .decoded = QLIT_QLIST(((QLitObject[]){
QLIT_QNUM(43),
- QLIT_QDICT(((LiteralQDictEntry[]){
+ QLIT_QDICT(((QLitDictEntry[]){
{ "h", QLIT_QSTR("b") },
{ }})),
- QLIT_QLIST(((LiteralQObject[]){
+ QLIT_QLIST(((QLitObject[]){
{ }})),
QLIT_QNUM(42),
{ }
@@ -1245,13 +1245,13 @@ static void simple_whitespace(void)
},
{
.encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
- .decoded = QLIT_QLIST(((LiteralQObject[]){
+ .decoded = QLIT_QLIST(((QLitObject[]){
QLIT_QNUM(43),
- QLIT_QDICT(((LiteralQDictEntry[]){
+ QLIT_QDICT(((QLitDictEntry[]){
{ "h", QLIT_QSTR("b") },
{ "a", QLIT_QNUM(32) },
{ }})),
- QLIT_QLIST(((LiteralQObject[]){
+ QLIT_QLIST(((QLitObject[]){
{ }})),
QLIT_QNUM(42),
{ }
@@ -1282,10 +1282,10 @@ static void simple_varargs(void)
{
QObject *embedded_obj;
QObject *obj;
- LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
+ QLitObject decoded = QLIT_QLIST(((QLitObject[]){
QLIT_QNUM(1),
QLIT_QNUM(2),
- QLIT_QLIST(((LiteralQObject[]){
+ QLIT_QLIST(((QLitObject[]){
QLIT_QNUM(32),
QLIT_QNUM(42),
{}})),
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 04/14] qlit: remove needless type cast
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (2 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 03/14] qlit: use QLit prefix consistently Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 6:20 ` Markus Armbruster
2017-08-24 10:33 ` [Qemu-devel] [PATCH 05/14] qlit: rename compare_litqobj_to_qobj Marc-André Lureau
` (9 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
And misc code style fix.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index f36bca4554..1e9696988a 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -36,13 +36,13 @@ struct QLitDictEntry {
};
#define QLIT_QNUM(val) \
- (QLitObject){.type = QTYPE_QNUM, .value.qnum = (val)}
+ { .type = QTYPE_QNUM, .value.qnum = (val) }
#define QLIT_QSTR(val) \
- (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
+ { .type = QTYPE_QSTRING, .value.qstr = (val) }
#define QLIT_QDICT(val) \
- (QLitObject){.type = QTYPE_QDICT, .value.qdict = (val)}
+ { .type = QTYPE_QDICT, .value.qdict = (val) }
#define QLIT_QLIST(val) \
- (QLitObject){.type = QTYPE_QLIST, .value.qlist = (val)}
+ { .type = QTYPE_QLIST, .value.qlist = (val) }
int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 04/14] qlit: remove needless type cast
2017-08-24 10:33 ` [Qemu-devel] [PATCH 04/14] qlit: remove needless type cast Marc-André Lureau
@ 2017-08-25 6:20 ` Markus Armbruster
2017-08-25 10:17 ` Marc-André Lureau
0 siblings, 1 reply; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 6:20 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> And misc code style fix.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> index f36bca4554..1e9696988a 100644
> --- a/include/qapi/qmp/qlit.h
> +++ b/include/qapi/qmp/qlit.h
> @@ -36,13 +36,13 @@ struct QLitDictEntry {
> };
>
> #define QLIT_QNUM(val) \
> - (QLitObject){.type = QTYPE_QNUM, .value.qnum = (val)}
> + { .type = QTYPE_QNUM, .value.qnum = (val) }
> #define QLIT_QSTR(val) \
> - (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
> + { .type = QTYPE_QSTRING, .value.qstr = (val) }
> #define QLIT_QDICT(val) \
> - (QLitObject){.type = QTYPE_QDICT, .value.qdict = (val)}
> + { .type = QTYPE_QDICT, .value.qdict = (val) }
> #define QLIT_QLIST(val) \
> - (QLitObject){.type = QTYPE_QLIST, .value.qlist = (val)}
> + { .type = QTYPE_QLIST, .value.qlist = (val) }
>
> int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
Technically, this isn't a type cast, it's a compound literal. A
compound literal is "an unnamed object whose value is given by the
initializer list" (C99 §6.5.2.5). The standard then cautions "that this
differs from a cast expression" (ibid).
The previous paragraph probably makes sense only to language-lawyers, so
let's consider an example.
The macro
#define QLIT_QSTR(val) \
(QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
expands into a compound literal of type QLitObject, which can be used as
an initializer for a variable of type QLitObject.
The macro
#define QLIT_QSTR(val) \
{ .type = QTYPE_QSTRING, .value.qstr = (val) }
expands into something that can be used as an initializer for a variable
of *any* structure type with suitable members. Duck typing, if you
will.
The original author's choice of compound literals is clearly
intentional. I'd prefer to respect it unless there's a compelling
reason not to.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 04/14] qlit: remove needless type cast
2017-08-25 6:20 ` Markus Armbruster
@ 2017-08-25 10:17 ` Marc-André Lureau
2017-08-28 11:17 ` Markus Armbruster
0 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-25 10:17 UTC (permalink / raw)
To: Markus Armbruster; +Cc: qemu-devel
Hi
On Fri, Aug 25, 2017 at 8:20 AM Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
> > And misc code style fix.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > include/qapi/qmp/qlit.h | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> > index f36bca4554..1e9696988a 100644
> > --- a/include/qapi/qmp/qlit.h
> > +++ b/include/qapi/qmp/qlit.h
> > @@ -36,13 +36,13 @@ struct QLitDictEntry {
> > };
> >
> > #define QLIT_QNUM(val) \
> > - (QLitObject){.type = QTYPE_QNUM, .value.qnum = (val)}
> > + { .type = QTYPE_QNUM, .value.qnum = (val) }
> > #define QLIT_QSTR(val) \
> > - (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
> > + { .type = QTYPE_QSTRING, .value.qstr = (val) }
> > #define QLIT_QDICT(val) \
> > - (QLitObject){.type = QTYPE_QDICT, .value.qdict = (val)}
> > + { .type = QTYPE_QDICT, .value.qdict = (val) }
> > #define QLIT_QLIST(val) \
> > - (QLitObject){.type = QTYPE_QLIST, .value.qlist = (val)}
> > + { .type = QTYPE_QLIST, .value.qlist = (val) }
> >
> > int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
>
> Technically, this isn't a type cast, it's a compound literal. A
> compound literal is "an unnamed object whose value is given by the
> initializer list" (C99 §6.5.2.5). The standard then cautions "that this
> differs from a cast expression" (ibid).
>
You are right, but actually the patch helps with another issue if we keep
the compound type:
const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
QLIT_QNULL,
{}
}));
qmp-introspect.c:17:63: error: initializer element is not constant
const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
^
/home/elmarco/src/qemu/include/qapi/qmp/qlit.h:50:57: note: in definition
of macro ‘QLIT_QLIST’
(QLitObject) { .type = QTYPE_QLIST, .value.qlist = (val) }
^~~
qmp-introspect.c:17:63: note: (near initialization for ‘(anonymous).value’)
const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
^
/home/elmarco/src/qemu/include/qapi/qmp/qlit.h:50:57: note: in definition
of macro ‘QLIT_QLIST’
(QLitObject) { .type = QTYPE_QLIST, .value.qlist = (val) }
^~~
Any idea how to fix that?
>
> The previous paragraph probably makes sense only to language-lawyers, so
> let's consider an example.
>
> The macro
>
> #define QLIT_QSTR(val) \
> (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
>
> expands into a compound literal of type QLitObject, which can be used as
> an initializer for a variable of type QLitObject.
>
> The macro
>
> #define QLIT_QSTR(val) \
> { .type = QTYPE_QSTRING, .value.qstr = (val) }
>
> expands into something that can be used as an initializer for a variable
> of *any* structure type with suitable members. Duck typing, if you
> will.
>
> The original author's choice of compound literals is clearly
> intentional. I'd prefer to respect it unless there's a compelling
> reason not to.
>
> --
Marc-André Lureau
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 04/14] qlit: remove needless type cast
2017-08-25 10:17 ` Marc-André Lureau
@ 2017-08-28 11:17 ` Markus Armbruster
0 siblings, 0 replies; 32+ messages in thread
From: Markus Armbruster @ 2017-08-28 11:17 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Fri, Aug 25, 2017 at 8:20 AM Markus Armbruster <armbru@redhat.com> wrote:
>
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>> > And misc code style fix.
>> >
>> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> > ---
>> > include/qapi/qmp/qlit.h | 8 ++++----
>> > 1 file changed, 4 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
>> > index f36bca4554..1e9696988a 100644
>> > --- a/include/qapi/qmp/qlit.h
>> > +++ b/include/qapi/qmp/qlit.h
>> > @@ -36,13 +36,13 @@ struct QLitDictEntry {
>> > };
>> >
>> > #define QLIT_QNUM(val) \
>> > - (QLitObject){.type = QTYPE_QNUM, .value.qnum = (val)}
>> > + { .type = QTYPE_QNUM, .value.qnum = (val) }
>> > #define QLIT_QSTR(val) \
>> > - (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
>> > + { .type = QTYPE_QSTRING, .value.qstr = (val) }
>> > #define QLIT_QDICT(val) \
>> > - (QLitObject){.type = QTYPE_QDICT, .value.qdict = (val)}
>> > + { .type = QTYPE_QDICT, .value.qdict = (val) }
>> > #define QLIT_QLIST(val) \
>> > - (QLitObject){.type = QTYPE_QLIST, .value.qlist = (val)}
>> > + { .type = QTYPE_QLIST, .value.qlist = (val) }
>> >
>> > int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
>>
>> Technically, this isn't a type cast, it's a compound literal. A
>> compound literal is "an unnamed object whose value is given by the
>> initializer list" (C99 §6.5.2.5). The standard then cautions "that this
>> differs from a cast expression" (ibid).
>
> You are right, but actually the patch helps with another issue if we keep
> the compound type:
>
> const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
> QLIT_QNULL,
> {}
> }));
>
> qmp-introspect.c:17:63: error: initializer element is not constant
> const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
> ^
> /home/elmarco/src/qemu/include/qapi/qmp/qlit.h:50:57: note: in definition
> of macro ‘QLIT_QLIST’
> (QLitObject) { .type = QTYPE_QLIST, .value.qlist = (val) }
> ^~~
> qmp-introspect.c:17:63: note: (near initialization for ‘(anonymous).value’)
> const QLitObject qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
> ^
> /home/elmarco/src/qemu/include/qapi/qmp/qlit.h:50:57: note: in definition
> of macro ‘QLIT_QLIST’
> (QLitObject) { .type = QTYPE_QLIST, .value.qlist = (val) }
> ^~~
> Any idea how to fix that?
This one:
[...]
>> The original author's choice of compound literals is clearly
>> intentional. I'd prefer to respect it unless there's a compelling
>> reason not to.
Rewrite your commit message so it explains your *actual* reason for
converting the macro from compound literal to initializer.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 05/14] qlit: rename compare_litqobj_to_qobj
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (3 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 04/14] qlit: remove needless type cast Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 6:35 ` Markus Armbruster
2017-08-24 10:33 ` [Qemu-devel] [PATCH 06/14] qlit: make qlit_equal_qobject return a bool Marc-André Lureau
` (8 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Use qlit_ prefix.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 2 +-
qobject/qlit.c | 6 +++---
tests/check-qjson.c | 14 +++++++-------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index 1e9696988a..e299e8fab0 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -44,6 +44,6 @@ struct QLitDictEntry {
#define QLIT_QLIST(val) \
{ .type = QTYPE_QLIST, .value.qlist = (val) }
-int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
+int qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
#endif /* QLIT_H_ */
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 262d64988d..0c4101898d 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -38,10 +38,10 @@ static void compare_helper(QObject *obj, void *opaque)
}
helper->result =
- compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
+ qlit_equal_qobject(&helper->objs[helper->index++], obj);
}
-int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs)
+int qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
{
int64_t val;
@@ -63,7 +63,7 @@ int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs)
QObject *obj = qdict_get(qobject_to_qdict(rhs),
lhs->value.qdict[i].key);
- if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
+ if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) {
return 0;
}
}
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 82b3681327..e5ca273cbc 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -1094,13 +1094,13 @@ static void simple_dict(void)
QString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
- g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
str = qobject_to_json(obj);
qobject_decref(obj);
obj = qobject_from_json(qstring_get_str(str), &error_abort);
- g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
qobject_decref(obj);
QDECREF(str);
}
@@ -1203,13 +1203,13 @@ static void simple_list(void)
QString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
- g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
str = qobject_to_json(obj);
qobject_decref(obj);
obj = qobject_from_json(qstring_get_str(str), &error_abort);
- g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
qobject_decref(obj);
QDECREF(str);
}
@@ -1265,13 +1265,13 @@ static void simple_whitespace(void)
QString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
- g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
str = qobject_to_json(obj);
qobject_decref(obj);
obj = qobject_from_json(qstring_get_str(str), &error_abort);
- g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
qobject_decref(obj);
QDECREF(str);
@@ -1295,7 +1295,7 @@ static void simple_varargs(void)
g_assert(embedded_obj != NULL);
obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
- g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&decoded, obj) == 1);
qobject_decref(obj);
}
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 05/14] qlit: rename compare_litqobj_to_qobj
2017-08-24 10:33 ` [Qemu-devel] [PATCH 05/14] qlit: rename compare_litqobj_to_qobj Marc-André Lureau
@ 2017-08-25 6:35 ` Markus Armbruster
2017-08-25 6:44 ` Markus Armbruster
0 siblings, 1 reply; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 6:35 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Use qlit_ prefix.
Let's spell it out:
qlit: rename compare_litqobj_to_qobj() to qlit_equal_qobject()
By the way, not only is your name shorter, it's also more precise:
"compare" suggests -1, 0, +1 for less than, equal and greater than,
equal suggests non-zero for equal, zero for unequal.
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 2 +-
> qobject/qlit.c | 6 +++---
> tests/check-qjson.c | 14 +++++++-------
> 3 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> index 1e9696988a..e299e8fab0 100644
> --- a/include/qapi/qmp/qlit.h
> +++ b/include/qapi/qmp/qlit.h
> @@ -44,6 +44,6 @@ struct QLitDictEntry {
> #define QLIT_QLIST(val) \
> { .type = QTYPE_QLIST, .value.qlist = (val) }
>
> -int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
> +int qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
>
> #endif /* QLIT_H_ */
Let's use this opportunity to change the return value to bool.
With those changes:
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 05/14] qlit: rename compare_litqobj_to_qobj
2017-08-25 6:35 ` Markus Armbruster
@ 2017-08-25 6:44 ` Markus Armbruster
0 siblings, 0 replies; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 6:44 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Markus Armbruster <armbru@redhat.com> writes:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Use qlit_ prefix.
>
> Let's spell it out:
>
> qlit: rename compare_litqobj_to_qobj() to qlit_equal_qobject()
>
> By the way, not only is your name shorter, it's also more precise:
> "compare" suggests -1, 0, +1 for less than, equal and greater than,
> equal suggests non-zero for equal, zero for unequal.
>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> include/qapi/qmp/qlit.h | 2 +-
>> qobject/qlit.c | 6 +++---
>> tests/check-qjson.c | 14 +++++++-------
>> 3 files changed, 11 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
>> index 1e9696988a..e299e8fab0 100644
>> --- a/include/qapi/qmp/qlit.h
>> +++ b/include/qapi/qmp/qlit.h
>> @@ -44,6 +44,6 @@ struct QLitDictEntry {
>> #define QLIT_QLIST(val) \
>> { .type = QTYPE_QLIST, .value.qlist = (val) }
>>
>> -int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs);
>> +int qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
>>
>> #endif /* QLIT_H_ */
>
> Let's use this opportunity to change the return value to bool.
Maybe I should peek at the next patch once in a while. Nevermind!
> With those changes:
Scratch "those changes", just touch up the commit message a bit:
qlit: rename compare_litqobj_to_qobj() to qlit_equal_qobject()
compare_litqobj_to_qobj() lacks a qlit_ prefix. Moreover, "compare"
suggests -1, 0, +1 for less than, equal and greater than. The
function actually returns non-zero for equal, zero for unequal.
Rename to qlit_equal_qobject().
Its return type will be cleaned up in the next patch.
Can do on commit.
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 06/14] qlit: make qlit_equal_qobject return a bool
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (4 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 05/14] qlit: rename compare_litqobj_to_qobj Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 6:55 ` Markus Armbruster
2017-08-24 10:33 ` [Qemu-devel] [PATCH 07/14] qlit: make qlit_equal_qobject() take const arguments Marc-André Lureau
` (7 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Make it more obvious about the expected return values.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 2 +-
qobject/qlit.c | 18 +++++++++---------
tests/check-qjson.c | 14 +++++++-------
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index e299e8fab0..2e22d0f73c 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -44,6 +44,6 @@ struct QLitDictEntry {
#define QLIT_QLIST(val) \
{ .type = QTYPE_QLIST, .value.qlist = (val) }
-int qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
+bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
#endif /* QLIT_H_ */
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 0c4101898d..a2975bef3f 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -21,19 +21,19 @@
typedef struct QListCompareHelper {
int index;
QLitObject *objs;
- int result;
+ bool result;
} QListCompareHelper;
static void compare_helper(QObject *obj, void *opaque)
{
QListCompareHelper *helper = opaque;
- if (helper->result == 0) {
+ if (!helper->result) {
return;
}
if (helper->objs[helper->index].type == QTYPE_NONE) {
- helper->result = 0;
+ helper->result = false;
return;
}
@@ -41,12 +41,12 @@ static void compare_helper(QObject *obj, void *opaque)
qlit_equal_qobject(&helper->objs[helper->index++], obj);
}
-int qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
+bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
{
int64_t val;
if (!rhs || lhs->type != qobject_type(rhs)) {
- return 0;
+ return false;
}
switch (lhs->type) {
@@ -64,18 +64,18 @@ int qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
lhs->value.qdict[i].key);
if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) {
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
case QTYPE_QLIST: {
QListCompareHelper helper;
helper.index = 0;
helper.objs = lhs->value.qlist;
- helper.result = 1;
+ helper.result = true;
qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
@@ -85,5 +85,5 @@ int qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
break;
}
- return 0;
+ return false;
}
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index e5ca273cbc..59227934ce 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -1094,13 +1094,13 @@ static void simple_dict(void)
QString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
- g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
str = qobject_to_json(obj);
qobject_decref(obj);
obj = qobject_from_json(qstring_get_str(str), &error_abort);
- g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
qobject_decref(obj);
QDECREF(str);
}
@@ -1203,13 +1203,13 @@ static void simple_list(void)
QString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
- g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
str = qobject_to_json(obj);
qobject_decref(obj);
obj = qobject_from_json(qstring_get_str(str), &error_abort);
- g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
qobject_decref(obj);
QDECREF(str);
}
@@ -1265,13 +1265,13 @@ static void simple_whitespace(void)
QString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
- g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
str = qobject_to_json(obj);
qobject_decref(obj);
obj = qobject_from_json(qstring_get_str(str), &error_abort);
- g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
qobject_decref(obj);
QDECREF(str);
@@ -1295,7 +1295,7 @@ static void simple_varargs(void)
g_assert(embedded_obj != NULL);
obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
- g_assert(qlit_equal_qobject(&decoded, obj) == 1);
+ g_assert(qlit_equal_qobject(&decoded, obj));
qobject_decref(obj);
}
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 06/14] qlit: make qlit_equal_qobject return a bool
2017-08-24 10:33 ` [Qemu-devel] [PATCH 06/14] qlit: make qlit_equal_qobject return a bool Marc-André Lureau
@ 2017-08-25 6:55 ` Markus Armbruster
0 siblings, 0 replies; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 6:55 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Make it more obvious about the expected return values.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 2 +-
> qobject/qlit.c | 18 +++++++++---------
> tests/check-qjson.c | 14 +++++++-------
> 3 files changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> index e299e8fab0..2e22d0f73c 100644
> --- a/include/qapi/qmp/qlit.h
> +++ b/include/qapi/qmp/qlit.h
> @@ -44,6 +44,6 @@ struct QLitDictEntry {
> #define QLIT_QLIST(val) \
> { .type = QTYPE_QLIST, .value.qlist = (val) }
>
> -int qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
> +bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
>
> #endif /* QLIT_H_ */
> diff --git a/qobject/qlit.c b/qobject/qlit.c
> index 0c4101898d..a2975bef3f 100644
> --- a/qobject/qlit.c
> +++ b/qobject/qlit.c
> @@ -21,19 +21,19 @@
> typedef struct QListCompareHelper {
> int index;
> QLitObject *objs;
> - int result;
> + bool result;
> } QListCompareHelper;
>
> static void compare_helper(QObject *obj, void *opaque)
> {
> QListCompareHelper *helper = opaque;
>
> - if (helper->result == 0) {
> + if (!helper->result) {
> return;
> }
>
> if (helper->objs[helper->index].type == QTYPE_NONE) {
> - helper->result = 0;
> + helper->result = false;
> return;
> }
>
> @@ -41,12 +41,12 @@ static void compare_helper(QObject *obj, void *opaque)
> qlit_equal_qobject(&helper->objs[helper->index++], obj);
> }
>
> -int qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
> +bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
> {
> int64_t val;
>
> if (!rhs || lhs->type != qobject_type(rhs)) {
> - return 0;
> + return false;
> }
>
> switch (lhs->type) {
> @@ -64,18 +64,18 @@ int qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
> lhs->value.qdict[i].key);
>
> if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) {
> - return 0;
> + return false;
> }
> }
>
> - return 1;
> + return true;
> }
> case QTYPE_QLIST: {
> QListCompareHelper helper;
>
> helper.index = 0;
> helper.objs = lhs->value.qlist;
> - helper.result = 1;
> + helper.result = true;
>
> qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
>
Let's use QLIST_FOREACH_ENTRY() rather than qlist_iter() with awkward
callback machinery. Could be done before this patch (might reduce
churn) or after. Even as a follow-up patch.
Speaking of additional cleanup: qlit_equal_dict() clones its QDict
argument for no good reason. Drop the clone and compare
qdict_size(dict) == i instead. Same result except when you got
duplicates in your QLitObject, but that's a silly programming error I
wouldn't bother to cope with or catch.
> @@ -85,5 +85,5 @@ int qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
> break;
> }
>
> - return 0;
> + return false;
> }
> diff --git a/tests/check-qjson.c b/tests/check-qjson.c
> index e5ca273cbc..59227934ce 100644
> --- a/tests/check-qjson.c
> +++ b/tests/check-qjson.c
> @@ -1094,13 +1094,13 @@ static void simple_dict(void)
> QString *str;
>
> obj = qobject_from_json(test_cases[i].encoded, &error_abort);
> - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
> + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
>
> str = qobject_to_json(obj);
> qobject_decref(obj);
>
> obj = qobject_from_json(qstring_get_str(str), &error_abort);
> - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
> + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
> qobject_decref(obj);
> QDECREF(str);
> }
> @@ -1203,13 +1203,13 @@ static void simple_list(void)
> QString *str;
>
> obj = qobject_from_json(test_cases[i].encoded, &error_abort);
> - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
> + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
>
> str = qobject_to_json(obj);
> qobject_decref(obj);
>
> obj = qobject_from_json(qstring_get_str(str), &error_abort);
> - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
> + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
> qobject_decref(obj);
> QDECREF(str);
> }
> @@ -1265,13 +1265,13 @@ static void simple_whitespace(void)
> QString *str;
>
> obj = qobject_from_json(test_cases[i].encoded, &error_abort);
> - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
> + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
>
> str = qobject_to_json(obj);
> qobject_decref(obj);
>
> obj = qobject_from_json(qstring_get_str(str), &error_abort);
> - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1);
> + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
>
> qobject_decref(obj);
> QDECREF(str);
> @@ -1295,7 +1295,7 @@ static void simple_varargs(void)
> g_assert(embedded_obj != NULL);
>
> obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
> - g_assert(qlit_equal_qobject(&decoded, obj) == 1);
> + g_assert(qlit_equal_qobject(&decoded, obj));
>
> qobject_decref(obj);
> }
Reviewed-by: Markus Armbruster <armbru@redhat.com>
I encourage you to pursue the additional cleanups I outlined above.
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 07/14] qlit: make qlit_equal_qobject() take const arguments
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (5 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 06/14] qlit: make qlit_equal_qobject return a bool Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 6:56 ` Markus Armbruster
2017-08-24 10:33 ` [Qemu-devel] [PATCH 08/14] qlit: add QLIT_QNULL and QLIT_BOOL Marc-André Lureau
` (6 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 2 +-
qobject/qlit.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index 2e22d0f73c..8882016199 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -44,6 +44,6 @@ struct QLitDictEntry {
#define QLIT_QLIST(val) \
{ .type = QTYPE_QLIST, .value.qlist = (val) }
-bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
+bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs);
#endif /* QLIT_H_ */
diff --git a/qobject/qlit.c b/qobject/qlit.c
index a2975bef3f..ae2787ef35 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -41,7 +41,7 @@ static void compare_helper(QObject *obj, void *opaque)
qlit_equal_qobject(&helper->objs[helper->index++], obj);
}
-bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
+bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
{
int64_t val;
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 07/14] qlit: make qlit_equal_qobject() take const arguments
2017-08-24 10:33 ` [Qemu-devel] [PATCH 07/14] qlit: make qlit_equal_qobject() take const arguments Marc-André Lureau
@ 2017-08-25 6:56 ` Markus Armbruster
0 siblings, 0 replies; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 6:56 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 2 +-
> qobject/qlit.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> index 2e22d0f73c..8882016199 100644
> --- a/include/qapi/qmp/qlit.h
> +++ b/include/qapi/qmp/qlit.h
> @@ -44,6 +44,6 @@ struct QLitDictEntry {
> #define QLIT_QLIST(val) \
> { .type = QTYPE_QLIST, .value.qlist = (val) }
>
> -bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs);
> +bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs);
>
> #endif /* QLIT_H_ */
> diff --git a/qobject/qlit.c b/qobject/qlit.c
> index a2975bef3f..ae2787ef35 100644
> --- a/qobject/qlit.c
> +++ b/qobject/qlit.c
> @@ -41,7 +41,7 @@ static void compare_helper(QObject *obj, void *opaque)
> qlit_equal_qobject(&helper->objs[helper->index++], obj);
> }
>
> -bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs)
> +bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
> {
> int64_t val;
Could be squashed into the previous patch, but since you got the two
split, let's leave them split and save us the trouble of wording the
squash's commit message.
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 08/14] qlit: add QLIT_QNULL and QLIT_BOOL
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (6 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 07/14] qlit: make qlit_equal_qobject() take const arguments Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 6:57 ` Markus Armbruster
2017-08-24 10:33 ` [Qemu-devel] [PATCH 09/14] qlit: replace assert(qnum_get_try_int) Marc-André Lureau
` (5 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
As they are going to be used in the following patches.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 5 +++++
qobject/qlit.c | 4 ++++
2 files changed, 9 insertions(+)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index 8882016199..7118fc9e32 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -23,6 +23,7 @@ typedef struct QLitObject QLitObject;
struct QLitObject {
int type;
union {
+ bool qbool;
int64_t qnum;
const char *qstr;
QLitDictEntry *qdict;
@@ -35,6 +36,10 @@ struct QLitDictEntry {
QLitObject value;
};
+#define QLIT_QNULL \
+ { .type = QTYPE_QNULL }
+#define QLIT_QBOOL(val) \
+ { .type = QTYPE_QBOOL, .value.qbool = (val) }
#define QLIT_QNUM(val) \
{ .type = QTYPE_QNUM, .value.qnum = (val) }
#define QLIT_QSTR(val) \
diff --git a/qobject/qlit.c b/qobject/qlit.c
index ae2787ef35..07ad6b05e8 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -50,6 +50,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
}
switch (lhs->type) {
+ case QTYPE_QBOOL:
+ return lhs->value.qbool == qbool_get_bool(qobject_to_qbool(rhs));
case QTYPE_QNUM:
g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val));
return lhs->value.qnum == val;
@@ -81,6 +83,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
return helper.result;
}
+ case QTYPE_QNULL:
+ return true;
default:
break;
}
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 09/14] qlit: replace assert(qnum_get_try_int)
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (7 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 08/14] qlit: add QLIT_QNULL and QLIT_BOOL Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-25 7:02 ` Markus Armbruster
2017-08-24 10:33 ` [Qemu-devel] [PATCH 10/14] tests: add qlit tests Marc-André Lureau
` (4 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
qnum_get_int() will assert if underlying type isn't compatible.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qobject/qlit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 07ad6b05e8..7e4bf92862 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -53,7 +53,7 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
case QTYPE_QBOOL:
return lhs->value.qbool == qbool_get_bool(qobject_to_qbool(rhs));
case QTYPE_QNUM:
- g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val));
+ val = qnum_get_int(qobject_to_qnum(rhs));
return lhs->value.qnum == val;
case QTYPE_QSTRING:
return (strcmp(lhs->value.qstr,
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 09/14] qlit: replace assert(qnum_get_try_int)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 09/14] qlit: replace assert(qnum_get_try_int) Marc-André Lureau
@ 2017-08-25 7:02 ` Markus Armbruster
0 siblings, 0 replies; 32+ messages in thread
From: Markus Armbruster @ 2017-08-25 7:02 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> qnum_get_int() will assert if underlying type isn't compatible.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qobject/qlit.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/qobject/qlit.c b/qobject/qlit.c
> index 07ad6b05e8..7e4bf92862 100644
> --- a/qobject/qlit.c
> +++ b/qobject/qlit.c
> @@ -53,7 +53,7 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
> case QTYPE_QBOOL:
> return lhs->value.qbool == qbool_get_bool(qobject_to_qbool(rhs));
> case QTYPE_QNUM:
> - g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val));
> + val = qnum_get_int(qobject_to_qnum(rhs));
> return lhs->value.qnum == val;
> case QTYPE_QSTRING:
> return (strcmp(lhs->value.qstr,
Suggest commit message
qlit: Replace open-coded qnum_get_int() by call
Bonus: rids us of a side effect in an assertion.
Can do on commit.
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 10/14] tests: add qlit tests
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (8 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 09/14] qlit: replace assert(qnum_get_try_int) Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 11/14] qlit: improve QLit dict vs qdict comparison Marc-André Lureau
` (3 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/check-qlit.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/Makefile.include | 5 +++-
2 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 tests/check-qlit.c
diff --git a/tests/check-qlit.c b/tests/check-qlit.c
new file mode 100644
index 0000000000..47fde92a46
--- /dev/null
+++ b/tests/check-qlit.c
@@ -0,0 +1,64 @@
+/*
+ * QLit unit-tests.
+ *
+ * Copyright (C) 2017 Red Hat Inc.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qlit.h"
+#include "qapi/qmp/qnum.h"
+#include "qapi/qmp/qstring.h"
+
+static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) {
+ { "foo", QLIT_QNUM(42) },
+ { "bar", QLIT_QSTR("hello world") },
+ { "baz", QLIT_QNULL },
+ { "bee", QLIT_QLIST(((QLitObject[]) {
+ QLIT_QNUM(43),
+ QLIT_QNUM(44),
+ QLIT_QBOOL(true),
+ { },
+ }))},
+ { },
+}));
+
+static QObject *make_qobject(void)
+{
+ QDict *qdict = qdict_new();
+ QList *list = qlist_new();
+
+ qdict_put_int(qdict, "foo", 42);
+ qdict_put_str(qdict, "bar", "hello world");
+ qdict_put_null(qdict, "baz");
+
+ qlist_append_int(list, 43);
+ qlist_append_int(list, 44);
+ qlist_append_bool(list, true);
+ qdict_put(qdict, "bee", list);
+
+ return QOBJECT(qdict);
+}
+
+static void qlit_equal_qobject_test(void)
+{
+ QObject *qobj = make_qobject();
+
+ g_assert(qlit_equal_qobject(&qlit, qobj));
+
+ qobject_decref(qobj);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/qlit/equal_qobject", qlit_equal_qobject_test);
+
+ return g_test_run();
+}
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 37c1bed683..3653c7b40a 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -43,6 +43,8 @@ check-unit-y += tests/check-qnull$(EXESUF)
gcov-files-check-qnull-y = qobject/qnull.c
check-unit-y += tests/check-qjson$(EXESUF)
gcov-files-check-qjson-y = qobject/qjson.c
+check-unit-y += tests/check-qlit$(EXESUF)
+gcov-files-check-qlit-y = qobject/qlit.c
check-unit-y += tests/test-qobject-output-visitor$(EXESUF)
gcov-files-test-qobject-output-visitor-y = qapi/qobject-output-visitor.c
check-unit-y += tests/test-clone-visitor$(EXESUF)
@@ -535,7 +537,7 @@ GENERATED_FILES += tests/test-qapi-types.h tests/test-qapi-visit.h \
test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \
tests/check-qlist.o tests/check-qnull.o \
- tests/check-qjson.o \
+ tests/check-qjson.o tests/check-qlit.o \
tests/test-coroutine.o tests/test-string-output-visitor.o \
tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \
tests/test-clone-visitor.o \
@@ -569,6 +571,7 @@ tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y)
tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y)
tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
+tests/check-qlit$(EXESUF): tests/check-qlit.o $(test-util-obj-y)
tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 11/14] qlit: improve QLit dict vs qdict comparison
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (9 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 10/14] tests: add qlit tests Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 12/14] qlit: improve QLit list vs qlist comparison Marc-André Lureau
` (2 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Fail if the QLit dict doesn't match exactly the object dict.
To do so, create a copy of the original qdict, and remove the checked
elements. Verify that the dict is empty by the end of the comparison.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qobject/qlit.c | 42 ++++++++++++++++++++++++++++--------------
tests/check-qlit.c | 7 +++++++
2 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 7e4bf92862..45ae0635c0 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -41,6 +41,32 @@ static void compare_helper(QObject *obj, void *opaque)
qlit_equal_qobject(&helper->objs[helper->index++], obj);
}
+static bool qlit_equal_qdict(const QLitObject *lhs, const QDict *qdict)
+{
+ QDict *dict = qdict_clone_shallow(qdict);
+ bool success = false;
+ int i;
+
+ for (i = 0; lhs->value.qdict[i].key; i++) {
+ QObject *obj = qdict_get(dict, lhs->value.qdict[i].key);
+
+ if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) {
+ goto end;
+ }
+ qdict_del(dict, lhs->value.qdict[i].key);
+ }
+
+ if (qdict_size(dict) != 0) {
+ goto end;
+ }
+
+ success = true;
+
+end:
+ QDECREF(dict);
+ return success;
+}
+
bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
{
int64_t val;
@@ -58,20 +84,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
case QTYPE_QSTRING:
return (strcmp(lhs->value.qstr,
qstring_get_str(qobject_to_qstring(rhs))) == 0);
- case QTYPE_QDICT: {
- int i;
-
- for (i = 0; lhs->value.qdict[i].key; i++) {
- QObject *obj = qdict_get(qobject_to_qdict(rhs),
- lhs->value.qdict[i].key);
-
- if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) {
- return false;
- }
- }
-
- return true;
- }
+ case QTYPE_QDICT:
+ return qlit_equal_qdict(lhs, qobject_to_qdict(rhs));
case QTYPE_QLIST: {
QListCompareHelper helper;
diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index 47fde92a46..5d9558dfd9 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -28,6 +28,11 @@ static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) {
{ },
}));
+static QLitObject qlit_foo = QLIT_QDICT(((QLitDictEntry[]) {
+ { "foo", QLIT_QNUM(42) },
+ { },
+}));
+
static QObject *make_qobject(void)
{
QDict *qdict = qdict_new();
@@ -51,6 +56,8 @@ static void qlit_equal_qobject_test(void)
g_assert(qlit_equal_qobject(&qlit, qobj));
+ g_assert(!qlit_equal_qobject(&qlit_foo, qobj));
+
qobject_decref(qobj);
}
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 12/14] qlit: improve QLit list vs qlist comparison
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (10 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 11/14] qlit: improve QLit dict vs qdict comparison Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-24 10:38 ` Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 13/14] qlit: add qobject_form_qlit() Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 14/14] qapi: generate a literal qobject for introspection Marc-André Lureau
13 siblings, 1 reply; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Check that the QLit list has the same size as the qlist, this should
ensure that we have an exact match when iterating over qlist for
comparing the elements.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qobject/qlit.c | 39 ++++++++++++++++++++++++++-------------
tests/check-qlit.c | 3 +++
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 45ae0635c0..0a60802d74 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -67,6 +67,28 @@ end:
return success;
}
+static bool qlit_equal_qlist(const QLitObject *lhs, const QList *qlist)
+{
+ QListCompareHelper helper;
+ int i;
+
+ for (i = 0; lhs->value.qlist[i].type != QTYPE_NONE; i++) {
+ continue;
+ }
+
+ if (qlist_size(qlist) != i) {
+ return false;
+ }
+
+ helper.index = 0;
+ helper.objs = lhs->value.qlist;
+ helper.result = true;
+
+ qlist_iter(qlist, compare_helper, &helper);
+
+ return helper.result;
+}
+
bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
{
int64_t val;
@@ -82,21 +104,12 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
val = qnum_get_int(qobject_to_qnum(rhs));
return lhs->value.qnum == val;
case QTYPE_QSTRING:
- return (strcmp(lhs->value.qstr,
- qstring_get_str(qobject_to_qstring(rhs))) == 0);
+ return g_str_equal(lhs->value.qstr,
+ qstring_get_str(qobject_to_qstring(rhs)));
case QTYPE_QDICT:
return qlit_equal_qdict(lhs, qobject_to_qdict(rhs));
- case QTYPE_QLIST: {
- QListCompareHelper helper;
-
- helper.index = 0;
- helper.objs = lhs->value.qlist;
- helper.result = true;
-
- qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
-
- return helper.result;
- }
+ case QTYPE_QLIST:
+ return qlit_equal_qlist(lhs, qobject_to_qlist(rhs));
case QTYPE_QNULL:
return true;
default:
diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index 5d9558dfd9..ae74bfcb83 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -58,6 +58,9 @@ static void qlit_equal_qobject_test(void)
g_assert(!qlit_equal_qobject(&qlit_foo, qobj));
+ qdict_put(qobject_to_qdict(qobj), "bee", qlist_new());
+ g_assert(!qlit_equal_qobject(&qlit, qobj));
+
qobject_decref(qobj);
}
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 12/14] qlit: improve QLit list vs qlist comparison
2017-08-24 10:33 ` [Qemu-devel] [PATCH 12/14] qlit: improve QLit list vs qlist comparison Marc-André Lureau
@ 2017-08-24 10:38 ` Marc-André Lureau
0 siblings, 0 replies; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:38 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru
----- Original Message -----
> Check that the QLit list has the same size as the qlist, this should
> ensure that we have an exact match when iterating over qlist for
> comparing the elements.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qobject/qlit.c | 39 ++++++++++++++++++++++++++-------------
> tests/check-qlit.c | 3 +++
> 2 files changed, 29 insertions(+), 13 deletions(-)
>
> diff --git a/qobject/qlit.c b/qobject/qlit.c
> index 45ae0635c0..0a60802d74 100644
> --- a/qobject/qlit.c
> +++ b/qobject/qlit.c
> @@ -67,6 +67,28 @@ end:
> return success;
> }
>
> +static bool qlit_equal_qlist(const QLitObject *lhs, const QList *qlist)
> +{
> + QListCompareHelper helper;
> + int i;
> +
> + for (i = 0; lhs->value.qlist[i].type != QTYPE_NONE; i++) {
> + continue;
> + }
> +
> + if (qlist_size(qlist) != i) {
> + return false;
> + }
> +
> + helper.index = 0;
> + helper.objs = lhs->value.qlist;
> + helper.result = true;
> +
> + qlist_iter(qlist, compare_helper, &helper);
> +
> + return helper.result;
> +}
> +
> bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
> {
> int64_t val;
> @@ -82,21 +104,12 @@ bool qlit_equal_qobject(const QLitObject *lhs, const
> QObject *rhs)
> val = qnum_get_int(qobject_to_qnum(rhs));
> return lhs->value.qnum == val;
> case QTYPE_QSTRING:
> - return (strcmp(lhs->value.qstr,
> - qstring_get_str(qobject_to_qstring(rhs))) == 0);
> + return g_str_equal(lhs->value.qstr,
> + qstring_get_str(qobject_to_qstring(rhs)));
drop this hunk, it slipped in by mistake.
> case QTYPE_QDICT:
> return qlit_equal_qdict(lhs, qobject_to_qdict(rhs));
> - case QTYPE_QLIST: {
> - QListCompareHelper helper;
> -
> - helper.index = 0;
> - helper.objs = lhs->value.qlist;
> - helper.result = true;
> -
> - qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
> -
> - return helper.result;
> - }
> + case QTYPE_QLIST:
> + return qlit_equal_qlist(lhs, qobject_to_qlist(rhs));
> case QTYPE_QNULL:
> return true;
> default:
> diff --git a/tests/check-qlit.c b/tests/check-qlit.c
> index 5d9558dfd9..ae74bfcb83 100644
> --- a/tests/check-qlit.c
> +++ b/tests/check-qlit.c
> @@ -58,6 +58,9 @@ static void qlit_equal_qobject_test(void)
>
> g_assert(!qlit_equal_qobject(&qlit_foo, qobj));
>
> + qdict_put(qobject_to_qdict(qobj), "bee", qlist_new());
> + g_assert(!qlit_equal_qobject(&qlit, qobj));
> +
> qobject_decref(qobj);
> }
>
> --
> 2.14.1.146.gd35faa819
>
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 13/14] qlit: add qobject_form_qlit()
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (11 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 12/14] qlit: improve QLit list vs qlist comparison Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
2017-08-24 10:33 ` [Qemu-devel] [PATCH 14/14] qapi: generate a literal qobject for introspection Marc-André Lureau
13 siblings, 0 replies; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 2 ++
qobject/qlit.c | 37 +++++++++++++++++++++++++++++++++++++
tests/check-qlit.c | 26 ++++++++++++++++++++++++++
3 files changed, 65 insertions(+)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index 7118fc9e32..9b6e06d02f 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -51,4 +51,6 @@ struct QLitDictEntry {
bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs);
+QObject *qobject_from_qlit(const QLitObject *qlit);
+
#endif /* QLIT_H_ */
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 0a60802d74..4adc2033a9 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -118,3 +118,40 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
return false;
}
+
+QObject *qobject_from_qlit(const QLitObject *qlit)
+{
+ int i;
+
+ switch (qlit->type) {
+ case QTYPE_QNULL:
+ return QOBJECT(qnull());
+ case QTYPE_QNUM:
+ return QOBJECT(qnum_from_int(qlit->value.qnum));
+ case QTYPE_QSTRING:
+ return QOBJECT(qstring_from_str(qlit->value.qstr));
+ case QTYPE_QDICT: {
+ QDict *qdict = qdict_new();
+ for (i = 0; qlit->value.qdict[i].value.type != QTYPE_NONE; i++) {
+ QLitDictEntry *e = &qlit->value.qdict[i];
+
+ qdict_put_obj(qdict, e->key, qobject_from_qlit(&e->value));
+ }
+ return QOBJECT(qdict);
+ }
+ case QTYPE_QLIST: {
+ QList *qlist = qlist_new();
+
+ for (i = 0; qlit->value.qlist[i].type != QTYPE_NONE; i++) {
+ qlist_append_obj(qlist, qobject_from_qlit(&qlit->value.qlist[i]));
+ }
+ return QOBJECT(qlist);
+ }
+ case QTYPE_QBOOL:
+ return QOBJECT(qbool_from_bool(qlit->value.qbool));
+ case QTYPE_NONE:
+ assert(0);
+ }
+
+ return NULL;
+}
diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index ae74bfcb83..135a399c6d 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -64,11 +64,37 @@ static void qlit_equal_qobject_test(void)
qobject_decref(qobj);
}
+static void qobject_from_qlit_test(void)
+{
+ QObject *obj, *qobj = qobject_from_qlit(&qlit);
+ QDict *qdict;
+ QList *bee;
+
+ qdict = qobject_to_qdict(qobj);
+ g_assert_cmpint(qdict_get_int(qdict, "foo"), ==, 42);
+ g_assert_cmpstr(qdict_get_str(qdict, "bar"), ==, "hello world");
+ g_assert(qobject_type(qdict_get(qdict, "baz")) == QTYPE_QNULL);
+
+ bee = qdict_get_qlist(qdict, "bee");
+ obj = qlist_pop(bee);
+ g_assert_cmpint(qnum_get_int(qobject_to_qnum(obj)), ==, 43);
+ qobject_decref(obj);
+ obj = qlist_pop(bee);
+ g_assert_cmpint(qnum_get_int(qobject_to_qnum(obj)), ==, 44);
+ qobject_decref(obj);
+ obj = qlist_pop(bee);
+ g_assert(qbool_get_bool(qobject_to_qbool(obj)));
+ qobject_decref(obj);
+
+ qobject_decref(qobj);
+}
+
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/qlit/equal_qobject", qlit_equal_qobject_test);
+ g_test_add_func("/qlit/qobject_from_qlit", qobject_from_qlit_test);
return g_test_run();
}
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 14/14] qapi: generate a literal qobject for introspection
2017-08-24 10:33 [Qemu-devel] [PATCH 00/14] Generate a literal qobject for introspection Marc-André Lureau
` (12 preceding siblings ...)
2017-08-24 10:33 ` [Qemu-devel] [PATCH 13/14] qlit: add qobject_form_qlit() Marc-André Lureau
@ 2017-08-24 10:33 ` Marc-André Lureau
13 siblings, 0 replies; 32+ messages in thread
From: Marc-André Lureau @ 2017-08-24 10:33 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Dr. David Alan Gilbert,
Michael Roth
Replace the generated json string with a literal qobject. The later is
easier to deal with, at run time as well as compile time: adding #if
conditionals will be easier than in a json string.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
scripts/qapi-introspect.py | 87 ++++++++++++++++++++++----------------
monitor.c | 2 +-
tests/test-qobject-input-visitor.c | 11 +++--
docs/devel/qapi-code-gen.txt | 29 ++++++++-----
4 files changed, 78 insertions(+), 51 deletions(-)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 032bcea491..a157a5f91c 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -12,31 +12,41 @@
from qapi import *
-# Caveman's json.dumps() replacement (we're stuck at Python 2.4)
-# TODO try to use json.dumps() once we get unstuck
-def to_json(obj, level=0):
+def to_qlit(obj, level=0, suppress_first_indent=False):
+
+ def indent(level):
+ return level * 4 * ' '
+
+ ret = ''
+ if not suppress_first_indent:
+ ret += indent(level)
if obj is None:
- ret = 'null'
+ ret += 'QLIT_QNULL'
elif isinstance(obj, str):
- ret = '"' + obj.replace('"', r'\"') + '"'
+ ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
elif isinstance(obj, list):
- elts = [to_json(elt, level + 1)
+ elts = [to_qlit(elt, level + 1)
for elt in obj]
- ret = '[' + ', '.join(elts) + ']'
+ elts.append(indent(level + 1) + "{}")
+ ret += 'QLIT_QLIST(((QLitObject[]) {\n'
+ ret += ',\n'.join(elts) + '\n'
+ ret += indent(level) + '}))'
elif isinstance(obj, dict):
- elts = ['"%s": %s' % (key.replace('"', r'\"'),
- to_json(obj[key], level + 1))
- for key in sorted(obj.keys())]
- ret = '{' + ', '.join(elts) + '}'
+ elts = []
+ for key, value in sorted(obj.iteritems()):
+ elts.append(indent(level + 1) + '{ %s, %s }' %
+ (to_c_string(key), to_qlit(value, level + 1, False)))
+ elts.append(indent(level + 1) + '{}')
+ ret += 'QLIT_QDICT(((QLitDictEntry[]) {\n'
+ ret += ',\n'.join(elts) + '\n'
+ ret += indent(level) + '}))'
else:
assert False # not implemented
- if level == 1:
- ret = '\n' + ret
return ret
-def to_c_string(string):
- return '"' + string.replace('\\', r'\\').replace('"', r'\"') + '"'
+def to_c_string(s):
+ return '"' + s.replace('\\', r'\\').replace('"', r'\"') + '"'
class QAPISchemaGenIntrospectVisitor(QAPISchemaVisitor):
@@ -45,39 +55,37 @@ class QAPISchemaGenIntrospectVisitor(QAPISchemaVisitor):
self.defn = None
self.decl = None
self._schema = None
- self._jsons = None
+ self._qlits = None
self._used_types = None
self._name_map = None
def visit_begin(self, schema):
self._schema = schema
- self._jsons = []
+ self._qlits = []
self._used_types = []
self._name_map = {}
def visit_end(self):
# visit the types that are actually used
- jsons = self._jsons
- self._jsons = []
+ qlits = self._qlits
+ self._qlits = []
for typ in self._used_types:
typ.visit(self)
# generate C
# TODO can generate awfully long lines
- jsons.extend(self._jsons)
- name = c_name(prefix, protect=False) + 'qmp_schema_json'
+ qlits.extend(self._qlits)
+ name = c_name(prefix, protect=False) + 'qmp_schema_qlit'
self.decl = mcgen('''
-extern const char %(c_name)s[];
+extern const QLitObject %(c_name)s;
''',
c_name=c_name(name))
- lines = to_json(jsons).split('\n')
- c_string = '\n '.join([to_c_string(line) for line in lines])
self.defn = mcgen('''
-const char %(c_name)s[] = %(c_string)s;
+const QLitObject %(c_name)s = %(c_string)s;
''',
c_name=c_name(name),
- c_string=c_string)
+ c_string=to_qlit(qlits))
self._schema = None
- self._jsons = None
+ self._qlits = None
self._used_types = None
self._name_map = None
@@ -111,12 +119,12 @@ const char %(c_name)s[] = %(c_string)s;
return '[' + self._use_type(typ.element_type) + ']'
return self._name(typ.name)
- def _gen_json(self, name, mtype, obj):
+ def _gen_qlit(self, name, mtype, obj):
if mtype not in ('command', 'event', 'builtin', 'array'):
name = self._name(name)
obj['name'] = name
obj['meta-type'] = mtype
- self._jsons.append(obj)
+ self._qlits.append(obj)
def _gen_member(self, member):
ret = {'name': member.name, 'type': self._use_type(member.type)}
@@ -132,24 +140,24 @@ const char %(c_name)s[] = %(c_string)s;
return {'case': variant.name, 'type': self._use_type(variant.type)}
def visit_builtin_type(self, name, info, json_type):
- self._gen_json(name, 'builtin', {'json-type': json_type})
+ self._gen_qlit(name, 'builtin', {'json-type': json_type})
def visit_enum_type(self, name, info, values, prefix):
- self._gen_json(name, 'enum', {'values': values})
+ self._gen_qlit(name, 'enum', {'values': values})
def visit_array_type(self, name, info, element_type):
element = self._use_type(element_type)
- self._gen_json('[' + element + ']', 'array', {'element-type': element})
+ self._gen_qlit('[' + element + ']', 'array', {'element-type': element})
def visit_object_type_flat(self, name, info, members, variants):
obj = {'members': [self._gen_member(m) for m in members]}
if variants:
obj.update(self._gen_variants(variants.tag_member.name,
variants.variants))
- self._gen_json(name, 'object', obj)
+ self._gen_qlit(name, 'object', obj)
def visit_alternate_type(self, name, info, variants):
- self._gen_json(name, 'alternate',
+ self._gen_qlit(name, 'alternate',
{'members': [{'type': self._use_type(m.type)}
for m in variants.variants]})
@@ -157,13 +165,13 @@ const char %(c_name)s[] = %(c_string)s;
gen, success_response, boxed):
arg_type = arg_type or self._schema.the_empty_object_type
ret_type = ret_type or self._schema.the_empty_object_type
- self._gen_json(name, 'command',
+ self._gen_qlit(name, 'command',
{'arg-type': self._use_type(arg_type),
'ret-type': self._use_type(ret_type)})
def visit_event(self, name, info, arg_type, boxed):
arg_type = arg_type or self._schema.the_empty_object_type
- self._gen_json(name, 'event', {'arg-type': self._use_type(arg_type)})
+ self._gen_qlit(name, 'event', {'arg-type': self._use_type(arg_type)})
# Debugging aid: unmask QAPI schema's type names
# We normally mask them, because they're not QMP wire ABI
@@ -205,11 +213,18 @@ h_comment = '''
fdef.write(mcgen('''
#include "qemu/osdep.h"
+#include "qapi/qmp/qlit.h"
#include "%(prefix)sqmp-introspect.h"
''',
prefix=prefix))
+fdecl.write(mcgen('''
+#include "qemu/osdep.h"
+#include "qapi/qmp/qlit.h"
+
+'''))
+
schema = QAPISchema(input_file)
gen = QAPISchemaGenIntrospectVisitor(opt_unmask)
schema.visit(gen)
diff --git a/monitor.c b/monitor.c
index e0f880107f..14c27d4b6f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -953,7 +953,7 @@ EventInfoList *qmp_query_events(Error **errp)
static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
Error **errp)
{
- *ret_data = qobject_from_json(qmp_schema_json, &error_abort);
+ *ret_data = qobject_from_qlit(&qmp_schema_qlit);
}
/*
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index bcf02617dc..bdd00f6bd8 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -1247,24 +1247,27 @@ static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
}
static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
- const char *schema_json)
+ const QLitObject *qlit)
{
SchemaInfoList *schema = NULL;
+ QObject *obj = qobject_from_qlit(qlit);
Visitor *v;
- v = visitor_input_test_init_raw(data, schema_json);
+ v = qobject_input_visitor_new(obj);
visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
g_assert(schema);
qapi_free_SchemaInfoList(schema);
+ qobject_decref(obj);
+ visit_free(v);
}
static void test_visitor_in_qmp_introspect(TestInputVisitorData *data,
const void *unused)
{
- do_test_visitor_in_qmp_introspect(data, test_qmp_schema_json);
- do_test_visitor_in_qmp_introspect(data, qmp_schema_json);
+ do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit);
+ do_test_visitor_in_qmp_introspect(data, &qmp_schema_qlit);
}
int main(int argc, char **argv)
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 9903ac4c19..b653e86bff 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -1295,18 +1295,27 @@ Example:
#ifndef EXAMPLE_QMP_INTROSPECT_H
#define EXAMPLE_QMP_INTROSPECT_H
- extern const char example_qmp_schema_json[];
+ extern const QLitObject qmp_schema_qlit;
#endif
$ cat qapi-generated/example-qmp-introspect.c
[Uninteresting stuff omitted...]
- const char example_qmp_schema_json[] = "["
- "{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\": \"MY_EVENT\"}, "
- "{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\": \"my-command\", \"ret-type\": \"2\"}, "
- "{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, "
- "{\"members\": [{\"name\": \"arg1\", \"type\": \"[2]\"}], \"meta-type\": \"object\", \"name\": \"1\"}, "
- "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"default\": null, \"name\": \"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"2\"}, "
- "{\"element-type\": \"2\", \"meta-type\": \"array\", \"name\": \"[2]\"}, "
- "{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\": \"int\"}, "
- "{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": \"str\"}]";
+ const QLitObject example_qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
+ QLIT_QDICT(((QLitDictEntry[]) {
+ { "arg-type", QLIT_QSTR("0") },
+ { "meta-type", QLIT_QSTR("event") },
+ { "name", QLIT_QSTR("Event") },
+ { }
+ })),
+ QLIT_QDICT(((QLitDictEntry[]) {
+ { "members", QLIT_QLIST(((QLitObject[]) {
+ { }
+ })) },
+ { "meta-type", QLIT_QSTR("object") },
+ { "name", QLIT_QSTR("0") },
+ { }
+ })),
+ ...
+ { }
+ }));
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 32+ messages in thread